Json已经成为当前服务器与 WEB 应用之间数据传输的公认标准。Java 中常见的 Json 类库有 Gson、JSON-lib 和 Jackson 等。相比于其他的解析工具,Jackson 简单易用,不依赖于外部jar 包,而且更新速度比较快。其也是 SpringMVC 框架 json 格式化输出的默认实现。

Jackson fasterxml 和 codehaus 的区别

他们是 Jackson 的两大分支。从 2.0 版本开始,Jackson 开始改用新的包名 com.fasterxml.jackson;其源代码也托管到了 Github(FasterXML/Jackson)。1.x 版本现在只提供 bug-fix 。另外版本 1 和版本 2 的 artifactId 也不相同。 在使用的过程中需要注意!

Jackson fasterxml 的结构

Jackson 主要有三部分组成,除了三个模块之间存在依赖,不依赖任何外部 jar 包。三个模块的 作用及 artifactId 如下:

  • jackson-core: 核心包
  • jackson-annotations : 注解包
  • jackson-databind : 数据绑定(依赖 coreannotations

使用方式

Jackson 提供了三种 json 处理方式:

  • Streaming API : 其他两种方式都依赖于它而实现,如果要从底层细粒度控制 json 的解析生成,可以使用这种方式;
  • Tree Model : 通过基于内存的树形结构来描述 json 数据。json 结构树由 JsonNode 组成。不需要绑定任何类和实体,可以方便的对 JsonNode 来进行操作。
  • Data Binding : 最常用的方式,基于属性的 get 和 set方法以及注解来实现 JavaBean 和 json 的互转,底层实现还是 Streaming API.

代码示例

Streaming API示例

package com.maolv.oschina;

import java.util.ArrayList;
import java.util.List; import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; /**
* Jackson 流处理APi处理
*/
public class JacksonStreamAPITest { private JsonFactory factory;
private JsonGenerator jsonGenerator; @Before
public void init() throws Exception {
factory = new JsonFactory();
// 工厂全局设置
factory.disable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES);
// 设置解析器
factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
// 设置生成器
factory.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
// 设置输出到console
jsonGenerator = factory.createGenerator(System.out);
// 覆盖上面的设置
jsonGenerator.disable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
} @Test
public void testGenerator() throws Exception {
String str = "hello,world!jackson!";
// 输出字节
jsonGenerator.writeBinary(str.getBytes());
// 输出布尔型
jsonGenerator.writeBoolean(true);
// null
jsonGenerator.writeNull();
// 输出字符型
jsonGenerator.writeNumber(2.2f);
// 使用Raw方法会执行字符中的特殊字符
jsonGenerator.writeRaw("\tc");
// 输出换行符
jsonGenerator.writeRaw("\r\n"); // 构造Json数据
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("message", "Hello World!");
jsonGenerator.writeArrayFieldStart("names");
jsonGenerator.writeString("周杰伦");
jsonGenerator.writeString("王力宏");
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();
} @Test
public void testParser() throws Exception {
String testStr = "{\"message\":\"Hello World!\",\"names\":[\"周杰伦\",\"王力宏\"]}";
JsonParser p = factory.createParser(testStr); JsonToken t = p.nextToken();
List<String> names = new ArrayList<String>();
if ( t != JsonToken.START_OBJECT){
System.out.println("Json格式不正确!");
}
while (t != JsonToken.END_OBJECT){
if (t == JsonToken.FIELD_NAME && "message".equals(p.getCurrentName())){
t = p.nextToken();
String message = p.getText();
System.out.printf("My message to you is %s!\n", message);
}
if (t == JsonToken.FIELD_NAME && "names".equals(p.getCurrentName())){
t = p.nextToken();
while (t != JsonToken.END_ARRAY){
if (t == JsonToken.VALUE_STRING){
String name = p.getValueAsString();
names.add(name);
}
t = p.nextToken();
}
}
t = p.nextToken();
}
System.out.println(names.toString());
p.close();
} @After
public void close() throws Exception {
jsonGenerator.close();
}
}

运行结果:

"aGVsbG8sd29ybGQhamFja3NvbiE=" true null 2.2	c
{"message":"Hello World!","names":["周杰伦","王力宏"]}

Tree Model示例

package com.maolv.oschina;

