JSON类库Jackson、JSON-lib、gson性能对比

 json  JSON类库Jackson、JSON-lib、gson性能对比已关闭评论
11月 032016
 

以下数据来自:http://wangym.iteye.com/blog/738933

Jackson:http://jackson.codehaus.org/

JSON-lib:http://json-lib.sourceforge.net/

Gson:http://code.google.com/p/google-gson/

 

测试环境:

 

1、工作电脑:Intel双核E8400 共6GHz,内存4GB,WinXP

2、JSON-lib用最新的JDK15,GSON版本是最新的v1.4,Jackson也是最新的v1.5.5,JDK-v1.6.0_20,JMeter-v2.4

3、测试时不开启任何无关进程,每完成一项测试后关闭JMeter整理内存后,再进行下一项测试,每项测试运行3次,取平均值

4、JSON转Java Bean意为将JSON格式转换成Java类,这个类内包括Map、List、Date、Integer/Long/Double、String等类型的属性,Java Bean转Json则同理。另外,两者互转,每次转换的数据都是随机生成

 

测试结果:

 

* 吞吐量的值越大越好,总耗时的值越小越好

 

JSON转Bean,5个线程并发,约200字节对象,1千万次转换:

 

Jackson JSON-lib Gson
TPS 64113.7 8067.4 13952.8
总耗时(秒) 155 1238 700

 

Bean转JSON,5个线程并发,约200字节对象,1千万次转换:

 

Jackson JSON-lib Gson
TPS 54802 15093.2 17308.2
总耗时(秒) 181 661 560

 

JSON转Bean,5个线程并发,约2K对象,1千万次转换:

 

Jackson JSON-lib Gson
TPS 37314 2406.9 3657.50
总耗时(秒) 267 4120 2720

 

Bean转JSON,5个线程并发,约2K对象,1千万次转换:

 

Jackson JSON-lib Gson
TPS 30922.2 4274.8 4977.00
总耗时(秒) 322 2320 2000

 

测试总结:

 

1、显而易见,无论是哪种形式的转换,Jackson > Gson > Json-lib。

     Jackson的处理能力甚至高出Json-lib有10倍左右

2、JSON-lib似乎已经停止更新,最新的版本也是基于JDK15,而Jackson的社区则较为活跃;

3、在测试性能的同时,又以人肉方式对这三个类库转换的正确性 进行了检查 ,三者均达100%正确 

4、JSON-lib在转换诸如Date类型时较为累赘,如以下是两者的转换结果:

JSON-lib:

{“brithday”:{“date”:17,”day”:2,”hours”:9,”minutes”:24,”month”:7,”seconds”:26,”time”:1282008266398,”timezoneOffset”:-480,”year”:110}}

Jackson:

{“brithday”:1282008123101}

5、JSON-lib依赖commons系列的包及 ezmorph包共 5个,而Jackson除自身的以外只依赖于commons-logging 
6、Jackson提供完整基于节点的Tree Model,以及完整的OJM数据绑定功能。

 

Jackson使用示例:

 

JacksonMapper:

创建为饿汉式单例模式 ,Jackson用于转换的核心类ObjectMapper无需每次都new一个object,官网上的一句话:can reuse, share globally

 

Java代码  收藏代码

  1. /** 
  2.  * @author xuanyin 
  3.  *  
  4.  */  
  5. public class JacksonMapper {  
  6.   
  7.     /** 
  8.      *  
  9.      */  
  10.     private static final ObjectMapper mapper = new ObjectMapper();  
  11.   
  12.     /** 
  13.      *  
  14.      */  
  15.     private JacksonMapper() {  
  16.   
  17.     }  
  18.   
  19.     /** 
  20.      *  
  21.      * @return 
  22.      */  
  23.     public static ObjectMapper getInstance() {  
  24.   
  25.         return mapper;  
  26.     }  
  27.   
  28. }  

 

JSON转Bean:

 

Java代码  收藏代码

  1. ……  
  2. String json = “…”;  
  3. ObjectMapper mapper = JacksonMapper.getInstance();  
  4. YourBean bean = mapper.readValue(json, new YourBean().getClass());  
  5. ……  

 

Bean转JSON:

 

Java代码  收藏代码

  1. ……  
  2. YourBean bean = new YourBean();  
  3. ……  
  4. ObjectMapper mapper = JacksonMapper.getInstance();  
  5. StringWriter sw = new StringWriter();  
  6. JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);  
  7. mapper.writeValue(gen, bean);  
  8. gen.close();  
  9. String json = sw.toString();  
  10. ……  

 

* 上面两段代码中的YourBean当然也可以是Java的基本类型

***************************************************************************************************************

附jackon具体使用:

一、入门
Jackson中有个ObjectMapper类很是实用,用于Java对象与JSON的互换。
1.JAVA对象转JSON[JSON序列化]

import java.io.IOException; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
  
import com.fasterxml.jackson.databind.ObjectMapper; 
  
public class JacksonDemo { 
  public static void main(String[] args) throws ParseException, IOException { 
    User user = new User(); 
    user.setName(“小民”);  
    user.setEmail(“xiaomin@sina.com”); 
    user.setAge(20); 
      
    SimpleDateFormat dateformat = new SimpleDateFormat(“yyyy-MM-dd”); 
    user.setBirthday(dateformat.parse(“1996-10-01”));     
      
    /** 
     * ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。 
     * ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。 
     * writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。 
     * writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。 
     * writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。 
     * writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。 
     */
    ObjectMapper mapper = new ObjectMapper(); 
      
    //User类转JSON 
    //输出结果:{“name”:”小民”,”age”:20,”birthday”:844099200000,”email”:”xiaomin@sina.com”} 
    String json = mapper.writeValueAsString(user); 
    System.out.println(json); 
      
    //Java集合转JSON 
    //输出结果:[{“name”:”小民”,”age”:20,”birthday”:844099200000,”email”:”xiaomin@sina.com”}] 
    List<User> users = new ArrayList<User>(); 
    users.add(user); 
    String jsonlist = mapper.writeValueAsString(users); 
    System.out.println(jsonlist); 
  } 

2.JSON转Java类[JSON反序列化]

import java.io.IOException; 
import java.text.ParseException; 
import com.fasterxml.jackson.databind.ObjectMapper; 
  
public class JacksonDemo { 
  public static void main(String[] args) throws ParseException, IOException { 
    String json = “{\”name\”:\”小民\”,\”age\”:20,\”birthday\”:844099200000,\”email\”:\”xiaomin@sina.com\”}”; 
      
    /** 
     * ObjectMapper支持从byte[]、File、InputStream、字符串等数据的JSON反序列化。 
     */
    ObjectMapper mapper = new ObjectMapper(); 
    User user = mapper.readValue(json, User.class); 
    System.out.println(user); 
  } 

 
二、Jackson支持3种使用方式:
1、Data Binding:最方便使用.
(1)Full Data Binding:

private static final String MODEL_BINDING = “{\”name\”:\”name1\”,\”type\”:1}”; 
  public void fullDataBinding() throws Exception{ 
    ObjectMapper mapper = new ObjectMapper(); 
    Model user = mapper.readValue(MODEL_BINDING, Model.class);//readValue到一个实体类中. 
    System.out.println(user.getName()); 
    System.out.println(user.getType()); 
  } 
Model类:

private static class Model{ 
    private String name; 
    private int type; 
      
