首页 > 代码库 > 【Android开发经验】比Gson解析速度快10倍!——Json解析神器Jackson使用介绍

【Android开发经验】比Gson解析速度快10倍!——Json解析神器Jackson使用介绍

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992

    在前面的两篇文章中,我们介绍了Json数据格式和系统自带Json以及Google的Gson项目,如果能学会这些东西,基本能满足工作需求了。但是,程序员都有追求极致效率的嗜好,在满足了基本需求之后,我们会考虑能不能再优化一下效率呢?当然!今天这篇文章要介绍的,就是在数据量比较大的时候,比Gson的解析效率高近10倍的Json数据解析框架— —Jackson!

    下面是一个大神关于几个常见的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里面。而且这个类可以重复使用,所以一般会创建这个类的一个单例模式,比如下面的代码

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数据生成

    这里所说的简单对象指的是单一对象或者是对象的集合类。

    下面我们先看代码实现,然后讲解一些细节。

    实现的方法有两种,先看第一种,如下:

public String getJsonString(Object object) throws Exception {
	return JacksonMapper.getInstance().writeValueAsString(object);
}
    在这种方法中,我们直接使用ObjectMapper类的writeValueAsString(),就可以把对象的json格式作为返回值直接返回。

    除此之外,我们还可以使用第二种方法,代码如下

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确实是以流的方式对数据进行处理的,这也是它处理速度这么快的原因所在。

    因为第一种方法更加的简洁,所以推荐大家使用。

    下面是测试代码和测试结果

/**
	 * 集合对象
	 * 
	 * @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));
	}

测试结果如下

{"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},{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]


2.复杂对象的Json数据的生成

    这里所说的复杂对象指的是由多种不同数据类型的数据组成的数据,下面我们将介绍如何创建这种复杂对象的Json数据。

    我们在前面介绍过,Json格式分为Object形式和Array形式,我们将分别介绍这两种格式如何生成。

    (1)Object格式

    我们先直接看下面的代码吧!

/**
	 * 生成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()即可。

    下面是测试结果

{"name":"zhaokaiqiang","age":22,"person":{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}}

    (2)Array格式

    下面我们介绍如何生成Array格式的Json数据,其实和上面的差不多。

    下面是代码实现:

/**
	 * 创建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());
	}
    思路是完全一样的,下面是测试的结果:
["zhaokaiqiang",22,{"name":"zhaokaiqiang","birthday":{"day":19,"month":1,"year":1992},"age":22}]

3.解析简单Json对象

    下面开始介绍如何解析Json数据为Java对象。

    我们直接看解析代码

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,就可以完成转换了。

    下面是解析简单的集合对象的代码

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对象

    正在研究,还没想出来。。。






【Android开发经验】比Gson解析速度快10倍!——Json解析神器Jackson使用介绍