import org.junit.Before;
import org.junit.Test; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode; /**
* Jackson Tree Model解析生成示例
*/
public class JacksonTreeModelTest { private ObjectMapper objectMapper; @Before
public void init() {
objectMapper = new ObjectMapper();
// 如果为空则不输出
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
// 对于空的对象转json的时候不抛出错误
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 禁用序列化日期为timestamps
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 禁用遇到未知属性抛出异常
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 视空字符传为null
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); // 低层级配置
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
// 允许属性名称没有引号
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// 允许单引号
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// 取消对非ASCII字符的转码
objectMapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, false); } @Test
public void testTreeModel() throws Exception {
JsonNodeFactory nodeFactory = objectMapper.getNodeFactory();
// 创建一个model
ObjectNode node = nodeFactory.objectNode();
node.put("age", 18);
// 新增
node.put("name", "周杰伦");
// 如果存在同名的则是替换操作
node.put("age", 19);
ArrayNode coursesNode = node.putArray("courses");
coursesNode.add("思想政治");
coursesNode.add("高等数学");
// 获取节点类型
System.out.println(node.getNodeType());
System.out.println(coursesNode.getNodeType());
// 移除第一个
coursesNode.remove(0);
// 输出
System.out.println(node.toString());
String jsonStr = "{\"age\":19,\"name\":\"周杰伦\",\"courses\":[\"高等数学\"]}";
JsonNode jsonNode = objectMapper.readTree(jsonStr);
ArrayNode arrayNode = (ArrayNode) jsonNode.withArray("courses");
arrayNode.add("马列");
for (int i = 0;i < arrayNode.size();i++){
System.out.println(arrayNode.get(i).asText());
}
System.out.println(jsonNode.toString()); }
}

运行结果:

OBJECT
ARRAY
{"age":19,"name":"周杰伦","courses":["高等数学"]}
高等数学
马列
{"age":19,"name":"周杰伦","courses":["高等数学","马列"]}

Data Binding 示例

package com.maolv.oschina;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date; import org.junit.Before;
import org.junit.Test; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; /**
* Jackson Data bind 解析生成示例
*/
public class JacksonDataBindTest { private ObjectMapper baseMapper;
private ObjectMapper prettyMapper1;
private ObjectMapper prettyMapper2;
private ObjectMapper nonEmptyMapper; @Before
public void init(){
baseMapper = new ObjectMapper();
// 对于空的对象转json的时候不抛出错误
baseMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 禁用遇到未知属性抛出异常
baseMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
baseMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
// 低层级配置
baseMapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);
baseMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,true);
baseMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES,true);
// 配置两个副本
prettyMapper1 = baseMapper.copy();
prettyMapper2 = baseMapper.copy();
// 高级配置
prettyMapper1.enable(SerializationFeature.INDENT_OUTPUT);
prettyMapper1.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
prettyMapper1.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
// 禁用序列化日期为timestamps
prettyMapper1.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
prettyMapper1.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII,false);
// Json格式化展示
prettyMapper2.setSerializationInclusion(JsonInclude.Include.NON_NULL);
prettyMapper2.enable(SerializationFeature.INDENT_OUTPUT);
prettyMapper2.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII,true);
prettyMapper2.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX); nonEmptyMapper = new ObjectMapper();
nonEmptyMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
nonEmptyMapper.enable(SerializationFeature.INDENT_OUTPUT);
nonEmptyMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
} @Test
public void testReadValue() throws IOException {
String json = "{\n" +
" \"name\" : \"发如雪\",\n" +
" \"now\" : \"2015-12-17 17:25:13\",\n" +
" \"sexy\" : \"MEN\"\n" +
"}";
TestBean testBean = nonEmptyMapper.readValue(json,TestBean.class);
System.out.println(testBean.toString());
} @Test
public void testWriteValue() throws IOException {
TestBean testBean = new TestBean("发如雪",Sexy.MEN);
System.out.println(prettyMapper1.writeValueAsString(testBean));
System.out.println(prettyMapper2.writeValueAsString(testBean));
System.out.println(nonEmptyMapper.writeValueAsString(testBean));
} }
class TestBean{
private String name;
private String course;
private Date now;
private Sexy sexy;
public TestBean(){}
public TestBean(String name,Sexy sexy){
this.name = name;
this.sexy = sexy;
this.now = new Date();
} public Date getNow() {
return now;
} public void setNow(Date now) {
this.now = now;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Sexy getSexy() {
return sexy;
} public void setSexy(Sexy sexy) {
this.sexy = sexy;
} public String getCourse() {
return course;
} public void setCourse(String course) {
this.course = course;
} @Override
public String toString() {
return "TestBean{" +
"name='" + name + '\'' +
", course='" + course + '\'' +
", now=" + now +
", sexy=" + sexy +
'}';
}
}
enum Sexy{
MEN("男","M"),WOMEN("女","W");
private String text;
private String code; private Sexy(String text,String code){
this.text = text;
this.code = code;
} public String getText() {
return text;
} public String getCode() {
return code;
} @Override
public String toString() {
return "{\"text\":\""+getText()+"\",\"code\":\""+getCode()+"\"}";
}
}

开源工具-Json 解析器 Jackson 的使用的更多相关文章

  1. spring boot2 修改默认json解析器Jackson为fastjson

