Android中解析Json——Jackson使用
2017-01-06 15:06
483 查看
面是一个大神关于几个常见的Json数据的解析速度的测试结果,原文请戳http://wangym.iteye.com/blog/738933
我们从上图可以看出,在大数据量的情况下,Jackson的速度比Gson的解析速度快了不是一点半点,所以,最推荐大家使用的就是Jackson框架,来,咱们一起看看怎么用!
我们先介绍一下常用的几个类的功能:
JsonFactory:这个类是Jackson项目主要的工厂方法,主要用于配置和构建解析器(比如 JsonParser)和生成器(比如 JsonGenerator),这个工厂实例是线程安全的,如果有配置的话,可以重复使用。
JsonGenerator:这个类主要是用来生成Json格式的内容的,我们可以使用JsonFactory的方法生成一个实例。
JsonParser:这个主要是用来读取Json格式的内容,并且完成解析操作的,我们可以使用JsonFactory的方法生成一个实例。
ObjectMapper:这个类提供了Java对象和Json之间的转化,主要通过JsonParser和JsonGenerator实例来完成实际的对Json数据的读写操作。这个类是ObjectCodec的子类,主要的实现细节都在ObjectCodec里面。而且这个类可以重复使用,所以一般会创建这个类的一个单例模式,比如下面的代码
[java]
view plaincopyprint?
package com.example.jsondemo;
import org.codehaus.jackson.map.ObjectMapper;
/**
*
* @ClassName: com.example.jsondemo.JacksonMapper
* @Description:ObjectMapper的单例模式
* @author zhaokaiqiang
* @date 2014-11-27 下午4:06:52
*
*/
public class JacksonMapper {
private static final ObjectMapper mapper = new ObjectMapper();
private JacksonMapper() {
}
public static ObjectMapper getInstance() {
return mapper;
}
}
[java]
view plain
copy
print?
package com.example.jsondemo;
import org.codehaus.jackson.map.ObjectMapper;
/**
*
* @ClassName: com.example.jsondemo.JacksonMapper
* @Description:ObjectMapper的单例模式
* @author zhaokaiqiang
* @date 2014-11-27 下午4:06:52
*
*/
public class JacksonMapper {
private static final ObjectMapper mapper = new ObjectMapper();
private JacksonMapper() {
}
public static ObjectMapper getInstance() {
return mapper;
}
}
我们在下面的代码中,我们经常使用这个单例模式,大家不要迷惑。
下面我们先看代码实现,然后讲解一些细节。<
4000
/p>
实现的方法有两种,先看第一种,如下:
[java]
view plaincopyprint?
<span style="font-size: 18px;">public String getJsonString(Object object) throws Exception {
return JacksonMapper.getInstance().writeValueAsString(object);
}</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">public String getJsonString(Object object) throws Exception {
return JacksonMapper.getInstance().writeValueAsString(object);
}</span>
除此之外,我们还可以使用第二种方法,代码如下
[java]
view plaincopyprint?
public String getJsonString1(Object object) throws Exception {
ObjectMapper mapper = JacksonMapper.getInstance();
StringWriter sw = new StringWriter();
JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
mapper.writeValue(gen, object);
gen.flush();
gen.close();
return sw.toString();
}
[java]
view plain
copy
print?
public String getJsonString1(Object object) throws Exception {
ObjectMapper mapper = JacksonMapper.getInstance();
StringWriter sw = new StringWriter();
JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
mapper.writeValue(gen, object);
gen.flush();
gen.close();
return sw.toString();
}
这里再多说一句,从第二种方法的方式里,我们可以看到操作非常像Java里面的IO流的处理,实际上,Jackson确实是以流的方式对数据进行处理的,这也是它处理速度这么快的原因所在。
因为第一种方法更加的简洁,所以推荐大家使用。
下面是测试代码和测试结果
[java]
view plaincopyprint?
/**
* 集合对象
*
* @throws Exception
*/
public void objectsToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
Log.d(TAG, getJsonString(persons));
}
/**
* 单一对象
*
* @throws Exception
*/
public void objectToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
Log.d(TAG, getJsonString(p));
}
[java]
view plain
copy
print?
/**
* 集合对象
*
* @throws Exception
*/
public void objectsToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
Log.d(TAG, getJsonString(persons));
}
/**
* 单一对象
*
* @throws Exception
*/
public void objectToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
Log.d(TAG, getJsonString(p));
}
测试结果如下
[java]
view plaincopyprint?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}
</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}
</span>
[java]
view plaincopyprint?
<span style="font-size: 18px;">[{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">[{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
我们在前面介绍过,Json格式分为Object形式和Array形式,我们将分别介绍这两种格式如何生成。
(1)Object格式
我们先直接看下面的代码吧!
[java]
view plaincopyprint?
/**
* 生成Object形式的json
*
* @throws Exception
*/
public void createObjectJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 必须通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("name", "zhaokaiqiang");
jsonGenerator.writeNumberField("age", 22);
jsonGenerator.writeObjectField("person", p);
jsonGenerator.writeEndObject();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
[java]
view plain
copy
print?
/**
* 生成Object形式的json
*
* @throws Exception
*/
public void createObjectJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 必须通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("name", "zhaokaiqiang");
jsonGenerator.writeNumberField("age", 22);
jsonGenerator.writeObjectField("person", p);
jsonGenerator.writeEndObject();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
java.lang.IllegalStateException: No ObjectCodec defined for the generator, can only serialize simple wrapper types (type passed com.example.jsondemo.Person)
上面的其余代码很简单,只要根据不同的数据类型,调用对应的write___Field()即可。
下面是测试结果
[java]
view plaincopyprint?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
</span>
(2)Array格式
下面我们介绍如何生成Array格式的Json数据,其实和上面的差不多。
下面是代码实现:
[java]
view plaincopyprint?
/**
* 创建Array形式的json
*
* @throws Exception
*/
public void createArrayJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 只能通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartArray();
jsonGenerator.writeString("zhaokaiqiang");
jsonGenerator.writeNumber(22);
jsonGenerator.writeObject(p);
jsonGenerator.writeEndArray();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
[java]
view plain
copy
print?
/**
* 创建Array形式的json
*
* @throws Exception
*/
public void createArrayJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 只能通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartArray();
jsonGenerator.writeString("zhaokaiqiang");
jsonGenerator.writeNumber(22);
jsonGenerator.writeObject(p);
jsonGenerator.writeEndArray();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
[java]
view plaincopyprint?
<span style="font-size: 18px;">["zhaokaiqiang",22,{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">["zhaokaiqiang",22,{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
我们直接看解析代码
[java]
view plaincopyprint?
public void toObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
String jsonString = getJsonString(p);
Person person = objectMapper.readValue(jsonString, Person.class);
Log.d(TAG, person.toString());
}
[java]
view plain
copy
print?
public void toObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
String jsonString = getJsonString(p);
Person person = objectMapper.readValue(jsonString, Person.class);
Log.d(TAG, person.toString());
}
在解析的时候,我们还是需要用ObjectMapper对象,调用readValue,然后传入需要解析的json数据和转换类型的class,就可以完成转换了。
下面是解析简单的集合对象的代码
[java]
view plaincopyprint?
public void toObjects() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = getJsonString(persons);
@SuppressWarnings("unchecked")
ArrayList<Person> arrayList = objectMapper.readValue(jsonString,
new ArrayList<Person>().getClass());
Log.d(TAG, arrayList.toString());
}
[java]
view plain
copy
print?
public void toObjects() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = getJsonString(persons);
@SuppressWarnings("unchecked")
ArrayList<Person> arrayList = objectMapper.readValue(jsonString,
new ArrayList<Person>().getClass());
Log.d(TAG, arrayList.toString());
}
[java]
view plaincopyprint?
{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
[java]
view plain
copy
print?
{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
[java]
view plaincopyprint?
public void fromJsons() throws Exception {
String jsonString = createObjectJson();
ObjectMapper objectMapper = JacksonMapper.getInstance();
JsonNode jsonNode = objectMapper.readTree(jsonString);
JsonNode nameNode = jsonNode.get("name");
JsonNode ageNode = jsonNode.get("age");
JsonNode persoNode = jsonNode.get("person");
String personString = persoNode.toString();
Person person = objectMapper.readValue(personString, Person.class);
Log.d(TAG, "person=" + person.toString());
Log.d(TAG, "age=" + ageNode.asInt());
Log.d(TAG, "name=" + nameNode.asText());
}
[java]
view plain
copy
print?
public void fromJsons() throws Exception {
String jsonString = createObjectJson();
ObjectMapper objectMapper = JacksonMapper.getInstance();
JsonNode jsonNode = objectMapper.readTree(jsonString);
JsonNode nameNode = jsonNode.get("name");
JsonNode ageNode = jsonNode.get("age");
JsonNode persoNode = jsonNode.get("person");
String personString = persoNode.toString();
Person person = objectMapper.readValue(personString, Person.class);
Log.d(TAG, "person=" + person.toString());
Log.d(TAG, "age=" + ageNode.asInt());
Log.d(TAG, "name=" + nameNode.asText());
}
我们在这里使用了ObjectMapper的readTree方法,返回一个JsonNode对象,我们在这里采用的是树模型的解析方式,类似XML中的DOM。
如果我们想获取基本数据类型的数据,那么我们使用JsonNode.get()根据key获取到包含了value的JsonNode对象之后,根据类型,使用as__()即可将需要获取的数据提取出来。JsonNode代表的是一个节点,是Json的树模型的一个基础类。
但是如果想获取类型是非基础类型的数据的时候,JsonNode并没有提供对应的方法,所以我们只能使用JsonNode的toString方法,获取到Json格式的数据,然后根据我们前面介绍的解析简单对象的方法再次解析即可。但是有一个注意点,就是我们获取key为"person"的数据的时候,不能够使用JsonNode.asText()来获取,因为这并不是一个文本,而是一个Object形式的另外一个Json对象,这样做会获取不到的,所以我用的toString()获取。
当然,这只是我自己探索出来的一个方法,还有其他的方案,比如直接创建这种类型的JavaBean,但是比较麻烦,上面的这种方法更加直观。
(1)Android自带的Json类库,效率低,使用繁琐,不支持反射解析,不推荐使用
(2)google的Gson解析库,这个是我之前一直使用的类库,使用方便,资料比较多,效率对于小量的数据解析来说没有问题,也是很推荐大家使用
(3)jackson是效率最高的解析方案,如果数据量巨大,这个方案绝对是首选。如果数据量比较小,和Gson相比差别不是很大,自己哪个顺手用那个。
除了上面介绍的Jackson,Jackson还有其他更强大的用法,这里就不一一介绍了,用到再说,下面是几个参考网址:
(1)Jackson在线文档:http://tool.oschina.net/apidocs/apidoc?api=jackson-1.9.9
(2)Jackson介绍的官网翻译:http://www.cnblogs.com/lee0oo0/articles/2652528.html
(3)Jackson源码查看:http://www.boyunjian.com/javasrc/org.codehaus.jackson/jackson-core-lgpl/1.9.10/_/
(4)在线Json验证:http://www.bejson.com/
文章中的测试Demo下载地址:https://github.com/ZhaoKaiQiang/JsonDemo
转载于:http://blog.csdn.net/zhaokaiqiang1992/article/details/41511641
我们从上图可以看出,在大数据量的情况下,Jackson的速度比Gson的解析速度快了不是一点半点,所以,最推荐大家使用的就是Jackson框架,来,咱们一起看看怎么用!
我们先介绍一下常用的几个类的功能:
JsonFactory:这个类是Jackson项目主要的工厂方法,主要用于配置和构建解析器(比如 JsonParser)和生成器(比如 JsonGenerator),这个工厂实例是线程安全的,如果有配置的话,可以重复使用。
JsonGenerator:这个类主要是用来生成Json格式的内容的,我们可以使用JsonFactory的方法生成一个实例。
JsonParser:这个主要是用来读取Json格式的内容,并且完成解析操作的,我们可以使用JsonFactory的方法生成一个实例。
ObjectMapper:这个类提供了Java对象和Json之间的转化,主要通过JsonParser和JsonGenerator实例来完成实际的对Json数据的读写操作。这个类是ObjectCodec的子类,主要的实现细节都在ObjectCodec里面。而且这个类可以重复使用,所以一般会创建这个类的一个单例模式,比如下面的代码
[java]
view plaincopyprint?
package com.example.jsondemo;
import org.codehaus.jackson.map.ObjectMapper;
/**
*
* @ClassName: com.example.jsondemo.JacksonMapper
* @Description:ObjectMapper的单例模式
* @author zhaokaiqiang
* @date 2014-11-27 下午4:06:52
*
*/
public class JacksonMapper {
private static final ObjectMapper mapper = new ObjectMapper();
private JacksonMapper() {
}
public static ObjectMapper getInstance() {
return mapper;
}
}
[java]
view plain
copy
print?
package com.example.jsondemo;
import org.codehaus.jackson.map.ObjectMapper;
/**
*
* @ClassName: com.example.jsondemo.JacksonMapper
* @Description:ObjectMapper的单例模式
* @author zhaokaiqiang
* @date 2014-11-27 下午4:06:52
*
*/
public class JacksonMapper {
private static final ObjectMapper mapper = new ObjectMapper();
private JacksonMapper() {
}
public static ObjectMapper getInstance() {
return mapper;
}
}
package com.example.jsondemo; import org.codehaus.jackson.map.ObjectMapper; /** * * @ClassName: com.example.jsondemo.JacksonMapper * @Description:ObjectMapper的单例模式 * @author zhaokaiqiang * @date 2014-11-27 下午4:06:52 * */ public class JacksonMapper { private static final ObjectMapper mapper = new ObjectMapper(); private JacksonMapper() { } public static ObjectMapper getInstance() { return mapper; } }
我们在下面的代码中,我们经常使用这个单例模式,大家不要迷惑。
1.简单对象的Json数据生成
这里所说的简单对象指的是单一对象或者是对象的集合类。下面我们先看代码实现,然后讲解一些细节。<
4000
/p>
实现的方法有两种,先看第一种,如下:
[java]
view plaincopyprint?
<span style="font-size: 18px;">public String getJsonString(Object object) throws Exception {
return JacksonMapper.getInstance().writeValueAsString(object);
}</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">public String getJsonString(Object object) throws Exception {
return JacksonMapper.getInstance().writeValueAsString(object);
}</span>
<span style="font-size: 18px;">public String getJsonString(Object object) throws Exception { return JacksonMapper.getInstance().writeValueAsString(object); }</span>在这种方法中,我们直接使用ObjectMapper类的writeValueAsString(),就可以把对象的json格式作为返回值直接返回。
除此之外,我们还可以使用第二种方法,代码如下
[java]
view plaincopyprint?
public String getJsonString1(Object object) throws Exception {
ObjectMapper mapper = JacksonMapper.getInstance();
StringWriter sw = new StringWriter();
JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
mapper.writeValue(gen, object);
gen.flush();
gen.close();
return sw.toString();
}
[java]
view plain
copy
print?
public String getJsonString1(Object object) throws Exception {
ObjectMapper mapper = JacksonMapper.getInstance();
StringWriter sw = new StringWriter();
JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
mapper.writeValue(gen, object);
gen.flush();
gen.close();
return sw.toString();
}
public String getJsonString1(Object object) throws Exception { ObjectMapper mapper = JacksonMapper.getInstance(); StringWriter sw = new StringWriter(); JsonGenerator gen = new JsonFactory().createJsonGenerator(sw); mapper.writeValue(gen, object); gen.flush(); gen.close(); return sw.toString(); }这种方法是使用JsonGenerator和StringWriter对象,通过ObjectMapper,把转换好的Json数据写到了StringWriter里面,然后toString()就可以拿到我们需要的Json数据了。
这里再多说一句,从第二种方法的方式里,我们可以看到操作非常像Java里面的IO流的处理,实际上,Jackson确实是以流的方式对数据进行处理的,这也是它处理速度这么快的原因所在。
因为第一种方法更加的简洁,所以推荐大家使用。
下面是测试代码和测试结果
[java]
view plaincopyprint?
/**
* 集合对象
*
* @throws Exception
*/
public void objectsToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
Log.d(TAG, getJsonString(persons));
}
/**
* 单一对象
*
* @throws Exception
*/
public void objectToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
Log.d(TAG, getJsonString(p));
}
[java]
view plain
copy
print?
/**
* 集合对象
*
* @throws Exception
*/
public void objectsToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
Log.d(TAG, getJsonString(persons));
}
/**
* 单一对象
*
* @throws Exception
*/
public void objectToJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
Log.d(TAG, getJsonString(p));
}
/** * 集合对象 * * @throws Exception */ public void objectsToJson() throws Exception { Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19)); ArrayList<Person> persons = new ArrayList<Person>(); persons.add(p); persons.add(p); persons.add(p); Log.d(TAG, getJsonString(persons)); } /** * 单一对象 * * @throws Exception */ public void objectToJson() throws Exception { Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19)); Log.d(TAG, getJsonString(p)); }
测试结果如下
[java]
view plaincopyprint?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}
</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}
</span>
<span style="font-size: 18px;">{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22} </span>
[java]
view plaincopyprint?
<span style="font-size: 18px;">[{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">[{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
<span style="font-size: 18px;">[{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
2.复杂对象的Json数据的生成
这里所说的复杂对象指的是由多种不同数据类型的数据组成的数据,下面我们将介绍如何创建这种复杂对象的Json数据。我们在前面介绍过,Json格式分为Object形式和Array形式,我们将分别介绍这两种格式如何生成。
(1)Object格式
我们先直接看下面的代码吧!
[java]
view plaincopyprint?
/**
* 生成Object形式的json
*
* @throws Exception
*/
public void createObjectJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 必须通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("name", "zhaokaiqiang");
jsonGenerator.writeNumberField("age", 22);
jsonGenerator.writeObjectField("person", p);
jsonGenerator.writeEndObject();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
[java]
view plain
copy
print?
/**
* 生成Object形式的json
*
* @throws Exception
*/
public void createObjectJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 必须通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("name", "zhaokaiqiang");
jsonGenerator.writeNumberField("age", 22);
jsonGenerator.writeObjectField("person", p);
jsonGenerator.writeEndObject();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
/** * 生成Object形式的json * * @throws Exception */ public void createObjectJson() throws Exception { Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19)); StringWriter stringWriter = new StringWriter(); // 必须通过这种方式获取 JsonGenerator jsonGenerator = JacksonMapper.getInstance() .getJsonFactory().createJsonGenerator(stringWriter); jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("name", "zhaokaiqiang"); jsonGenerator.writeNumberField("age", 22); jsonGenerator.writeObjectField("person", p); jsonGenerator.writeEndObject(); jsonGenerator.flush(); jsonGenerator.close(); Log.d(TAG, stringWriter.toString()); }JsonGenerator是一个生成器,如果我们想创建复杂的Json对象,我们就可以是用这个类来完成。但是有一点必须要注意,就是获取JsonGenerator的方式,我们必须使用ObjectMapper的getJsonFactory(),然后创建一个JsonGenerator,否则如果我们使用writeObjectField()方法的时候,会报下面的异常
java.lang.IllegalStateException: No ObjectCodec defined for the generator, can only serialize simple wrapper types (type passed com.example.jsondemo.Person)
上面的其余代码很简单,只要根据不同的数据类型,调用对应的write___Field()即可。
下面是测试结果
[java]
view plaincopyprint?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
</span>
<span style="font-size: 18px;">{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}} </span>
(2)Array格式
下面我们介绍如何生成Array格式的Json数据,其实和上面的差不多。
下面是代码实现:
[java]
view plaincopyprint?
/**
* 创建Array形式的json
*
* @throws Exception
*/
public void createArrayJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 只能通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartArray();
jsonGenerator.writeString("zhaokaiqiang");
jsonGenerator.writeNumber(22);
jsonGenerator.writeObject(p);
jsonGenerator.writeEndArray();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
[java]
view plain
copy
print?
/**
* 创建Array形式的json
*
* @throws Exception
*/
public void createArrayJson() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
StringWriter stringWriter = new StringWriter();
// 只能通过这种方式获取
JsonGenerator jsonGenerator = JacksonMapper.getInstance()
.getJsonFactory().createJsonGenerator(stringWriter);
jsonGenerator.writeStartArray();
jsonGenerator.writeString("zhaokaiqiang");
jsonGenerator.writeNumber(22);
jsonGenerator.writeObject(p);
jsonGenerator.writeEndArray();
jsonGenerator.flush();
jsonGenerator.close();
Log.d(TAG, stringWriter.toString());
}
/** * 创建Array形式的json * * @throws Exception */ public void createArrayJson() throws Exception { Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19)); StringWriter stringWriter = new StringWriter(); // 只能通过这种方式获取 JsonGenerator jsonGenerator = JacksonMapper.getInstance() .getJsonFactory().createJsonGenerator(stringWriter); jsonGenerator.writeStartArray(); jsonGenerator.writeString("zhaokaiqiang"); jsonGenerator.writeNumber(22); jsonGenerator.writeObject(p); jsonGenerator.writeEndArray(); jsonGenerator.flush(); jsonGenerator.close(); Log.d(TAG, stringWriter.toString()); }思路是完全一样的,下面是测试的结果:
[java]
view plaincopyprint?
<span style="font-size: 18px;">["zhaokaiqiang",22,{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
[java]
view plain
copy
print?
<span style="font-size: 18px;">["zhaokaiqiang",22,{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
<span style="font-size: 18px;">["zhaokaiqiang",22,{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]</span>
3.解析简单Json对象
下面开始介绍如何解析Json数据为Java对象。我们直接看解析代码
[java]
view plaincopyprint?
public void toObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
String jsonString = getJsonString(p);
Person person = objectMapper.readValue(jsonString, Person.class);
Log.d(TAG, person.toString());
}
[java]
view plain
copy
print?
public void toObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
String jsonString = getJsonString(p);
Person person = objectMapper.readValue(jsonString, Person.class);
Log.d(TAG, person.toString());
}
public void toObject() throws Exception { ObjectMapper objectMapper = new ObjectMapper(); Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19)); String jsonString = getJsonString(p); Person person = objectMapper.readValue(jsonString, Person.class); Log.d(TAG, person.toString()); }
在解析的时候,我们还是需要用ObjectMapper对象,调用readValue,然后传入需要解析的json数据和转换类型的class,就可以完成转换了。
下面是解析简单的集合对象的代码
[java]
view plaincopyprint?
public void toObjects() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = getJsonString(persons);
@SuppressWarnings("unchecked")
ArrayList<Person> arrayList = objectMapper.readValue(jsonString,
new ArrayList<Person>().getClass());
Log.d(TAG, arrayList.toString());
}
[java]
view plain
copy
print?
public void toObjects() throws Exception {
Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19));
ArrayList<Person> persons = new ArrayList<Person>();
persons.add(p);
persons.add(p);
persons.add(p);
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = getJsonString(persons);
@SuppressWarnings("unchecked")
ArrayList<Person> arrayList = objectMapper.readValue(jsonString,
new ArrayList<Person>().getClass());
Log.d(TAG, arrayList.toString());
}
public void toObjects() throws Exception { Person p = new Person("zhaokaiqiang", 22, new Birthday(1992, 1, 19)); ArrayList<Person> persons = new ArrayList<Person>(); persons.add(p); persons.add(p); persons.add(p); ObjectMapper objectMapper = new ObjectMapper(); String jsonString = getJsonString(persons); @SuppressWarnings("unchecked") ArrayList<Person> arrayList = objectMapper.readValue(jsonString, new ArrayList<Person>().getClass()); Log.d(TAG, arrayList.toString()); }
4.解析复杂的Json对象
这里所说的复杂对象,与上面的生成的复杂Json对象是一个意思,指不是由简单的基本类型或者是单一对象集合的Json对象。我们要进行解析测试的文本,是下面的这种形式[java]
view plaincopyprint?
{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
[java]
view plain
copy
print?
{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}
{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}这个字符串中有字符串类型、int类型、一个拥有对象属性的一个自定义的对象,所以使用上面的进行类型反射的做法是完不成解析操作的,因为这个对象比较复杂,所以经过研究,我决定采用分段的方式进行解析,也就是对于这种Object类型的Json数据,分别根据key取出value,然后单独对里面的自定义对象进行解析,下面我们看代码实现:
[java]
view plaincopyprint?
public void fromJsons() throws Exception {
String jsonString = createObjectJson();
ObjectMapper objectMapper = JacksonMapper.getInstance();
JsonNode jsonNode = objectMapper.readTree(jsonString);
JsonNode nameNode = jsonNode.get("name");
JsonNode ageNode = jsonNode.get("age");
JsonNode persoNode = jsonNode.get("person");
String personString = persoNode.toString();
Person person = objectMapper.readValue(personString, Person.class);
Log.d(TAG, "person=" + person.toString());
Log.d(TAG, "age=" + ageNode.asInt());
Log.d(TAG, "name=" + nameNode.asText());
}
[java]
view plain
copy
print?
public void fromJsons() throws Exception {
String jsonString = createObjectJson();
ObjectMapper objectMapper = JacksonMapper.getInstance();
JsonNode jsonNode = objectMapper.readTree(jsonString);
JsonNode nameNode = jsonNode.get("name");
JsonNode ageNode = jsonNode.get("age");
JsonNode persoNode = jsonNode.get("person");
String personString = persoNode.toString();
Person person = objectMapper.readValue(personString, Person.class);
Log.d(TAG, "person=" + person.toString());
Log.d(TAG, "age=" + ageNode.asInt());
Log.d(TAG, "name=" + nameNode.asText());
}
public void fromJsons() throws Exception { String jsonString = createObjectJson(); ObjectMapper objectMapper = JacksonMapper.getInstance(); JsonNode jsonNode = objectMapper.readTree(jsonString); JsonNode nameNode = jsonNode.get("name"); JsonNode ageNode = jsonNode.get("age"); JsonNode persoNode = jsonNode.get("person"); String personString = persoNode.toString(); Person person = objectMapper.readValue(personString, Person.class); Log.d(TAG, "person=" + person.toString()); Log.d(TAG, "age=" + ageNode.asInt()); Log.d(TAG, "name=" + nameNode.asText()); }
我们在这里使用了ObjectMapper的readTree方法,返回一个JsonNode对象,我们在这里采用的是树模型的解析方式,类似XML中的DOM。
如果我们想获取基本数据类型的数据,那么我们使用JsonNode.get()根据key获取到包含了value的JsonNode对象之后,根据类型,使用as__()即可将需要获取的数据提取出来。JsonNode代表的是一个节点,是Json的树模型的一个基础类。
但是如果想获取类型是非基础类型的数据的时候,JsonNode并没有提供对应的方法,所以我们只能使用JsonNode的toString方法,获取到Json格式的数据,然后根据我们前面介绍的解析简单对象的方法再次解析即可。但是有一个注意点,就是我们获取key为"person"的数据的时候,不能够使用JsonNode.asText()来获取,因为这并不是一个文本,而是一个Object形式的另外一个Json对象,这样做会获取不到的,所以我用的toString()获取。
当然,这只是我自己探索出来的一个方法,还有其他的方案,比如直接创建这种类型的JavaBean,但是比较麻烦,上面的这种方法更加直观。
5.总结
到现在为止,Android平台下主流的三种Json解析方式已经介绍完毕,我们来总结一下:(1)Android自带的Json类库,效率低,使用繁琐,不支持反射解析,不推荐使用
(2)google的Gson解析库,这个是我之前一直使用的类库,使用方便,资料比较多,效率对于小量的数据解析来说没有问题,也是很推荐大家使用
(3)jackson是效率最高的解析方案,如果数据量巨大,这个方案绝对是首选。如果数据量比较小,和Gson相比差别不是很大,自己哪个顺手用那个。
除了上面介绍的Jackson,Jackson还有其他更强大的用法,这里就不一一介绍了,用到再说,下面是几个参考网址:
(1)Jackson在线文档:http://tool.oschina.net/apidocs/apidoc?api=jackson-1.9.9
(2)Jackson介绍的官网翻译:http://www.cnblogs.com/lee0oo0/articles/2652528.html
(3)Jackson源码查看:http://www.boyunjian.com/javasrc/org.codehaus.jackson/jackson-core-lgpl/1.9.10/_/
(4)在线Json验证:http://www.bejson.com/
文章中的测试Demo下载地址:https://github.com/ZhaoKaiQiang/JsonDemo
转载于:http://blog.csdn.net/zhaokaiqiang1992/article/details/41511641
相关文章推荐
- Android-json解析(二):Jackson的使用
- Android中Json数据解析(二)--使用Gson、Jackson和FastJson解析Json数据
- Android中解析Json——Jackson使用
- Android Json 使用Jackson解析和生成json .
- android:json解析的两个工具:Gson和Jackson的使用小例子
- Android中Json数据解析(二)--使用Gson、Jackson和FastJson解析Json数据
- Android中解析Json——Jackson使用
- Android 中Json解析的几种框架(Gson、Jackson、FastJson、LoganSquare)使用与对比
- Android 中Json解析的几种框架(Gson、Jackson、FastJson、LoganSquare)使用与对比
- android:json解析的两个工具:Gson和Jackson的使用小例子
- Android Json的使用(2) 使用Jackson解析和生成json
- Android Json的使用(2) 使用Jackson解析和生成json
- android:json解析的两个工具:Gson和Jackson的使用小例子
- 【Android开发经验】比Gson解析速度快10倍!——Json解析神器Jackson使用介绍
- android:json解析的两个工具:Gson和Jackson的使用小例子
- android中json解析的两个工具:Gson和Jackson的使用小demo
- 在 Android 应用程序中使用 Internet 数据 解析 XML、JSON 和 protocol buffers 数据
- Android下使用Gson解析JSON数据
- Android的数据处理:使用annotation实现JSON字符串解析为java对象
- Android中使用Gson解析JSON数据