开源工具-Json 解析器 Jackson 的使用
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: 数据绑定(依赖core和annotations)
使用方式
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 的使用的更多相关文章
- spring boot2 修改默认json解析器Jackson为fastjson
0.前言 fastjson是阿里出的,尽管近年fasjson爆出过几次严重漏洞,但是平心而论,fastjson的性能的确很有优势,尤其是大数据量时的性能优势,所以fastjson依然是我们的首选:sp ...
- Jackson:我是最牛掰的 Java JSON 解析器(有点虚)
在当今的编程世界里,JSON 已经成为将信息从客户端传输到服务器端的首选协议,可以好不夸张的说,XML 就是那个被拍死在沙滩上的前浪. 很不幸的是,JDK 没有 JSON 库,不知道为什么不搞一下.L ...
- SpringBoot 默认json解析器详解和字段序列化自定义
前言 在我们开发项目API接口的时候,一些没有数据的字段会默认返回NULL,数字类型也会是NULL,这个时候前端希望字符串能够统一返回空字符,数字默认返回0,那我们就需要自定义json序列化处理 Sp ...
- 这个东西,写C++插件的可以用到。 RapidJSON —— C++ 快速 JSON 解析器和生成器
点这里 原文: RapidJSON —— C++ 快速 JSON 解析器和生成器 时间 2015-04-05 07:33:33 开源中国新闻原文 http://www.oschina.net/p/ ...
- 高性能JSON解析器及生成器RapidJSON
RapidJSON是腾讯公司开源的一个C++的高性能的JSON解析器及生成器,同时支持SAX/DOM风格的API. 直击现场 RapidJSON是腾讯公司开源的一个C++的高性能的JSON解析器及生成 ...
- 手写Json解析器学习心得
一. 介绍 一周前,老同学阿立给我转了一篇知乎回答,答主说检验一门语言是否掌握的标准是实现一个Json解析器,网易游戏过去的Python入门培训作业之一就是五天时间实现一个Json解析器. 知乎回答- ...
- 几百行代码实现一个 JSON 解析器
前言 之前在写 gscript时我就在想有没有利用编译原理实现一个更实际工具?毕竟真写一个语言的难度不低,并且也很难真的应用起来. 一次无意间看到有人提起 JSON 解析器,这类工具充斥着我们的日常开 ...
- 一起写一个JSON解析器
[本篇博文会介绍JSON解析的原理与实现,并一步一步写出来一个简单但实用的JSON解析器,项目地址:SimpleJSON.希望通过这篇博文,能让我们以后与JSON打交道时更加得心应手.由于个人水平有限 ...
- 如何编写一个JSON解析器
编写一个JSON解析器实际上就是一个函数,它的输入是一个表示JSON的字符串,输出是结构化的对应到语言本身的数据结构. 和XML相比,JSON本身结构非常简单,并且仅有几种数据类型,以Java为例,对 ...
随机推荐
- 深入浅出Docker(二):Docker命令行探秘
1. Docker命令行 Docker官方为了让用户快速了解Docker,提供了一个交互式教程,旨在帮助用户掌握Docker命令行的使用方法.但是由于Docker技术的快速发展,此交互式教程已经无法满 ...
- 巡风代码架构简介以及Flask的项目文件结构简介
一.巡风: 巡风是一款什么东西,想必安全同行都不陌生吧.用它作为内网漏洞扫描管理架构是一种很好的选择,扫描快,开源,还可自己编写符合规则的POC直接放入相应目录来扩展.今天下午趁着有点时间捋了一下巡风 ...
- 【黑金ZYNQ7000系列原创视频教程】07.自定义IP——定制RTC IP实验
黑金论坛地址: http://www.heijin.org/forum.php?mod=viewthread&tid=36641&extra=page%3D1 爱奇艺地址: http: ...
- Video如何不自动全屏播放?
知乎:微信内置浏览器 如何小窗不全屏播放视频? 目前在微信中只能全屏播放,只有加入腾讯白名单的视频才能小屏播放. 知乎上讨论的解决方案尚未测试,太麻烦了.
- 以前做的H5推广小游戏(活动及派发奖品形式)
润百颜 1 微信授权登录,获取用户openid.一个openid一次抽奖机会,该openid用户多次玩游戏抽奖,仍然是相同的优惠码. 2 游戏结束抽奖,100%中奖,获得优惠码.优惠码和openid保 ...
- 【BZOJ4236】JOIOJI STL
[BZOJ4236]JOIOJI Description JOIOJI桑是JOI君的叔叔.“JOIOJI”这个名字是由“J.O.I”三个字母各两个构成的. 最近,JOIOJI桑有了一个孩子.JOIOJ ...
- Thrift入门之mac下的安装流程
新建一个maven项目,先下载maven依赖 http://thrift.apache.org/download <dependency> <groupId>org.apac ...
- MS-SQL数据库定时自动备份
在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库.而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求管理员每天守到晚上1点去备份数据库.要实现数据库的定 ...
- (ubuntu ufw)My firewall is blocking network connections from the docker container to outside
Maybe this is due to the current version, but the current answer doesn't work on my system (Docker 0 ...
- UEM用户行为了如指掌!
“千呼万唤始出来”,万众期待的UEM正式与宝宝们见面啦~~~ 今天很多人来问小编,Web咋不见了,表急,Web并没有消失,而是重磅升级为UEM啦!!! 什么是UEM呢?UEM全称User Experi ...