`
learnworld
  • 浏览: 168339 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论
阅读更多

1. 背景
目前维护的产品使用jackson处理json,现整理一下jackson相关资料,希望对初次接触jackson的新手有所帮助。
    jackson主页: http://jackson.codehaus.org/
    jackson document: http://wiki.fasterxml.com/JacksonJavaDocs
    JacksonInFiveMinutes: http://wiki.fasterxml.com/JacksonInFiveMinutes
    本文主要内容译自JacksonInFiveMinutes,增加了部分示例,转载请注明出处。
受java平台上各种处理xml的类库(StAX, JAXB等)启发,Jackson提供一种处理json的java类库。Jackson的目标是为开发者提供快速、准确、轻量级和用起来最爽的json处理类库。本文将概括介绍Jackson的主要功能和相关功能的使用示例。

 

2.  使用方式
Jackson提供三种可选的json处理方式:
1) Streaming API
又称Incremental parsing/generation, 受StAX API启发,以非关联递增方式读写json内容。 通过 org.codehaus.jackson.JsonParser读取,通过org.codehaus.jackson.JsonGenerator写入。

2) Tree Model

通过基于内存的树形结构来描述json数据,和 XML DOM类似。通过org.codehaus.jackson.map.ObjectMapper构建树,树由JsonNode节点组成 

3) Data Binding 

基于属性访问或注解的方式将json和POJO对象互相转换, 受JAXB基于注解的处理方式启发。通过org.codehaus.jackson.map.ObjectMapper读写json数据。它包含两种类型:

3.1 Simple Data Binding

用于json和Java Maps, Lists, Strings, Numbers, Booleans and nulls的相互转换。

3.2 Full Data Binding

用于json和Java Bean的相互转换。

 

下面从使用的角度上比较三种处理方式:

Streaming API 执行效率最高,读写速度最快,另外两种方式都基于它实现;

Tree Model 是最灵活的;

Data Binding 通常是最方便使用的;


3.  示例

快速上手最好的方式就是看示例,下面的例子演示了上面三种方式的用法,建议通过附件下载完整的示例工程文件。

 

package com.learnworld.jackson.main;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.type.TypeReference;

import com.learnworld.jackson.annotation.Account;
import com.learnworld.jackson.pojo.Name;
import com.learnworld.jackson.pojo.User;
import com.learnworld.jackson.pojo.User.Gender;

public class JacksonMain {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		ObjectMapper mapper = new ObjectMapper();
		
		// 1.1 Simple Data Binding
		simpleDataBinding(mapper);
		
		// 1.2 Full Data Binding
		fullDataBinding(mapper);
		
		// 1.3 Data Binding with Generics
		dataBindingWithGenerics(mapper);
		
		// 1.4 Data Binding with Annotation
		dataBindingWithAnnotation(mapper);
		
		// 2.1 Tree Model
		treeModel(mapper);
		
		// 2.2 Construct a Tree
		constructTreeModel(mapper);
		
		// 3.1 Streaming API (write Json)
		streamingAPIWrite();
		
		// 3.2 Streaming API (read Json)
		streamingAPIRead();
	}

	@SuppressWarnings("unchecked")
	public static void simpleDataBinding(ObjectMapper mapper) throws Exception {
		// json -> Map
		Map<String, Object> userDataRead = mapper.readValue(new File("user.json"),
				Map.class);
		System.out.println("simpleDataBinding(): " + userDataRead);
	
		// Map -> json
		Map<String,Object> userData = new HashMap<String,Object>();
		Map<String,String> nameStruct = new HashMap<String,String>();
		nameStruct.put("first", "Joe");
		nameStruct.put("last", "Sixpack");
		userData.put("name", nameStruct);
		userData.put("gender", "MALE");
		userData.put("verified", Boolean.FALSE);
		userData.put("userImage", "Rm9vYmFyIQ==");
		mapper.writeValue(new File("user-modified.json"), userData);
	}

	public static void fullDataBinding(ObjectMapper mapper) throws Exception {
		// json -> Object
		User user = mapper.readValue(new File("user.json"), User.class);
		System.out.println("fullDataBinding(): " + user);

		// Object -> json
		mapper.writeValue(new File("user-modified.json"), user);
	}
	
	public static void dataBindingWithGenerics(ObjectMapper mapper) throws Exception {
		// json -> Map
		Map<String, Name> genericData = mapper.readValue(new File("generic.json"),
				new TypeReference<Map<String,Name>>() { });
		System.out.println("dataBindingWithGenerics():" + genericData);
	}
	
	public static void dataBindingWithAnnotation(ObjectMapper mapper) throws Exception {
		// json -> Object
		Account account = mapper.readValue(new File("account.json"), Account.class);
		System.out.println("dataBindingWithAnnotation(): " + account);

		account.setGmtCreate(new Date());
		// Object -> json
		mapper.writeValue(new File("account.json"), account);
	}
	
	public static void treeModel(ObjectMapper mapper) throws Exception {
		// can either use mapper.readTree(JsonParser), or bind to JsonNode
		JsonNode rootNode = mapper.readValue(new File("user.json"), JsonNode.class);
		
		// ensure that "last name" isn't "Xmler"; if is, change to "Jsoner"
		JsonNode nameNode = rootNode.path("name");
		String lastName = nameNode.path("last").getTextValue();
		if ("xmler".equalsIgnoreCase(lastName)) {
		  ((ObjectNode)nameNode).put("last", "Jsoner");
		}
		// write it out
		mapper.writeValue(new File("user-modified.json"), rootNode);
	}
	
	public static void constructTreeModel(ObjectMapper mapper) throws Exception {
		ObjectMapper objectMapper = new ObjectMapper();
		ObjectNode userOb = objectMapper.createObjectNode();
		ObjectNode nameOb = userOb.putObject("name");
		nameOb.put("first", "Thomas");
		nameOb.put("last", "Zhou");
		userOb.put("gender", User.Gender.MALE.toString());
		userOb.put("verified", false);
		userOb.put("userImage", "Foobar!".getBytes());
		// write it out
		mapper.writeValue(new File("user-modified.json"), userOb);
	}
	
	public static void streamingAPIRead() throws Exception {
		JsonFactory f = new JsonFactory();
		JsonGenerator g = f.createJsonGenerator(new File("user.json"), JsonEncoding.UTF8);

		g.writeStartObject();
		g.writeObjectFieldStart("name");
		g.writeStringField("first", "Thomas");
		g.writeStringField("last", "Zhou");
		g.writeEndObject(); // for field 'name'
		g.writeStringField("gender", Gender.MALE.name());
		g.writeBooleanField("verified", false);
		g.writeFieldName("userImage"); // no 'writeBinaryField' (yet?)
		byte[] binaryData = "Foobar!".getBytes();
		g.writeBinary(binaryData);
		g.writeEndObject();
		g.close(); // important: will force flushing of output, close underlying output stream
	}
	
	public static void streamingAPIWrite() throws Exception {
		JsonFactory f = new JsonFactory();
		JsonParser jp = f.createJsonParser(new File("user.json"));
		User user = new User();
		jp.nextToken(); // will return JsonToken.START_OBJECT (verify?)
		while (jp.nextToken() != JsonToken.END_OBJECT) {
		  String fieldname = jp.getCurrentName();
		  jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY
		  if ("name".equals(fieldname)) { // contains an object
		    Name name = new Name();
		    while (jp.nextToken() != JsonToken.END_OBJECT) {
		      String namefield = jp.getCurrentName();
		      jp.nextToken(); // move to value
		      if ("first".equals(namefield)) {
		        name.setFirst(jp.getText());
		      } else if ("last".equals(namefield)) {
		        name.setLast(jp.getText());
		      } else {
		        throw new IllegalStateException("Unrecognized field '"+fieldname+"'!");
		      }
		    }
		    user.setName(name);
		  } else if ("gender".equals(fieldname)) {
		    user.setGender(User.Gender.valueOf(jp.getText()));
		  } else if ("verified".equals(fieldname)) {
		    user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE);
		  } else if ("userImage".equals(fieldname)) {
		    user.setUserImage(jp.getBinaryValue());
		  } else {
		    throw new IllegalStateException("Unrecognized field '"+fieldname+"'!");
		  }
		}
		jp.close(); // ensure resources get cleaned up timely and properly
		System.out.println("streamingAPIWrite(): " + user);
	}
}

4.  其他

除了使用上文中演示的ObjectMapper方式使用data binding和tree model以下方法也可以满足你的需求:

  • JsonParser.readValueAs()

  • JsonParser.readValueAsTree()

  • JsonGenerator.writeObject()

  • JsonGenerator.writeTree()


 

分享到:
评论
1 楼 qq27716588 2014-07-28  
  

相关推荐

    用于Jackson JSON处理器的可插拔BSON生成器和解析器。-Android开发

    快速入门只需使用BsonFactory创建Jackson的ObjectMapper即可,如下所示:ObjectMapper mapper = new ObjectMapper(new BsonFactory()); 有关更多信息,您可以阅读我的bson4jackson教程或Jackson的完整文档。 可...

    GSON入门篇(教学视频+源代码)

    GSON入门篇 一、创建一个JavaSE项目 二、IDEA中导入gson的jar包 三、创建JavaBean 四、测试类 4.1 一个对象转JSON 4.2 多个对象转JSON 4.3 JSON字符串转一个对象 4.4 JSON字符串转多个对象(List) 4.4.1 错误案例 ...

    websocket-starter:Websocket入门项目

    快速预览 该项目包含一个简单的应用程序,该应用程序: 在/ws接受websocket连接 发回客户发送的任何消息 向/ws所有连接的客户端广播消息 : public class App extends Jooby { { // https for wss securePort...

    livereload-starter:LiveReload的入门项目

    直播用于协议的入门工具包。快速预览该项目包含一个简单的静态应用程序。 : public class App extends Jooby { { /* * Install Jackson: */ use( new Jackson ()); /* * Install LiveReload: */ use( new Live...

    requery-starter:重新查询的入门项目

    用于入门工具包。 快速预览 该项目包含一个简单的应用程序,该应用程序: 使用内存数据库 插入有关应用程序启动时间的数据库记录 通过JSON路由公开数据。 : public class App extends Jooby { /* * The logging...

    spring4学习完整demo

    开发工具IntelliJ IDEA15,maven构建工程,使用spring4.1.1,demo集成jackson传输json,hibernate-validator校验数据,mybatis数据库持久框架,拦截器interceptor,aop构建事务等,让你快速入门spring

    json 入门教程

    JSON 即 JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互。本文将快速讲解 JSON 格式,并通过代码示例演示如何分别在客户端和服务器端进行 JSON 格式数据的处理

    mango:高性能,开源Java RPC框架

    芒果 ...快速入门的最低要求是: JDK 1.7或更高 基于Java的项目管理软件,例如或 快速开始 1.同步通话 将依赖项添加到pom。 &lt;groupId&gt;com.mindflow&lt;/groupId&gt; &lt;artifactId&gt;mango-core &lt;vers

    hello-starter:JSON状态器项目

    快速预览该项目包含一个简单的应用程序,该应用程序: 接受可选的name HTTP参数创建一个POJO并将响应作为JSON发送回 : public class App extends Jooby { { /* * Render JSON: */ use( new Jackson ()); /** * Say ...

    应用级产品开发平台APDPlat.zip

    APDPlat快速体验 APDPlat入门指南 APDPlat专题文章 APDPlat是Application Product Development Platform(应用级产品开发平台)的缩写。 APDPlat提供了应用容器、多模块架构、代码生成、安装程序、认证...

    ebean-starter:启动Ebean ORM项目

    豆类入门项目。快速预览该项目包含一个简单的应用程序,该应用程序: 使用内存数据库在应用程序启动时间插入一些数据库记录通过JSON路由公开数据。 : public class App extends Jooby { { use( new Jackson ()); /*...

    apitool-starter:将您的API导出到Swagger和RAML

    模块的入门项目。 屏幕截图 昂首阔步 拉姆 快速预览 该项目包含一个简单的应用程序,该应用程序: 使用脚本路由定义Pet API 将API导出到和 { use( new Jackson ()); /** * * Everything about your Pets. */...

    全新原生Java影视源码-test-your-trivia:一种基于Kotlin并由Quarkus框架提供支持的新型琐事Alexa游戏

    update脚本快速部署到 AWS 预先打包的 REST 客户端支持开箱即用地构建类似改造的 API。 用于 lambda 的 AWS sdk 已包含在 Quarkus 包中。 主启动处理程序的 Quarkus 单元测试 可用作使用 Kotlin 和 Gradle 工具链的...

    flask_v1.2 1.zip

    本资源是关于Flask框架常用知识的干货提炼,可以帮助快速了解Flask基础知识。如有深究的可以查阅Flask官方文档https://flask.palletsprojects.com/en/1.1.x

    Spring Boot中文文档.rar

    入门 8.介绍Spring Boot 9.系统要求 9.1.Servlet容器 10.安装Spring Boot 10.1.Java Developer的安装说明 10.1.1.Maven安装 10.1.2.Gradle安装 10.2.安装Spring Boot CLI 10.2.1....

    java开源包1

    AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器...

    java开源包11

    AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器...

    java开源包2

    AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器...

    java开源包3

    AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器...

Global site tag (gtag.js) - Google Analytics