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()
分享到:
相关推荐
以下是关于Jackson入门的关键知识点: 1. **Streaming API**: - Jackson的Streaming API提供了一种低级、高性能的方式来处理JSON,适合大数据量或内存有限的情况。 - `JsonParser`用于读取JSON数据,而`...
在本快速入门中,我们将探讨JSON-LIB的基本使用方法和核心概念。 1. JSON-LIB安装 首先,你需要将JSON-LIB库引入到你的项目中。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```xml <groupId>...
以上就是“Spring Boot入门例子”中涉及的一些关键知识点,通过这些基本概念的理解和实践,可以快速上手Spring Boot的开发工作。在实际项目中,你可以根据需求添加更多的特性,如WebSocket、定时任务、缓存等,...
《Google Android开发入门与实战》是一本专门为初学者和开发者准备的指南,旨在帮助读者快速掌握Android应用开发的基础知识,并通过实战项目加深理解。这本书涵盖了从Android开发环境的搭建到实际应用开发的全过程,...
这份“安卓入门到精通”的开发文档旨在为初学者提供全面、系统的学习路径,帮助他们从零基础快速掌握安卓应用开发的核心技能。 首先,文档可能会涵盖安卓开发的基础知识,包括Java或Kotlin编程语言的基础,这是安卓...
《Android开发从入门到精通》是由扶松柏编著的一本深入浅出的Android应用程序开发指南,这本书旨在帮助初学者快速掌握Android开发的基础,并逐步提升至高级技能。书中的内容全面且详细,覆盖了Android开发的各个方面...
这些文档通常会涵盖基础概念、语法特性、使用示例、常见问题及解决方案等内容,帮助初学者快速入门并逐步提升技能。例如,`json.pdf`可能包含了JSON的结构介绍、数据类型、编码规则、解析和生成的方法,以及在AJAX和...
这份"Android开发入门与实战体验-ppt"提供了丰富的学习资源,旨在帮助初学者快速掌握Android开发的基础知识,并通过实践提升技能。 1. **Android基础知识** - **环境搭建**:Android Studio是官方推荐的集成开发...
在这个名为"springboot-demo"的项目中,我们将深入探讨SpringBoot的基本概念、核心功能以及如何进行入门实践。 一、SpringBoot概述 SpringBoot是由Pivotal团队提供的全新框架,其设计目标是为了使创建独立的、生产...
这个"Android App开发入门范例程序"集合提供了多个章节的学习材料,旨在帮助新手快速掌握Android应用的基础开发技能。以下是各个章节和FlagAPI部分可能涉及的知识点: 1. **Ch01 - Android基础** - Android系统...
快速入门只需使用BsonFactory创建Jackson的ObjectMapper即可,如下所示:ObjectMapper mapper = new ObjectMapper(new BsonFactory()); 有关更多信息,您可以阅读我的bson4jackson教程或Jackson的完整文档。 可...
**Google Drive 快速入门** 在本文中,我们将深入探讨如何使用Java进行Google Drive的快速入门,以便您可以高效地管理和操作存储在云端的文件。Google Drive API为开发者提供了丰富的功能,包括上传、下载、更新、...
本项目是基于SpringBoot的入门级示例,旨在帮助初学者快速掌握SpringBoot的基本用法以及与其他技术如Mybatis、多线程和定时任务的集成。 首先,我们来探讨**SpringBoot**。SpringBoot是由Pivotal团队提供的全新框架...
5. **最佳实践**:Springside集成了许多优秀的开源库,如SLF4J日志框架、Hibernate ORM、Jackson JSON处理等,遵循最佳实践,帮助开发者编写高质量的代码。 【学习路径】: 1. 首先,你需要阅读《maven-definitive-...
《Android4.X入门应用到精通》是一本专为Android初学者设计的教程,作者孙宏明深入浅出地讲解了Android开发的基础与进阶知识。这本书涵盖了从安装Android开发环境到构建实际应用的全过程,旨在帮助读者从零基础快速...
GSON入门篇 一、创建一个JavaSE项目 二、IDEA中导入gson的jar包 三、创建JavaBean 四、测试类 4.1 一个对象转JSON 4.2 多个对象转JSON 4.3 JSON字符串转一个对象 4.4 JSON字符串转多个对象(List) 4.4.1 错误案例 ...
这个"Android入门经典例子合集"正是为了帮助初学者快速理解和掌握Android应用开发的基础知识而精心整理的资源。以下是一些核心知识点,涵盖从环境搭建到功能实现的全过程: 1. **Android Studio安装与设置**:...