    public String getName() { 
      return name; 
    } 
    public void setName(String name) { 
      this.name = name; 
    } 
    public int getType() { 
      return type; 
    } 
    public void setType(int type) { 
      this.type = type; 
    } 
  } 
(2)Raw Data Binding:

/** 
  Concrete Java types that Jackson will use for simple data binding are: 
  JSON Type    Java Type 
  object     LinkedHashMap<String,Object> 
  array      ArrayList<Object> 
  string     String 
  number(no fraction) Integer, Long or BigInteger (smallest applicable) 
  number(fraction)  Double(configurable to use BigDecimal) 
  true|false   Boolean 
  null      null 
  */
  public void rawDataBinding() throws Exception{ 
    ObjectMapper mapper = new ObjectMapper(); 
    HashMap map = mapper.readValue(MODEL_BINDING,HashMap.class);//readValue到一个原始数据类型. 
    System.out.println(map.get(“name”)); 
    System.out.println(map.get(“type”)); 
  } 
 (3)generic Data Binding:

private static final String GENERIC_BINDING = “{\”key1\”:{\”name\”:\”name2\”,\”type\”:2},\”key2\”:{\”name\”:\”name3\”,\”type\”:3}}”; 
  public void genericDataBinding() throws Exception{ 
    ObjectMapper mapper = new ObjectMapper(); 
    HashMap<String,Model> modelMap = mapper.readValue(GENERIC_BINDING,new TypeReference<HashMap<String,Model>>(){});//readValue到一个范型数据中. 
    Model model = modelMap.get(“key2”); 
    System.out.println(model.getName()); 
    System.out.println(model.getType()); 
  } 
2、Tree Model:最灵活。

private static final String TREE_MODEL_BINDING = “{\”treekey1\”:\”treevalue1\”,\”treekey2\”:\”treevalue2\”,\”children\”:[{\”childkey1\”:\”childkey1\”}]}”; 
  public void treeModelBinding() throws Exception{ 
    ObjectMapper mapper = new ObjectMapper(); 
    JsonNode rootNode = mapper.readTree(TREE_MODEL_BINDING); 
    //path与get作用相同,但是当找不到该节点的时候,返回missing node而不是Null. 
    String treekey2value = rootNode.path(“treekey2”).getTextValue();// 
    System.out.println(“treekey2value:” + treekey2value); 
    JsonNode childrenNode = rootNode.path(“children”); 
    String childkey1Value = childrenNode.get(0).path(“childkey1”).getTextValue(); 
    System.out.println(“childkey1Value:”+childkey1Value); 
      
    //创建根节点 
    ObjectNode root = mapper.createObjectNode(); 
    //创建子节点1 
    ObjectNode node1 = mapper.createObjectNode(); 
    node1.put(“nodekey1”,1); 
    node1.put(“nodekey2”,2); 
    //绑定子节点1 
    root.put(“child”,node1); 
    //数组节点 
    ArrayNode arrayNode = mapper.createArrayNode(); 
    arrayNode.add(node1); 
    arrayNode.add(1); 
    //绑定数组节点 
    root.put(“arraynode”, arrayNode); 
    //JSON读到树节点 
    JsonNode valueToTreeNode = mapper.valueToTree(TREE_MODEL_BINDING); 
    //绑定JSON节点 
    root.put(“valuetotreenode”,valueToTreeNode); 
    //JSON绑定到JSON节点对象 
    JsonNode bindJsonNode = mapper.readValue(GENERIC_BINDING, JsonNode.class);//绑定JSON到JSON节点对象. 
    //绑定JSON节点 
    root.put(“bindJsonNode”,bindJsonNode); 
    System.out.println(mapper.writeValueAsString(root)); 
  } 
3、Streaming API:最佳性能。
 
对于性能要求高的程序,推荐使用流API,否则使用其他方法
不管是创建JsonGenerator还是JsonParser,都是使用JsonFactory。

packagecom.jingshou.jackson;
  
importjava.io.File;
importjava.io.IOException;
  
importcom.fasterxml.jackson.core.JsonEncoding;
importcom.fasterxml.jackson.core.JsonFactory;
importcom.fasterxml.jackson.core.JsonGenerator;
importcom.fasterxml.jackson.core.JsonParser;
importcom.fasterxml.jackson.core.JsonToken;
  
publicclassJacksonTest6 {
  
  publicstaticvoidmain(String[] args)throwsIOException {
    JsonFactory jfactory =newJsonFactory();
       
    /*** write to file ***/
    JsonGenerator jGenerator = jfactory.createGenerator(newFile(
        “c:\\user.json”), JsonEncoding.UTF8);
    jGenerator.writeStartObject();// {
     
    jGenerator.writeStringField(“name”,”mkyong”);// “name” : “mkyong”
    jGenerator.writeNumberField(“age”,29);// “age” : 29
     
    jGenerator.writeFieldName(“messages”);// “messages” :
    jGenerator.writeStartArray();// [
     
    jGenerator.writeString(“msg 1”);// “msg 1”
    jGenerator.writeString(“msg 2”);// “msg 2”
    jGenerator.writeString(“msg 3”);// “msg 3”
     
    jGenerator.writeEndArray();// ]
     
    jGenerator.writeEndObject();// }
    jGenerator.close();
      
    /*** read from file ***/
    JsonParser jParser = jfactory.createParser(newFile(“c:\\user.json”));
    // loop until token equal to “}”
    while(jParser.nextToken() != JsonToken.END_OBJECT) {
     
      String fieldname = jParser.getCurrentName();
      if(“name”.equals(fieldname)) {
     
       // current token is “name”,
       // move to next, which is “name”‘s value
       jParser.nextToken();
       System.out.println(jParser.getText());// display mkyong
     
      }
     
      if(“age”.equals(fieldname)) {
     
       // current token is “age”, 
       // move to next, which is “name”‘s value
       jParser.nextToken();
       System.out.println(jParser.getIntValue());// display 29
     
      }
     
      if(“messages”.equals(fieldname)) {
     
       jParser.nextToken();// current token is “[“, move next
     
       // messages is array, loop until token equal to “]”
       while(jParser.nextToken() != JsonToken.END_ARRAY) {
     
             // display msg1, msg2, msg3
         System.out.println(jParser.getText()); 
     
       }
     
      }
     
     }
     jParser.close();
  
  }
  
}

5月 072015
 

作者有是两篇文章,我合二为一了,写的挺好,分享下:

XML和Json作为最常用的两种网络传输格式而被广泛使用,XML在早期数据传输中作为首选,但是近年来Json以其轻量级和更容易编写和解析而越来越流行,Gson作为google的一个开源Json解析框架提供了稳定和快速解析的功能,可以读读它的源代码了解一番。

说到Gson,其实它无非就是做两个工作,序列化(Object—>JsonString)和反序列化(JsonString—>Object),后文所说的两个方向从Object到String和String到Object的两个方向。可想而知,对于序列化来说,是较为容易的工作,而对于反序列化即Json解析才是Gson的重头戏。既然是对Json字符串的解析,那么少不了对Json字符串中的结构进行抽象。

Json抽象类

JsonElement

这是Json中元素的基类,它只提供了若干个类型判断的接口,简单判断这个Json元素的类型。以下几个类型都是它的子类。

1、JsonObject

包含多个JsonElement的集合,它在Json中对应这种类型的数据:

{
    "count":100,
    "users":[],
    "paging":{
        "offset":0,
        "limit":10,
        "hasMore":true
    }
}

这个data是一个典型的JsonObject,它以{开头,其中包含了一些类似数值,数组,对象等其他JsonElement的内容。其实每一个Json字符串的根节点都是一个JsonObject或者JsonArray。

JsonObject提供了比较多的方法来得到Json中的信息,addProperty()函数可以在当前Json节点下新建子结点。

2、JsonArray

JsonArray也表示JsonElement的集合,注意:Json中的数组并不要求所有的数据类型都一样

[true,"hello"] //JsonArray,包括一个boolean和一个hello类型。

需要讨论的是JsonArray和JsonObject的区别是什么?从集合的角度来说,JsonObject中的JsonElement是无序的,而JsonArray中的集合元素是有序的,从直观感受来说,你可以通过下标来引用JsonArray中的元素,而JsonObject是通过键值对的方式来访问的,get(“name”)—>value。

3、JsonPrimitive

对应Json中的基本类型,比如boolean,int,当然提供了基本类型和包装类的自动替换。

"count":100

4、JsonNull

空,对应null

"person":null

以上就是Gson对应Json结构的封装。

注解-Annotations

Expose

在对象进行序列化和反序列化的过程中,我们可以通过注解来屏蔽某一些字段。这个注解默认有两个参数,serialize和deserialize都是默认true。如果设置为false,表示这个序列化(反)的过程中,这一个属性不需要进行处理。

通过Expose标注的属性在直接new Gson()的情况下不能生效,我们必须通过Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()来创建一个可以识别Expose注解的Gson。

小小的吐槽一把,这个地方的使用确实不太方便,举个栗子,一般来说,我们进行序列化的时候都是希望某一个属性不会序列化到Json字符里面(反之亦然),所以这里的一般思维是我要去处理这些特殊的属性。而如果你想通过Expose来去掉10个属性中的某一个,对不起,10个属性你都需要加上@Expose,然后对你想要处理的那个属性的Expose注解增加false参数,简直就是坑爹。。。。

//我想让Person类在序列化时,不去序列化password,是不是很坑爹?
class Person {
    @Expose
    private String userName;
    @Expose (serialize = false)
    private String passWord;
}

此外,和java本身的序列化一样,如果一个属性设置为transient或者static,那么两个序列化的两个方向上都会屏蔽掉这个属性,虽然比Expose简单,但是不够灵活。

SerializedName

这个注解使用较多,它会改变两个方向上这个属性的名称,在序列化是,JsonElement的键值会被替换成这个名字;解析时,Json中键值为这个名字的JsonElement会赋值给被注解的属性。

class Person {

@SerializedName(value = "A")
private int a = 1;
private int b = 2;
}

//{"A":1,"b":2}  这个Json字符串和前面的Person等价

它使用场景最多的地方就是比如后端返回的json中的名称和我们定义的model类名称不一样时使用。

Since 和 Until

我们可以对我们的Model类进行序列化(两个方向)的版本控制,Since和Until刚好是两个相反的意义。

例子:

class Person {
    @Since(value = 1.0)     //GsonBuilder指定版本要从1.0开始的Gson才能解析
    private int a = 1;

    @Until(value = 1.5)   //GsonBuilder指定版本到1.5的Gson都可以解析,超过了不能解析
    private int b = 2;
}

和Expose一样,要想Gson识别这两个注解,同样需要通过GsonBuilder.setVersion(double).create()来实现。

前文介绍了Gson对于Json规范中的类型进行了抽象定义,本文将来介绍stream包中的源码,这一块是Gson的核心代码之一。Gson中的JsonReader和JsonWriter抄自android.util包中的两个类,只是把其中的上下文栈由ArrayList换成了数组,提高了效率。这两个类为Json序列化和反序列化提供了基本接口。

反序列化—JsonReader

StringPool–(Flyweight Pattern)

在Stream包中提供了一种针对String的优化处理,可以减少内存中String对象的个数,途径就是通过StringPool来对字符串进行复用。需要注意的是,在Java中字符串对象是不能被修改的,这也是这个Pool能正常工作的重要原因。StringPool原理和HashMap一模一样,通过一个2的n次方(512)作为数组的长度,字符串的hascode计算方式和String中的一致。为了使得hashcode分布分散一点,同样使用hashmap的补偿hash函数对hashcode进行处理,这一块的具体优化处理可以关注以后的HashMap源码分析。

深度优先的解析策略

Gson解析Json字符采用的是深度优先策略,下面是一个简单解析的栗子:

[
<!--数组中每一个对象为一个message对象-->
{
  "id": 912345678901,
  "text": "How do I read a JSON stream in Java?",
  <!--geo是一个double类型的数组-->
  "geo": null,
  <!--user对象-->
  "user": {
    "name": "json_newb",
    "followers_count": 41
   }
},
{
  "id": 912345678902,
  "text": "@json_newb just use JsonReader!",
  "geo": [50.454722, -104.606667],
  "user": {
    "name": "jesse",
    "followers_count": 2
  }
}
]

深度解析的逻辑如下,先找到这个json字符串的开始位置,本例中是[,此时我们知道这个json字符串是一个数组,下一步从第一个元素开始解析(一层循环)。读取下一个字符,{,可以知道第一个元素为对象。对于{开始的JsonObject,我们知道它其中的内容肯定是键值对的样式,那我可以读取下一个字符,而且它必须为”(属性名),然后去读取属性值。ok,我们可以看到这是一种非常正常的解析逻辑,其实Gson的解析就是这么做的。

数据抽象

为了进行上面的解析过程,Gson中定义了两种数据类型:

JsonToken(解析类型)

由于Json定义规范的原因,我们在解析过程中只要解析到一个结构的第一个元素再联系上下文就可以推断这个结构的类型。JsonToken用来描述Json中的'{‘,’}’,'[‘,’]’,'”‘,NULL,number,boolean,属性名和属性字符串值,其实JsonToken的基本上等于每一个结构的开头,其中”既可以表示一个属性名也可以表示一个属性就是一个String,这需要按照上下文来确定。 在JsonReader定义了一个属性token,用来存储Json串解析位置的下一个JsonToken。

JsonScope(解析上下文)

用来描述当前正在解析的位置所处的一个状态,为解析提供一个上下文做推断。比如,目前我们解析到了一个{字符,那么下一个字符串必须是空或者’“‘,如此我们可以推断这个”肯定是一个JsonToken.Name(属性名)。此外,JsonScope还可以描述一个JsonArray或者JsonObject目前解析到的位置是否是第一个元素。JsonScope被存放在一个栈中,而且是成对出现。

private JsonScope[] stack = new JsonScope[32];
 {
   push(JsonScope.EMPTY_DOCUMENT);  //静态初始化时push空Json文件到栈顶
 }
 需要注意的是,这里这个栈之只实现了一个push操作,并提供了动态增长,出栈操作只需要简单的简单的stacksize--

JsonReader工作流

JsonReader的构造函数接受一个Reader的参数,它是一个Json串的InputStream包装出来的Reader。

对于这个上文Json文档的解析,JsonReader的理逻辑如下:

List<Message> result = new ArrayList<Message>();
jsonReader.beginArray();   //找到数组
while(jsonReader.hasnext) {
    Message message = new Message();
    jsonReader.beginObject();   //开始数组中的对象
    while(jsonReader.hasnext) {
        String name = jsonReader.nextName();
        if(name.equals("id")) {
            message.setId(jsonReader.nextString());
        }else if(name.equals("text")) {
            message.setText(jsonReader.nextString());
        }else if(name.equals("geo")&&jsonReader.peek()!=NULL) {
             List<Double> list = new ArrayList<Double>();
             jsonReader.beginArray();
             while(jsonReader.hasnext()) {
                list.add(jsonReader.nextDouble());
             }
             JsonReader.endArray();
        }
        jsonReader.beginObject();
       .....开始解析User对象......
    }
    result.add(message);
}

一些函数的解释

begin和 end系列函数

其实这两个函数只是从业务的角度出发,封装了一下,实际两个函数都是调用except(JsonToken),作用是寻找json字符串中的下一个JsonToken。以beginObject()函数来说,它直接调用except(JsonToken.BEGIN_OBJECT)。

private void expect(JsonToken expected) throws IOException {
peek();         //找到下一个JsonToken,赋值给JsonReader的token属性
if (token != expected) {  //判断下一个Token是否等于指定的Token类型
  throw new IllegalStateException("Expected " + expected + " but was " +        peek() + " at line " + getLineNumber() + " column " +       getColumnNumber());
}
advance();  //下一步操作
}

peek函数

peek函数是JsonReader中最重要的函数,它的主要作用是进行上下文的判断,判断下一个JsonToken的读取方法。

下面看一下peek()函数的实现:

public JsonToken peek() throws IOException {
//之前解析出来的token还没有被消费,直接取回
if (token != null) {
  return token;
}
//查看栈顶的JsonScope,这里可以看到JsonScope就是一个上下文的角色
switch (stack[stackSize - 1]) {
case EMPTY_DOCUMENT:    //json文档的开始
  if (lenient) {    //json防止攻击引入的前导,防止跨域攻击
    consumeNonExecutePrefix();
  }
  stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT;   //注意这里不是push而是直接替换栈顶元素
  JsonToken firstToken = nextValue();   //返回流中的下一个开始JsonToken,在上个例子中就是'[',也就是这里返回的是一个JsonToken.BEGIN_ARRAY,这个值还会被保存在token属性中
  if (!lenient && token != JsonToken.BEGIN_ARRAY && token != JsonToken.BEGIN_OBJECT) {   //一个json文档开始无非就是一个对象或者数组
    throw new IOException("Expected JSON document to start with '[' or '{' but was " + token
        + " at line " + getLineNumber() + " column " + getColumnNumber());
  }
  return firstToken;
case EMPTY_ARRAY:
    //目前处于一个数组中,但是还没有开始读取任何数据
  return nextInArray(true);
case NONEMPTY_ARRAY:
  return nextInArray(false);
case EMPTY_OBJECT: //目前处于一个JsonObject中但是还没有读取任何数据
  return nextInObject(true);
case DANGLING_NAME: //目前处于一个属性名的位置
  return objectValue();
case NONEMPTY_OBJECT:
  return nextInObject(false);
case NONEMPTY_DOCUMENT:
    //当前处于一个文档的解析上下文中,可以理解为根元素下一级的环境
  int c = nextNonWhitespace(false);
  if (c == -1) {
    return JsonToken.END_DOCUMENT;
  }
  pos--;
  if (!lenient) {
    throw syntaxError("Expected EOF");
  }
  //找下一个JsonToken
  return nextValue();
case CLOSED:
  throw new IllegalStateException("JsonReader is closed");
default:
  throw new AssertionError();
}
}

nextIn**()

提供了数组、JsonObject的解析方法。

nextValue()

找下一个JsonToken

private JsonToken nextValue() throws IOException {
int c = nextNonWhitespace(true);    //找到当前解析位置之后的第一个非空白字符
switch (c) {
case '{':
  push(JsonScope.EMPTY_OBJECT);   //进入一个JsonObject
  return token = JsonToken.BEGIN_OBJECT;

case '[':
  push(JsonScope.EMPTY_ARRAY);   //进入一个数组
  return token = JsonToken.BEGIN_ARRAY;
  //以上两种情况说明是一个新的结构的开始,所以需要pushJsonScope到栈中
case ''':
  checkLenient(); // fall-through
case '"':
  //代表一个Json字符串值
  value = nextString((char) c);  //找到两个引号之间的String值
  return token = JsonToken.STRING;

default:
  pos--;
  return readLiteral();
}
}

JsonReader总结

JsonReader可以看作一个最基本的Json解析的接口,JsonReader中通过一个上下文来保存当前解析的环境,通过next**系列函数来获取下一个JsonToken。

序列化–JsonWriter

理解了JsonReader的源码之后,再来看Writer就相对来说简单多了。现在我们有一个数组,List,它的值就如上面的例子,那如何序列化呢?

public void writeJsonStream(OutputStream out, List<Message> messages) throws IOException {
      JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
      writer.setIndent("t");           //设置每一行的缩进
      writeMessagesArray(writer, messages);
      writer.close();
    }

    public void writeMessagesArray(JsonWriter writer, List<Message> messages) throws IOException {
      writer.beginArray();   //[
      for (Message message : messages) {
        writeMessage(writer, message);
      }
      writer.endArray();
    }

    public void writeMessage(JsonWriter writer, Message message) throws IOException {
      writer.beginObject(); //{
      writer.name("id").value(message.getId()); // "id":23435356
      writer.name("text").value(message.getText()); //"text":"dflsfldsfljd"
      if (message.getGeo() != null) {
        writer.name("geo");
        writeDoublesArray(writer, message.getGeo());
      } else {
        writer.name("geo").nullValue();
      }
      writer.name("user");
      writeUser(writer, message.getUser());
      writer.endObject();
    }

    public void writeUser(JsonWriter writer, User user) throws IOException {
      writer.beginObject();
      writer.name("name").value(user.getName());
      writer.name("followers_count").value(user.getFollowersCount());
      writer.endObject();
    }

    public void writeDoublesArray(JsonWriter writer, List<Double> doubles) throws IOException {
      writer.beginArray();
      for (Double value : doubles) {
        writer.value(value);
      }
      writer.endArray();
    }

JsonWriter中的函数

事实上,可以看到JsonWriter的工作和JsonReader刚好相反,两个类的对json字符串的处理方式也基本相同。下面说一些业务流程中较为重要的方法。

beginArray and beginObject

开始向流中写入一个数组或者JsonObject的开始,注意,这里不仅仅是写入一个[或者一个{这么简单,首先会调用writeDeferredName方法,它的主要功能是如果这个开始的JsonElement是JsonObject中的一个属性,那么它的前面肯定有一个和上一个元素的分割符号和一个名字。

endArray and endObject

结束一个数组和对象。

转自:http://chuyun923.github.io/blog/2015/01/10/gsonyuan-ma-zhi-streamchu-li/

http://chuyun923.github.io/blog/2015/01/06/gsonyuan-ma-fen-xi/

4月 232015
 

问题:

使用gson转json时出现下面错误:

com.google.gson.JsonParseException: Type information is unavailable, and the target object is not a primitive:xxxxx

分析:

为了转换方便,一般都会使用key:value方式组成json,有时会使用到下面这样稍微复杂些的json格式:

{

    “name”:”tom”,

    “age”:”18″,

    “scores”:

            {

                “sc1“:”100”,

                “sc2″:”90”

            }

}


当使用:

Gson gson = new GsonBuilder();

Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String,Object> arg = (Map<String, Object>) gson.fromJson(body, type);

时出现上述错误。 


解决方式:

 升级Gson包, 新Gson包有LinkedTreeMap可解决上述问题。 就是不使用LinkedTreeMap,直接object都可,搞定!


1月 212015
 

网上找到的关于Gson各特殊类型转换的代码实例,非常好,分享下。

转自:http://blog.csdn.net/lk_blog/article/details/7685190

Json转换利器Gson之实例一-简单对象转化和带泛型的List转化

Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。

jar和源码下载地址: http://code.google.com/p/google-gson/downloads/list


实体类:

[java] view plaincopy

  1.   
[java] view plaincopy

  1. public class Student {  
  2.     private int id;  
  3.     private String name;  
  4.     private Date birthDay;  
  5.   
  6.     public int getId() {  
  7.         return id;  
  8.     }  
  9.   
  10.     public void setId(int id) {  
  11.         this.id = id;  
  12.     }  
  13.   
  14.     public String getName() {  
  15.         return name;  
  16.     }  
  17.   
  18.     public void setName(String name) {  
  19.         this.name = name;  
  20.     }  
  21.   
  22.     public Date getBirthDay() {  
  23.         return birthDay;  
  24.     }  
  25.   
  26.     public void setBirthDay(Date birthDay) {  
  27.         this.birthDay = birthDay;  
  28.     }  
  29.   
  30.     @Override  
  31.     public String toString() {  
  32.         return “Student [birthDay=” + birthDay + “, id=” + id + “, name=”  
  33.                 + name + “]”;  
  34.     }  
  35.   
  36. }  

测试类:

[html] view plaincopy

  1. import java.util.ArrayList;  
  2. import java.util.Date;  
  3. import java.util.List;  
  4.   
  5. import com.google.gson.Gson;  
  6. import com.google.gson.reflect.TypeToken;  
  7.   
  8. public class GsonTest1 {  
  9.   
  10.     public static void main(String[] args) {  
  11.         Gson gson = new Gson();  
  12.   
  13.         Student student1 = new Student();  
  14.         student1.setId(1);  
  15.         student1.setName(“李坤”);  
  16.         student1.setBirthDay(new Date());  
  17.   
  18.         // //////////////////////////////////////////////////////////  
  19.         System.out.println(“———-简单对象之间的转化————-“);  
  20.         // 简单的bean转为json  
  21.         String s1 = gson.toJson(student1);  
  22.         System.out.println(“简单Bean转化为Json===” + s1);  
  23.   
  24.         // json转为简单Bean  
  25.         Student student = gson.fromJson(s1, Student.class);  
  26.         System.out.println(“Json转为简单Bean===” + student);  
  27.         // 结果:  
  28.         // 简单Bean转化为Json==={“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 8:27:52 AM”}  
  29.         // Json转为简单Bean===Student [birthDay=Fri Jun 22 08:27:52 CST 2012, id=1,  
  30.         // name=李坤]  
  31.         // //////////////////////////////////////////////////////////  
  32.   
  33.         Student student2 = new Student();  
  34.         student2.setId(2);  
  35.         student2.setName(“曹贵生”);  
  36.         student2.setBirthDay(new Date());  
  37.   
  38.         Student student3 = new Student();  
  39.         student3.setId(3);  
  40.         student3.setName(“柳波”);  
  41.         student3.setBirthDay(new Date());  
  42.   
  43.         List<Student> list = new ArrayList<Student>();  
  44.         list.add(student1);  
  45.         list.add(student2);  
  46.         list.add(student3);  
  47.   
  48.         System.out.println(“———-带泛型的List之间的转化————-“);  
  49.         // 带泛型的list转化为json  
  50.         String s2 = gson.toJson(list);  
  51.         System.out.println(“带泛型的list转化为json==” + s2);  
  52.   
  53.         // json转为带泛型的list  
  54.         List<Student> retList = gson.fromJson(s2,  
  55.                 new TypeToken<List<Student>>() {  
  56.                 }.getType());  
  57.         for (Student stu : retList) {  
  58.             System.out.println(stu);  
  59.         }  
  60.   
  61.         // 结果:  
  62.         // 带泛型的list转化为json==[{“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 8:28:52 AM”},{“id”:2,”name”:”曹贵生”,”birthDay”:”Jun 22, 2012 8:28:52 AM”},{“id”:3,”name”:”柳波”,”birthDay”:”Jun 22, 2012 8:28:52 AM”}]  
  63.         // Student [birthDay=Fri Jun 22 08:28:52 CST 2012, id=1name=李坤]  
  64.         // Student [birthDay=Fri Jun 22 08:28:52 CST 2012, id=2name=曹贵生]  
  65.         // Student [birthDay=Fri Jun 22 08:28:52 CST 2012, id=3name=柳波]  
  66.   
  67.     }  
  68. }  

执行结果:

[plain] view plaincopy

  1. ———-简单对象之间的转化————-  
  2. 简单Bean转化为Json==={“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 9:10:31 PM”}  
  3. Json转为简单Bean===Student [birthDay=Fri Jun 22 21:10:31 CST 2012, id=1, name=李坤]  
  4. ———-带泛型的List之间的转化————-  
  5. 带泛型的list转化为json==[{“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 9:10:31 PM”},{“id”:2,”name”:”曹贵生”,”birthDay”:”Jun 22, 2012 9:10:31 PM”},{“id”:3,”name”:”柳波”,”birthDay”:”Jun 22, 2012 9:10:31 PM”}]  
  6. Student [birthDay=Fri Jun 22 21:10:31 CST 2012, id=1, name=李坤]  
  7. Student [birthDay=Fri Jun 22 21:10:31 CST 2012, id=2, name=曹贵生]  
  8. Student [birthDay=Fri Jun 22 21:10:31 CST 2012, id=3, name=柳波]  

Json转换利器Gson之实例二-Gson注解和GsonBuilder

有时候我们不需要把实体的所有属性都导出,只想把一部分属性导出为Json.

有时候我们的实体类会随着版本的升级而修改.

有时候我们想对输出的json默认排好格式.

… …

请看下面的例子吧:

实体类:

[java] view plaincopy

  1. import java.util.Date;  
  2.   
  3. import com.google.gson.annotations.Expose;  
  4. import com.google.gson.annotations.SerializedName;  
  5.   
  6. public class Student {  
  7.     private int id;  
  8.       
  9.     @Expose  
  10.     private String name;  
  11.       
  12.     @Expose  
  13.     @SerializedName(“bir”)  
  14.     private Date birthDay;  
  15.   
  16.     public int getId() {  
  17.         return id;  
  18.     }  
  19.   
  20.     public void setId(int id) {  
  21.         this.id = id;  
  22.     }  
  23.   
  24.     public String getName() {  
  25.         return name;  
  26.     }  
  27.   
  28.     public void setName(String name) {  
  29.         this.name = name;  
  30.     }  
  31.   
  32.     public Date getBirthDay() {  
  33.         return birthDay;  
  34.     }  
  35.   
  36.     public void setBirthDay(Date birthDay) {  
  37.         this.birthDay = birthDay;  
  38.     }  
  39.   
  40.     @Override  
  41.     public String toString() {  
  42.         return “Student [birthDay=” + birthDay + “, id=” + id + “, name=”  
  43.                 + name + “]”;  
  44.     }  
  45.   
  46. }  

测试类:

[java] view plaincopy

  1. import java.util.ArrayList;  
  2. import java.util.Date;  
  3. import java.util.List;  
  4.   
  5. import com.google.gson.FieldNamingPolicy;  
  6. import com.google.gson.Gson;  
  7. import com.google.gson.GsonBuilder;  
  8. import com.google.gson.reflect.TypeToken;  
  9.   
  10. public class GsonTest2 {  
  11.   
  12.     public static void main(String[] args) {  
  13.         //注意这里的Gson的构建方式为GsonBuilder,区别于test1中的Gson gson = new Gson();  
  14.         Gson gson = new GsonBuilder()  
  15.         .excludeFieldsWithoutExposeAnnotation() //不导出实体中没有用@Expose注解的属性  
  16.         .enableComplexMapKeySerialization() //支持Map的key为复杂对象的形式  
  17.         .serializeNulls().setDateFormat(“yyyy-MM-dd HH:mm:ss:SSS”)//时间转化为特定格式    
  18.         .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)//会把字段首字母大写,注:对于实体上使用了@SerializedName注解的不会生效.  
  19.         .setPrettyPrinting() //对json结果格式化.  
  20.         .setVersion(1.0)    //有的字段不是一开始就有的,会随着版本的升级添加进来,那么在进行序列化和返序列化的时候就会根据版本号来选择是否要序列化.  
  21.                             //@Since(版本号)能完美地实现这个功能.还的字段可能,随着版本的升级而删除,那么  
  22.                             //@Until(版本号)也能实现这个功能,GsonBuilder.setVersion(double)方法需要调用.  
  23.         .create();  
  24.           
  25.           
  26.   
  27.         Student student1 = new Student();  
  28.         student1.setId(1);  
  29.         student1.setName(“李坤”);  
  30.         student1.setBirthDay(new Date());  
  31.   
  32.         // //////////////////////////////////////////////////////////  
  33.         System.out.println(“———-简单对象之间的转化————-“);  
  34.         // 简单的bean转为json  
  35.         String s1 = gson.toJson(student1);  
  36.         System.out.println(“简单Bean转化为Json===” + s1);  
  37.   
  38.         // json转为简单Bean  
  39.         Student student = gson.fromJson(s1, Student.class);  
  40.         System.out.println(“Json转为简单Bean===” + student);  
  41.         // //////////////////////////////////////////////////////////  
  42.   
  43.         Student student2 = new Student();  
  44.         student2.setId(2);  
  45.         student2.setName(“曹贵生”);  
  46.         student2.setBirthDay(new Date());  
  47.   
  48.         Student student3 = new Student();  
  49.         student3.setId(3);  
  50.         student3.setName(“柳波”);  
  51.         student3.setBirthDay(new Date());  
  52.   
  53.         List<Student> list = new ArrayList<Student>();  
  54.         list.add(student1);  
  55.         list.add(student2);  
  56.         list.add(student3);  
  57.   
  58.         System.out.println(“———-带泛型的List之间的转化————-“);  
  59.         // 带泛型的list转化为json  
  60.         String s2 = gson.toJson(list);  
  61.         System.out.println(“带泛型的list转化为json==” + s2);  
  62.   
  63.         // json转为带泛型的list  
  64.         List<Student> retList = gson.fromJson(s2,  
  65.                 new TypeToken<List<Student>>() {  
  66.                 }.getType());  
  67.         for (Student stu : retList) {  
  68.             System.out.println(stu);  
  69.         }  
  70.           
  71.     }  
  72. }  

输出结果:

[plain] view plaincopy

  1. ———-简单对象之间的转化————-  
  2. 简单Bean转化为Json==={  
  3.   “Name”: “李坤”,  
  4.   “bir”: “2012-06-22 21:26:40:592”  
  5. }  
  6. Json转为简单Bean===Student [birthDay=Fri Jun 22 21:26:40 CST 2012, id=0, name=李坤]  
  7. ———-带泛型的List之间的转化————-  
  8. 带泛型的list转化为json==[  
  9.   {  
  10.     “Name”: “李坤”,  
  11.     “bir”: “2012-06-22 21:26:40:592”  
  12.   },  
  13.   {  
  14.     “Name”: “曹贵生”,  
  15.     “bir”: “2012-06-22 21:26:40:625”  
  16.   },  
  17.   {  
  18.     “Name”: “柳波”,  
  19.     “bir”: “2012-06-22 21:26:40:625”  
  20.   }  
  21. ]  
  22. Student [birthDay=Fri Jun 22 21:26:40 CST 2012, id=0, name=李坤]  
  23. Student [birthDay=Fri Jun 22 21:26:40 CST 2012, id=0, name=曹贵生]  
  24. Student [birthDay=Fri Jun 22 21:26:40 CST 2012, id=0, name=柳波]  

 

Json转换利器Gson之实例三-Map处理

Map的存储结构式Key/Value形式,Key 和 Value可以是普通类型,也可以是自己写的JavaBean(本文),还可以是带有泛型的List(下一篇博客).本例中您要重点看如何将Json转回为普通JavaBean对象时TypeToken的定义.

实体类:

[java] view plaincopy

  1. public class Point {  
  2.     private int x;  
  3.     private int y;  
  4.   
  5.     public Point(int x, int y) {  
  6.         this.x = x;  
  7.         this.y = y;  
  8.     }  
  9.   
  10.     public int getX() {  
  11.         return x;  
  12.     }  
  13.   
  14.     public void setX(int x) {  
  15.         this.x = x;  
  16.     }  
  17.   
  18.     public int getY() {  
  19.         return y;  
  20.     }  
  21.   
  22.     public void setY(int y) {  
  23.         this.y = y;  
  24.     }  
  25.   
  26.     @Override  
  27.     public String toString() {  
  28.         return “Point [x=” + x + “, y=” + y + “]”;  
  29.     }  
  30.   
  31. }  

测试类:

[java] view plaincopy

  1. import java.util.LinkedHashMap;  
  2. import java.util.Map;  
  3.   
  4. import com.google.gson.Gson;  
  5. import com.google.gson.GsonBuilder;  
  6. import com.google.gson.reflect.TypeToken;  
  7.   
  8. public class GsonTest3 {  
  9.   
  10.     public static void main(String[] args) {  
  11.         Gson gson = new GsonBuilder().enableComplexMapKeySerialization()  
  12.                 .create();  
  13.   
  14.         Map<Point, String> map1 = new LinkedHashMap<Point, String>();// 使用LinkedHashMap将结果按先进先出顺序排列  
  15.         map1.put(new Point(56), “a”);  
  16.         map1.put(new Point(88), “b”);  
  17.         String s = gson.toJson(map1);  
  18.         System.out.println(s);// 结果:[[{“x”:5,”y”:6},”a”],[{“x”:8,”y”:8},”b”]]  
  19.   
  20.         Map<Point, String> retMap = gson.fromJson(s,  
  21.                 new TypeToken<Map<Point, String>>() {  
  22.                 }.getType());  
  23.         for (Point p : retMap.keySet()) {  
  24.             System.out.println(“key:” + p + ” values:” + retMap.get(p));  
  25.         }  
  26.         System.out.println(retMap);  
  27.   
  28.         System.out.println(“———————————-“);  
  29.         Map<String, Point> map2 = new LinkedHashMap<String, Point>();  
  30.         map2.put(“a”new Point(34));  
  31.         map2.put(“b”new Point(56));  
  32.         String s2 = gson.toJson(map2);  
  33.         System.out.println(s2);  
  34.   
  35.         Map<String, Point> retMap2 = gson.fromJson(s2,  
  36.                 new TypeToken<Map<String, Point>>() {  
  37.                 }.getType());  
  38.         for (String key : retMap2.keySet()) {  
  39.             System.out.println(“key:” + key + ” values:” + retMap2.get(key));  
  40.         }  
  41.   
  42.     }  
  43. }  

结果:

[plain] view plaincopy

  1. [[{“x”:5,”y”:6},”a”],[{“x”:8,”y”:8},”b”]]  
  2. key:Point [x=5, y=6] values:a  
  3. key:Point [x=8, y=8] values:b  
  4. {Point [x=5, y=6]=a, Point [x=8, y=8]=b}  
  5. ———————————-  
  6. {“a”:{“x”:3,”y”:4},”b”:{“x”:5,”y”:6}}  
  7. key:a values:Point [x=3, y=4]  
  8. key:b values:Point [x=5, y=6]  

Map的存储结构式Key/Value形式,Key 和 Value可以是普通类型,也可以是自己写的JavaBean,还可以是带有泛型的List(本文).本例中您要重点看如何将Json转回为带泛型的对象List,并且List中的泛型对象有多种实体.

实体类:

[java] view plaincopy

  1. import java.util.Date;  
  2.   
  3. public class Student {  
  4.     private int id;  
  5.     private String name;  
  6.     private Date birthDay;  
  7.   
  8.     public int getId() {  
  9.         return id;  
  10.     }  
  11.   
  12.     public void setId(int id) {  
  13.         this.id = id;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public Date getBirthDay() {  
  25.         return birthDay;  
  26.     }  
  27.   
  28.     public void setBirthDay(Date birthDay) {  
  29.         this.birthDay = birthDay;  
  30.     }  
  31.   
  32.     @Override  
  33.     public String toString() {  
  34.         return “Student [birthDay=” + birthDay + “, id=” + id + “, name=”  
  35.                 + name + “]”;  
  36.     }  
  37.   
  38. }  

[java] view plaincopy

  1. public class Teacher {  
  2.     private int id;  
  3.   
  4.     private String name;  
  5.   
  6.     private String title;  
  7.   
  8.     public int getId() {  
  9.         return id;  
  10.     }  
  11.   
  12.     public void setId(int id) {  
  13.         this.id = id;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public String getTitle() {  
  25.         return title;  
  26.     }  
  27.   
  28.     public void setTitle(String title) {  
  29.         this.title = title;  
  30.     }  
  31.   
  32.     @Override  
  33.     public String toString() {  
  34.         return “Teacher [id=” + id + “, name=” + name + “, title=” + title  
  35.                 + “]”;  
  36.     }  
  37.   
  38. }  

测试类:

[java] view plaincopy

  1. package com.tgb.lk.demo.gson.test4;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Date;  
  5. import java.util.LinkedHashMap;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8.   
  9. import com.google.gson.Gson;  
  10. import com.google.gson.reflect.TypeToken;  
  11.   
  12. public class GsonTest4 {  
  13.     public static void main(String[] args) {  
  14.         Student student1 = new Student();  
  15.         student1.setId(1);  
  16.         student1.setName(“李坤”);  
  17.         student1.setBirthDay(new Date());  
  18.   
  19.         Student student2 = new Student();  
  20.         student2.setId(2);  
  21.         student2.setName(“曹贵生”);  
  22.         student2.setBirthDay(new Date());  
  23.   
  24.         Student student3 = new Student();  
  25.         student3.setId(3);  
  26.         student3.setName(“柳波”);  
  27.         student3.setBirthDay(new Date());  
  28.   
  29.         List<Student> stulist = new ArrayList<Student>();  
  30.         stulist.add(student1);  
  31.         stulist.add(student2);  
  32.         stulist.add(student3);  
  33.   
  34.         Teacher teacher1 = new Teacher();  
  35.         teacher1.setId(1);  
  36.         teacher1.setName(“米老师”);  
  37.         teacher1.setTitle(“教授”);  
  38.   
  39.         Teacher teacher2 = new Teacher();  
  40.         teacher2.setId(2);  
  41.         teacher2.setName(“丁老师”);  
  42.         teacher2.setTitle(“讲师”);  
  43.         List<Teacher> teacherList = new ArrayList<Teacher>();  
  44.         teacherList.add(teacher1);  
  45.         teacherList.add(teacher2);  
  46.   
  47.         Map<String, Object> map = new LinkedHashMap<String, Object>();  
  48.         map.put(“students”, stulist);  
  49.         map.put(“teachers”, teacherList);  
  50.   
  51.         Gson gson = new Gson();  
  52.         String s = gson.toJson(map);  
  53.         System.out.println(s);  
  54.   
  55.         System.out.println(“———————————-“);  
  56.   
  57.         Map<String, Object> retMap = gson.fromJson(s,  
  58.                 new TypeToken<Map<String, List<Object>>>() {  
  59.                 }.getType());  
  60.   
  61.         for (String key : retMap.keySet()) {  
  62.             System.out.println(“key:” + key + ” values:” + retMap.get(key));  
  63.             if (key.equals(“students”)) {  
  64.                 List<Student> stuList = (List<Student>) retMap.get(key);  
  65.                 System.out.println(stuList);  
  66.             } else if (key.equals(“teachers”)) {  
  67.                 List<Teacher> tchrList = (List<Teacher>) retMap.get(key);  
  68.                 System.out.println(tchrList);  
  69.             }  
  70.         }  
  71.   
  72.     }  
  73. }  

输出结果:

[plain] view plaincopy

  1. {“students”:[{“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 9:48:19 PM”},{“id”:2,”name”:”曹贵生”,”birthDay”:”Jun 22, 2012 9:48:19 PM”},{“id”:3,”name”:”柳波”,”birthDay”:”Jun 22, 2012 9:48:19 PM”}],”teachers”:[{“id”:1,”name”:”米老师”,”title”:”教授”},{“id”:2,”name”:”丁老师”,”title”:”讲师”}]}  
  2. ———————————-  
  3. key:students values:[{id=1.0, name=李坤, birthDay=Jun 22, 2012 9:48:19 PM}, {id=2.0, name=曹贵生, birthDay=Jun 22, 2012 9:48:19 PM}, {id=3.0, name=柳波, birthDay=Jun 22, 2012 9:48:19 PM}]  
  4. [{id=1.0, name=李坤, birthDay=Jun 22, 2012 9:48:19 PM}, {id=2.0, name=曹贵生, birthDay=Jun 22, 2012 9:48:19 PM}, {id=3.0, name=柳波, birthDay=Jun 22, 2012 9:48:19 PM}]  
  5. key:teachers values:[{id=1.0, name=米老师, title=教授}, {id=2.0, name=丁老师, title=讲师}]  
  6. [{id=1.0, name=米老师, title=教授}, {id=2.0, name=丁老师, title=讲师}]  

 

Json转换利器Gson之实例-实际开发中的特殊需求处理

前面博客基本上可以满足我们处理的绝大多数需求,但有时项目中对json有特殊的格式规定.比如下面的json串解析:

[{“tableName”:”students”,”tableData”:[{“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 9:54:49 PM”},{“id”:2,”name”:”曹贵生”,”birthDay”:”Jun 22, 2012 9:54:49 PM”},{“id”:3,”name”:”柳波”,”birthDay”:”Jun 22, 2012 9:54:49 PM”}]},{“tableName”:”teachers”,”tableData”:[{“id”:1,”name”:”米老师”,”title”:”教授”},{“id”:2,”name”:”丁老师”,”title”:”讲师”}]}]

分析之后我们发现使用前面博客中用到的都不好处理上面的json串.请看本文是如何处理的吧:

实体类:

[java] view plaincopy

  1. import java.util.Date;  
  2.   
  3. public class Student {  
  4.     private int id;  
  5.     private String name;  
  6.     private Date birthDay;  
  7.   
  8.     public int getId() {  
  9.         return id;  
  10.     }  
  11.   
  12.     public void setId(int id) {  
  13.         this.id = id;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public Date getBirthDay() {  
  25.         return birthDay;  
  26.     }  
  27.   
  28.     public void setBirthDay(Date birthDay) {  
  29.         this.birthDay = birthDay;  
  30.     }  
  31.   
  32.     @Override  
  33.     public String toString() {  
  34.         return “Student [birthDay=” + birthDay + “, id=” + id + “, name=”  
  35.                 + name + “]”;  
  36.     }  
  37.   
  38. }  

[java] view plaincopy

  1. public class Teacher {  
  2.     private int id;  
  3.   
  4.     private String name;  
  5.   
  6.     private String title;  
  7.   
  8.     public int getId() {  
  9.         return id;  
  10.     }  
  11.   
  12.     public void setId(int id) {  
  13.         this.id = id;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public String getTitle() {  
  25.         return title;  
  26.     }  
  27.   
  28.     public void setTitle(String title) {  
  29.         this.title = title;  
  30.     }  
  31.   
  32.     @Override  
  33.     public String toString() {  
  34.         return “Teacher [id=” + id + “, name=” + name + “, title=” + title  
  35.                 + “]”;  
  36.     }  
  37.   
  38. }  

注意这里定义了一个TableData实体类:

[java] view plaincopy

  1. import java.util.List;  
  2.   
  3. public class TableData {  
  4.   
  5.     private String tableName;  
  6.   
  7.     private List tableData;  
  8.   
  9.     public String getTableName() {  
  10.         return tableName;  
  11.     }  
  12.   
  13.     public void setTableName(String tableName) {  
  14.         this.tableName = tableName;  
  15.     }  
  16.   
  17.     public List getTableData() {  
  18.         return tableData;  
  19.     }  
  20.   
  21.     public void setTableData(List tableData) {  
  22.         this.tableData = tableData;  
  23.     }  
  24. }  

测试类:

(仔细看将json转回为对象的实现,这里经过两次转化,第一次转回的结果是map不是我们所期望的对象,对map再次转为json后再转为对象,我引用的是Gson2.1的jar处理正常,好像使用Gson1.6的jar会报错,所以建议用最新版本)

[java] view plaincopy

  1. import java.util.ArrayList;  
  2. import java.util.Date;  
  3. import java.util.List;  
  4.   
  5. import com.google.gson.Gson;  
  6. import com.google.gson.reflect.TypeToken;  
  7.   
  8. public class GsonTest5 {  
  9.   
  10.     /** 
  11.      * @param args 
  12.      */  
  13.     public static void main(String[] args) {  
  14.         // 对象转为Json–>start  
  15.         Student student1 = new Student();  
  16.         student1.setId(1);  
  17.         student1.setName(“李坤”);  
  18.         student1.setBirthDay(new Date());  
  19.   
  20.         Student student2 = new Student();  
  21.         student2.setId(2);  
  22.         student2.setName(“曹贵生”);  
  23.         student2.setBirthDay(new Date());  
  24.   
  25.         Student student3 = new Student();  
  26.         student3.setId(3);  
  27.         student3.setName(“柳波”);  
  28.         student3.setBirthDay(new Date());  
  29.   
  30.         List<Student> stulist = new ArrayList<Student>();  
  31.         stulist.add(student1);  
  32.         stulist.add(student2);  
  33.         stulist.add(student3);  
  34.   
  35.         Teacher teacher1 = new Teacher();  
  36.         teacher1.setId(1);  
  37.         teacher1.setName(“米老师”);  
  38.         teacher1.setTitle(“教授”);  
  39.   
  40.         Teacher teacher2 = new Teacher();  
  41.         teacher2.setId(2);  
  42.         teacher2.setName(“丁老师”);  
  43.         teacher2.setTitle(“讲师”);  
  44.         List<Teacher> teacherList = new ArrayList<Teacher>();  
  45.         teacherList.add(teacher1);  
  46.         teacherList.add(teacher2);  
  47.   
  48.         TableData td1 = new TableData();  
  49.         td1.setTableName(“students”);  
  50.         td1.setTableData(stulist);  
  51.   
  52.         TableData td2 = new TableData();  
  53.         td2.setTableName(“teachers”);  
  54.         td2.setTableData(teacherList);  
  55.   
  56.         List<TableData> tdList = new ArrayList<TableData>();  
  57.         tdList.add(td1);  
  58.         tdList.add(td2);  
  59.         Gson gson = new Gson();  
  60.         String s = gson.toJson(tdList);  
  61.   
  62.         System.out.println(s);  
  63.         // 结果:[{“tableName”:”students”,”tableData”:[{“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 10:44:16 AM”},{“id”:2,”name”:”曹贵生”,”birthDay”:”Jun 22, 2012 10:44:16 AM”},{“id”:3,”name”:”柳波”,”birthDay”:”Jun 22, 2012 10:44:16 AM”}]},{“tableName”:”teachers”,”tableData”:[{“id”:1,”name”:”米老师”,”title”:”教授”},{“id”:2,”name”:”丁老师”,”title”:”讲师”}]}]  
  64.         // 对象转为Json–>end  
  65.   
  66.         // /////////////////////////////////////////////////////////////////////  
  67.   
  68.         // 将json转为数据–>start  
  69.         List<TableData> tableDatas2 = gson.fromJson(s,  
  70.                 new TypeToken<List<TableData>>() {  
  71.                 }.getType());  
  72.         for (int i = 0; i < tableDatas2.size(); i++) {  
  73.             TableData entityData = tableDatas2.get(i);  
  74.             String tableName = entityData.getTableName();  
  75.             List tableData = entityData.getTableData();  
  76.             String s2 = gson.toJson(tableData);  
  77.             // System.out.println(s2);  
  78.             // System.out.println(entityData.getData());  
  79.             if (tableName.equals(“students”)) {  
  80.                 System.out.println(“students”);  
  81.                 List<Student> retStuList = gson.fromJson(s2,  
  82.                         new TypeToken<List<Student>>() {  
  83.                         }.getType());  
  84.                 for (int j = 0; j < retStuList.size(); j++) {  
  85.                     System.out.println(retStuList.get(j));  
  86.                 }  
  87.   
  88.             } else if (tableName.equals(“teachers”)) {  
  89.                 System.out.println(“teachers”);  
  90.                 List<Teacher> retTchrList = gson.fromJson(s2,  
  91.                         new TypeToken<List<Teacher>>() {  
  92.                         }.getType());  
  93.                 for (int j = 0; j < retTchrList.size(); j++) {  
  94.                     System.out.println(retTchrList.get(j));  
  95.                 }  
  96.             }  
  97.         }  
  98.   
  99.         // Json转为对象–>end  
  100.     }  
  101. }  

输出结果:

[plain] view plaincopy

  1. [{“tableName”:”students”,”tableData”:[{“id”:1,”name”:”李坤”,”birthDay”:”Jun 22, 2012 10:04:12 PM”},{“id”:2,”name”:”曹贵生”,”birthDay”:”Jun 22, 2012 10:04:12 PM”},{“id”:3,”name”:”柳波”,”birthDay”:”Jun 22, 2012 10:04:12 PM”}]},{“tableName”:”teachers”,”tableData”:[{“id”:1,”name”:”米老师”,”title”:”教授”},{“id”:2,”name”:”丁老师”,”title”:”讲师”}]}]  
  2. students  
  3. Student [birthDay=Fri Jun 22 22:04:12 CST 2012, id=1, name=李坤]  
  4. Student [birthDay=Fri Jun 22 22:04:12 CST 2012, id=2, name=曹贵生]  
  5. Student [birthDay=Fri Jun 22 22:04:12 CST 2012, id=3, name=柳波]  
  6. teachers  
  7. Teacher [id=1, name=米老师, title=教授]  
  8. Teacher [id=2, name=丁老师, title=讲师]  

Json转换利器Gson之实例六-注册TypeAdapter及处理Enum类型

枚举类型给我们的程序带来了好处,如何用Gson来实现与Json的互转呢?请看本文.

本文重点掌握如何自己写一个TypeAdapter及注册TypeAdapter和处理Enum类型.

实体类:

[java] view plaincopy

  1. public enum PackageState {  
  2.     PLAY, UPDATE, UPDATING, DOWNLOAD, DOWNLOADING,  
  3. }  

[java] view plaincopy

  1. public class PackageItem {  
  2.     private String name;  
  3.     private PackageState state;  
  4.     private String size;  
  5.   
  6.     public String getName() {  
  7.         return name;  
  8.     }  
  9.   
  10.     public void setName(String name) {  
  11.         this.name = name;  
  12.     }  
  13.   
  14.     public PackageState getState() {  
  15.         return state;  
  16.     }  
  17.   
  18.     public void setState(PackageState state) {  
  19.         this.state = state;  
  20.     }  
  21.   
  22.     public String getSize() {  
  23.         return size;  
  24.     }  
  25.   
  26.     public void setSize(String size) {  
  27.         this.size = size;  
  28.     }  
  29.   
  30.     @Override  
  31.     public String toString() {  
  32.         return “PackageItem [name=” + name + “, size=” + size + “, state=”  
  33.                 + state + “]”;  
  34.     }  
  35. }  

自己写一个转换器实现JsonSerializer<T>接口和jsonDeserializer<T>接口:

[java] view plaincopy

  1. mport java.lang.reflect.Type;  
  2.   
  3. import com.google.gson.JsonDeserializationContext;  
  4. import com.google.gson.JsonDeserializer;  
  5. import com.google.gson.JsonElement;  
  6. import com.google.gson.JsonParseException;  
  7. import com.google.gson.JsonPrimitive;  
  8. import com.google.gson.JsonSerializationContext;  
  9. import com.google.gson.JsonSerializer;  
  10.   
  11. public class EnumSerializer implements JsonSerializer<PackageState>,  
  12.         JsonDeserializer<PackageState> {  
  13.   
  14.     // 对象转为Json时调用,实现JsonSerializer<PackageState>接口  
  15.     @Override  
  16.     public JsonElement serialize(PackageState state, Type arg1,  
  17.             JsonSerializationContext arg2) {  
  18.         return new JsonPrimitive(state.ordinal());  
  19.     }  
  20.   
  21.     // json转为对象时调用,实现JsonDeserializer<PackageState>接口  
  22.     @Override  
  23.     public PackageState deserialize(JsonElement json, Type typeOfT,  
  24.             JsonDeserializationContext context) throws JsonParseException {  
  25.         if (json.getAsInt() < PackageState.values().length)  
  26.             return PackageState.values()[json.getAsInt()];  
  27.         return null;  
  28.     }  
  29.   
  30. }  

测试类:

[java] view plaincopy

  1. import com.google.gson.Gson;  
  2. import com.google.gson.GsonBuilder;  
  3.   
  4. public class GsonTest6 {  
  5.   
  6.     public static void main(String[] args) {  
  7.         GsonBuilder gsonBuilder = new GsonBuilder();  
  8.         gsonBuilder.registerTypeAdapter(PackageState.class,  
  9.                 new EnumSerializer());  
  10.         Gson gson = gsonBuilder.create();  
  11.         PackageItem item = new PackageItem();  
  12.         item.setName(“item_name”);  
  13.         item.setSize(“500M”);  
  14.         item.setState(PackageState.UPDATING);// 这个 state是枚举值  
  15.   
  16.         String s = gson.toJson(item);  
  17.         System.out.println(s);  
  18.   
  19.         System.out.println(“——————————–“);  
  20.   
  21.         PackageItem retItem = gson.fromJson(s, PackageItem.class);  
  22.         System.out.println(retItem);  
  23.     }  
  24. }  


输出结果(结果中已经将state的对应枚举类型转为了int类型):

[plain] view plaincopy

  1. {“name”:”item_name”,”state”:2,”size”:”500M”}  
  2. ——————————–  
  3. PackageItem [name=item_name, size=500M, state=UPDATING]  

6月 302014
 

虽然文章来自英文的,但精华还是在实例代码部分,我自己看完受益匪浅,强烈推荐! 由于格式问题,我仅摘录两个实例。

例子一:

定义一个简单类:
package com.javacreed.examples.gson.part1;

import com.google.gson.annotations.SerializedName;

public class Box { 
    @SerializedName("w") 
    private int width; 
    
    @SerializedName("h")
    private int height; 
    
    @SerializedName("d") 
    private int depth; 
    // Methods removed for brevity 
}
使用:
package com.javacreed.examples.gson.part1;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {
  public static void main(final String[] args) {
    final GsonBuilder builder = new GsonBuilder();
    final Gson gson = builder.create();

    final Box box = new Box();
    box.setWidth(10);
    box.setHeight(20);
    box.setDepth(30);

    final String json = gson.toJson(box);
    System.out.printf("Serialised: %s%n", json);

    final Box otherBox = gson.fromJson(json, Box.class);
    System.out.printf("Same box: %s%n", box.equals(otherBox));
  }
}
显示结果:

Serialised: {"w":10,"h":20,"d":30}
Same box: true

例子二:

定义一个简单类:
package com.javacreed.examples.gson.part2;

import com.google.gson.annotations.Expose;

public class Account { 
    @Expose(deserialize = false) 
    private String accountNumber; 
    @Expose private String iban; 
    @Expose(serialize = false) 
    private String owner; 
    @Expose(serialize = false, deserialize = false) 
    private String address;

    private String pin;
}
说明:
Field Serialise Deserialise
@Expose(deserialize = false)
private String accountNumber;
YES NO
@Expose
private String iban;
YES YES
@Expose(serialize = false)
private String owner;
NO YES
@Expose(serialize = false, deserialize = false)
private String address;
NO NO
private String pin;
NO NO

使用:

package com.javacreed.examples.gson.part2;

import java.io.InputStreamReader;
import java.io.Reader;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {
  public static void main(final String[] args) throws Exception {
    final GsonBuilder builder = new GsonBuilder();
    builder.excludeFieldsWithoutExposeAnnotation();
    final Gson gson = builder.create();

    final Account account = new Account();
    account.setAccountNumber("A123 45678 90");
    account.setIban("IBAN 11 22 33 44");
    account.setOwner("Albert Attard");
    account.setPin("1234");
    account.setAddress("Somewhere, Far Far Away");

    final String json = gson.toJson(account);
    System.out.printf("Serialised%n  %s%n", json);

    try (final Reader data = new InputStreamReader(Main.class.getResourceAsStream("account.json"), "UTF-8")) {

      final Account otherAccount = gson.fromJson(data, Account.class);
      System.out.println("Deserialised");
      System.out.printf("  Account Number: %s%n", otherAccount.getAccountNumber());
      System.out.printf("  IBAN:           %s%n", otherAccount.getIban());
      System.out.printf("  Owner:          %s%n", otherAccount.getOwner());
      System.out.printf("  Pin:            %s%n", otherAccount.getPin());
      System.out.printf("  Address:        %s%n", otherAccount.getAddress());
    }
  }
}
显示结果:
Serialised
  {"accountNumber":"A123 45678 90","iban":"IBAN 11 22 33 44"}
Deserialised
  Account Number: null
  IBAN:           IBAN 11 22 33 44
  Owner:          Albert Attard
  Pin:            null
  Address:        null

更详细内容可参考http://www.javacreed.com/gson-annotations-example/

5月 282014
 

今天碰到个gson转数组对象的问题,查到下资料,分享下:


GsonGoogle的开源项目(项目主页:https://code.google.com/p/google-gson/),

Gson在线帮助文档:http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/index.html

Gson包下载地址:https://google-gson.googlecode.com/files/google-gson-2.2.4-release.zip

 

示例:

Java代码  收藏代码

  1. import java.util.ArrayList;  
  2. import java.util.Arrays;  
  3. import java.util.Collection;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.    
  7. import com.google.gson.Gson;  
  8. import com.google.gson.reflect.TypeToken;  
  9.    
  10. class User{  
  11.    public User(String name,int age,StringBuffer sex,boolean isChild){  
  12.       this.name = name;  
  13.       this.age = age;  
  14.       this.sex = sex;  
  15.       this.isChild = isChild;  
  16.    }  
  17.    private String name;  
  18.    private int age;  
  19.    private StringBuffer sex;  
  20.    private boolean isChild;  
  21.    public String toString(){  
  22.       return “{name=”+name+“;age=”+age+“;sex=”+sex+“;isChild=”+isChild+“}”;  
  23.    }  
  24.    public int hashCode(){  
  25.       return name.hashCode()*100+age;  
  26.    }  
  27. }  
  28.    
  29. public class GsonTest {  
  30.    public static void main(String[] args) {  
  31.       Gson gson = new Gson();  
  32.        
  33.       System.out.println(“1普通的Bean的转换**************************”);  
  34.       System.out.println(“将一个Bean转换成为json字符串->”);  
  35.       User user1 = new User(“凤姐”,12,new StringBuffer(“未知”),true);  
  36.       System.out.println(“转换之前的user1”+user1);  
  37.       String json = gson.toJson(user1);  
  38.       System.out.println(“User对象转换成为Json字符串,json===”+json);  
  39.        
  40.       System.out.println(“***************************”);  
  41.       System.out.println(“将一个json字符串转换成为Bean->”);  
  42.       User user2 = gson.fromJson(json, User.class);  
  43.       System.out.println(“转换成为的user2==”+user2);  
  44.       System.out.println();  
  45.        
  46.       System.out.println(“2Collection集合的转换**************************”);  
  47.       System.out.println(“将一个Bean的List集合转换成为json字符串->”);  
  48.       Collection<User> userList1 = new ArrayList<User>();  
  49.       for(int i=0;i<3;i++){  
  50.         User user = new User(“如花”,10+i,new StringBuffer(“男”),false);  
  51.         userList1.add(user);  
  52.       }  
  53.       json = gson.toJson(userList1);  
  54.       System.out.println(“User的List集合对象转换成为Json字符串,json===”+json);  
  55.        
  56.       System.out.println(“***************************”);  
  57.       System.out.println(“将一个json字符串转换成为Bean的List集合->”);  
  58.       Collection<User> userList2 =  
  59.            gson.fromJson(json,  
  60.                  new TypeToken<Collection<User>>(){}.getType());  
  61.       System.out.println(“转换成为的User的List集合,userList2=”+userList2);  
  62.       System.out.println();  
  63.        
  64.       System.out.println(“3Array数组的转换**************************”);  
  65.       System.out.println(“将一个Bean的Array数组转换成为json字符串->”);  
  66.       User [] userArray1 = new User[3];  
  67.       for(int i=0;i<userArray1.length;i++){  
  68.         userArray1[i] = new User(“芙蓉”,20,new StringBuffer(“人妖”),true);  
  69.       }  
  70.       json = gson.toJson(userArray1);  
  71.       System.out.println(“User的数组对象转换成为Json字符串,json===”+json);  
  72.        
  73.       System.out.println(“***************************”);  
  74.       System.out.println(“将一个json字符串转换成为Bean的数组对象->”);  
  75.       User [] userArray2 = gson.fromJson(json, new TypeToken<User[]>(){}.getType());  
  76.       System.out.println(“转换成为的User的数组对象,userArray2=”+Arrays.toString(userArray2));  
  77.       System.out.println();  
  78.        
  79.       System.out.println(“4Map的转换**************************”);  
  80.       System.out.println(“将一个Bean的Map转换成为json字符串->”);  
  81.       Map<String,User> map1 = new HashMap<String,User>();  
  82.       for(int i=0;i<3;i++){  
  83.         map1.put(“”+(i+10), userArray1[i]);  
  84.       }  
  85.       json = gson.toJson(map1);  
  86.       System.out.println(“User的Map集合转换成为Json字符串,json===”+json);  
  87.        
  88.       System.out.println(“***************************”);  
  89.       System.out.println(“将一个json字符串转换成为Bean的数组对象->”);  
  90.       Map<String,User> map2 =  
  91.            gson.fromJson(json,  
  92.                  new TypeToken<Map<String,User>>(){}.getType());  
  93.       System.out.println(“转换成为的User的数组对象,map2==”+map2);  
  94.    }  
  95. }  

运行结果:

Java代码  收藏代码

  1. 1普通的Bean的转换**************************  
  2. 将一个Bean转换成为json字符串->  
  3. 转换之前的user1{name=凤姐;age=12;sex=未知;isChild=true}  
  4. User对象转换成为Json字符串,json==={“name”:“凤姐”,“age”:12,“sex”:“未知”,“isChild”:true}  
  5. ***************************  
  6. 将一个json字符串转换成为Bean->  
  7. 转换成为的user2=={name=凤姐;age=12;sex=未知;isChild=true}  
  8.   
  9. 2Collection集合的转换**************************  
  10. 将一个Bean的List集合转换成为json字符串->  
  11. User的List集合对象转换成为Json字符串,json===[{“name”:“如花”,“age”:10,“sex”:“男”,“isChild”:false},{“name”:“如花”,“age”:11,“sex”:“男”,“isChild”:false},{“name”:“如花”,“age”:12,“sex”:“男”,“isChild”:false}]  
  12. ***************************  
  13. 将一个json字符串转换成为Bean的List集合->  
  14. 转换成为的User的List集合,userList2=[{name=如花;age=10;sex=男;isChild=false}, {name=如花;age=11;sex=男;isChild=false}, {name=如花;age=12;sex=男;isChild=false}]  
  15.   
  16. 3Array数组的转换**************************  
  17. 将一个Bean的Array数组转换成为json字符串->  
  18. User的数组对象转换成为Json字符串,json===[{“name”:“芙蓉”,“age”:20,“sex”:“人妖”,“isChild”:true},{“name”:“芙蓉”,“age”:20,“sex”:“人妖”,“isChild”:true},{“name”:“芙蓉”,“age”:20,“sex”:“人妖”,“isChild”:true}]  
  19. ***************************  
  20. 将一个json字符串转换成为Bean的数组对象->  
  21. 转换成为的User的数组对象,userArray2=[{name=芙蓉;age=20;sex=人妖;isChild=true}, {name=芙蓉;age=20;sex=人妖;isChild=true}, {name=芙蓉;age=20;sex=人妖;isChild=true}]  
  22.   
  23. 4Map的转换**************************  
  24. 将一个Bean的Map转换成为json字符串->  
  25. User的Map集合转换成为Json字符串,json==={“10”:{“name”:“芙蓉”,“age”:20,“sex”:“人妖”,“isChild”:true},“11”:{“name”:“芙蓉”,“age”:20,“sex”:“人妖”,“isChild”:true},“12”:{“name”:“芙蓉”,“age”:20,“sex”:“人妖”,“isChild”:true}}  
  26. ***************************  
  27. 将一个json字符串转换成为Bean的数组对象->  
  28. 转换成为的User的数组对象,map2=={10={name=芙蓉;age=20;sex=人妖;isChild=true}, 11={name=芙蓉;age=20;sex=人妖;isChild=true}, 12={name=芙蓉;age=20;sex=人妖;isChild=true}}  

转自:http://forestqqqq.iteye.com/blog/1942328

使用gson包对简单数据以Map解析

 java  使用gson包对简单数据以Map解析已关闭评论
3月 242014
 

对于简单json返回,想通过gson包以map类型解析,可参考下面的代码: 

public static void main(String[] args) { 

     String rt = “{ “result”:0 }”; 

     Gson gson = new Gson(); 

     java.lang.reflect.Type type=new com.google.gson.reflect.TypeToken>(){}.getType(); 

     HashMap m = (HashMap)gson.fromJson(rt,type); 

     System.out.println(m); 

 }

9月 042013
 

创建类型适配类:

Timestamp类型适配类代码  收藏代码

  1. import java.lang.reflect.Type;  
  2. import java.sql.Timestamp;  
  3. import java.text.DateFormat;  
  4. import java.text.ParseException;  
  5. import java.text.SimpleDateFormat;  
  6. import java.util.Date;  
  7.   
  8. import com.google.gson.JsonDeserializationContext;  
  9. import com.google.gson.JsonDeserializer;  
  10. import com.google.gson.JsonElement;  
  11. import com.google.gson.JsonParseException;  
  12. import com.google.gson.JsonPrimitive;  
  13. import com.google.gson.JsonSerializationContext;  
  14. import com.google.gson.JsonSerializer;  
  15.   
  16. public class TimestampTypeAdapter implements JsonSerializer<Timestamp>, JsonDeserializer<Timestamp>{  
  17.     private final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.     public JsonElement serialize(Timestamp src, Type arg1, JsonSerializationContext arg2) {  
  19.         String dateFormatAsString = format.format(new Date(src.getTime()));  
  20.         return new JsonPrimitive(dateFormatAsString);  
  21.     }  
  22.   
  23.     public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {  
  24.         if (!(json instanceof JsonPrimitive)) {  
  25.             throw new JsonParseException("The date should be a string value");  
  26.         }  
  27.   
  28.         try {  
  29.             Date date = format.parse(json.getAsString());  
  30.             return new Timestamp(date.getTime());  
  31.         } catch (ParseException e) {  
  32.             throw new JsonParseException(e);  
  33.         }  
  34.     }  
  35.   
  36. }  

 

  类型适配类

   应用类型适配器 写道

Gson gson = new GsonBuilder().registerTypeAdapter(Timestamp.class,new TimestampTypeAdapter()).setDateFormat("yyyy-MM-dd HH:mm:ss").create();
String jsonString = gson.toJson(resourceInfo,ResourceGeoInfo.class);

  
   输出结果

{"positionTime":"2010-01-07 10:57:27"}

 

Date 类型的时间转换第二种方式;

 

Java代码  收藏代码

  1. Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();  
  2. String jsonString = gson.toJson(new Date(System.currentTimeMillis()),Date.class);  
  3. System.out.println(jsonString);  

 

输出结果:

 

"2010-01-07 12:24:34"

 转自:http://joesmart.iteye.com/blog/564633