    0.前言 fastjson是阿里出的,尽管近年fasjson爆出过几次严重漏洞,但是平心而论,fastjson的性能的确很有优势,尤其是大数据量时的性能优势,所以fastjson依然是我们的首选:sp ...

  2. Jackson:我是最牛掰的 Java JSON 解析器(有点虚)

    在当今的编程世界里,JSON 已经成为将信息从客户端传输到服务器端的首选协议,可以好不夸张的说,XML 就是那个被拍死在沙滩上的前浪. 很不幸的是,JDK 没有 JSON 库,不知道为什么不搞一下.L ...

  3. SpringBoot 默认json解析器详解和字段序列化自定义

    前言 在我们开发项目API接口的时候,一些没有数据的字段会默认返回NULL,数字类型也会是NULL,这个时候前端希望字符串能够统一返回空字符,数字默认返回0,那我们就需要自定义json序列化处理 Sp ...

  4. 这个东西,写C++插件的可以用到。 RapidJSON —— C++ 快速 JSON 解析器和生成器

    点这里 原文: RapidJSON —— C++ 快速 JSON 解析器和生成器 时间 2015-04-05 07:33:33  开源中国新闻原文  http://www.oschina.net/p/ ...

  5. 高性能JSON解析器及生成器RapidJSON

    RapidJSON是腾讯公司开源的一个C++的高性能的JSON解析器及生成器,同时支持SAX/DOM风格的API. 直击现场 RapidJSON是腾讯公司开源的一个C++的高性能的JSON解析器及生成 ...

  6. 手写Json解析器学习心得

    一. 介绍 一周前,老同学阿立给我转了一篇知乎回答,答主说检验一门语言是否掌握的标准是实现一个Json解析器,网易游戏过去的Python入门培训作业之一就是五天时间实现一个Json解析器. 知乎回答- ...

  7. 几百行代码实现一个 JSON 解析器

    前言 之前在写 gscript时我就在想有没有利用编译原理实现一个更实际工具?毕竟真写一个语言的难度不低,并且也很难真的应用起来. 一次无意间看到有人提起 JSON 解析器,这类工具充斥着我们的日常开 ...

  8. 一起写一个JSON解析器

    [本篇博文会介绍JSON解析的原理与实现,并一步一步写出来一个简单但实用的JSON解析器,项目地址:SimpleJSON.希望通过这篇博文,能让我们以后与JSON打交道时更加得心应手.由于个人水平有限 ...

  9. 如何编写一个JSON解析器

    编写一个JSON解析器实际上就是一个函数,它的输入是一个表示JSON的字符串,输出是结构化的对应到语言本身的数据结构. 和XML相比,JSON本身结构非常简单,并且仅有几种数据类型,以Java为例,对 ...

随机推荐

  1. python的三个函数(eval、exec、complie)和python版RMI

    一.python的三个函数: 1.eval函数: 之前已经讲过了这个函数,该函数也类似于php的eval,例如下边这个例子 eval("os.system('id')") 但是有个 ...

  2. WEB安全第六篇--千里之外奇袭客户端:XSS和HTML注入

    零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...

  3. 170808、生成为CVS文件

    /** * Desc : 生成为CVS文件 * User : RICK * @param data 源数据List * @param map csv文件的列表头map * @param outPutP ...

  4. [转] mysql数据库分离和附加

    1.导出整个数据库 mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u wcnc -p smgp_apps_wcnc > wcnc.sql 2.导 ...

  5. pta习题集 5-10 切分表达式——写个tokenizer吧

    [先说点出题背景] 这个题是为低年级同学.学C语言的同学准备的,因为,对这部分同学,这个题目编写起来略有一点复杂.如果是高年级.学过了正则表达式(Regular Expression)的同学或者学过了 ...

  6. Ubuntu下MySQL主从同步配置

    一.在两台Linux机器上安装MySQL 二.Master主服务器配置(192.168.1.3) 1.编辑my.cnf编(命令查找文件位置:find / -name my.cnf) vi /etc/m ...

  7. python基础之递归、二分法

    一 递归 1. 必须有一个明确的结束条件2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结 ...

  8. Hive与ES整合

    https://www.elastic.co/guide/en/elasticsearch/hadoop/current/hive.html 注:添加的第三方jar必须位于namenode下,否则依然 ...

  9. js-jquery-从SweetAlert到SweetAlert2

    原文地址:https://github.com/limonte/sweetalert2/wiki/Migration-from-SweetAlert-to-SweetAlert2 1. IE supp ...

  10. python 异常处理、进程

    目录: 异常处理 python进程 python并发之多进程 一.异常处理(try...except...) 1.程序中难免出现错误,而错误分成两种: a.语法错误: b.逻辑错误(逻辑错误) 2.异 ...