版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_37076574/article/details/81317403
JackSon介绍
本文使用的JackSon版本为2.9.6。

JackSon是解析JSON和XML的一个框架,优点是简单易用,性能较高。

JackSon处理JSON的方式
JackSon提供了三种JSON的处理方式。分别是数据绑定,树模型,流式API。下面会分别介绍这三种方式。

JackSon数据绑定
数据绑定用于JSON转化,可以将JSON与POJO对象进行转化。数据绑定有两种,简单数据绑定和完整数据绑定。

完整数据绑定
package com.xymxyg.json;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

/**
* @author guangsheng.tang
* 下面是最常用的场景,将json字符串映射为对象,或者是将对象转化为json字符串。这是完整数据绑定。
缺点:这种方法十分方便,但是扩展性不强,增加一个字段便要修改POJO对象,这个操作有一定风险性。并且解析的时候,如果json缺少POJO中的某字段,映射出的对象对应值默认为null,直接使用有一定风险。如果json对象多了某一字段,解析过程中会抛出UnrecognizedPropertyException异常。并且如果json较为复杂的话,POJO对象会显得特别臃肿。
*/
public class CompleteDataBind {
public static void main(String[] args) throws IOException {
String s = "{\"id\": 1,\"name\": \"小明\",\"array\": [\"1\", \"2\"]}";
ObjectMapper mapper = new ObjectMapper();
//Json映射为对象
Student student = mapper.readValue(s, Student.class);
//对象转化为Json
String json = mapper.writeValueAsString(student);
System.out.println(json);
System.out.println(student.toString());
}
}

package com.xymxyg.json;

/**
* @author guangsheng.tang
*/
public class Student {
private int id;
private String name;
private String sex;
private ArrayList<String> array;
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public ArrayList<String> getArray() {
return array;
}

public void setArray(ArrayList<String> array) {
this.array = array;
}

@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", array=" + Arrays.toString(array.toArray()) +
'}';
}
}

简单数据绑定
简单数据绑定就是将json字符串映射为java核心的数据类型。

json类型 Java类型
object LinkedHashMap
array ArrayList
string String
number Integer,Long,Double
true|false Boolean
null null
下面演示一个例子,将json转化为一个Map。通过Map来读取。

package com.xymxyg.json;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
* @author guangsheng.tang
* 简单数据绑定的示例,不用POJO对象,直接映射为一个Map,然后从Map中获取。
*/
public class SimpleDataBind {
public static void main(String[] args) throws IOException {
Map<String, Object> map = new HashMap<>(16);
String s = "{\"id\": 1,\"name\": \"小明\",\"array\": [\"1\", \"2\"]," +
"\"test\":\"I'm test\",\"base\": {\"major\": \"物联网\",\"class\": \"3\"}}";
ObjectMapper mapper = new ObjectMapper();
map = mapper.readValue(s, map.getClass());
//获取id
Integer studentId = (Integer) map.get("id");
System.out.println(studentId);
//获取数据
ArrayList list = (ArrayList) map.get("array");
System.out.println(Arrays.toString(list.toArray()));
//新增加的字段可以很方便的处理
String test = (String) map.get("test");
System.out.println(test);
//不存在的返回null
String notExist = (String) map.get("notExist");
System.out.println(notExist);
//嵌套的对象获取
Map base = (Map) map.get("base");
String major = (String) base.get("major");
System.out.println(major);
}
}

树模型
针对JackSon的树模型结构,我下面写了一个比较完善的例子。同样Java树模型有优点,也有缺点。

package com.xymxyg.json;

import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.IOException;

/**
* @author guangsheng.tang
* JackSon树模型结构,可以通过get,JsonPointer等进行操作,适合用来获取大Json中的字段,比较灵活。缺点是如果需要获取的内容较多,
* 会显得比较繁琐。
*/
public class TreeModel {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
//以下是对象转化为Json
JsonNode root = mapper.createObjectNode();
((ObjectNode) root).putArray("array");
ArrayNode arrayNode = (ArrayNode) root.get("array");
((ArrayNode) arrayNode).add("args1");
((ArrayNode) arrayNode).add("args2");
((ObjectNode) root).put("name", "小红");
String json = mapper.writeValueAsString(root);
System.out.println("使用树型模型构建的json:"+json);
//以下是树模型的解析Json
String s = "{\"id\": 1,\"name\": \"小明\",\"array\": [\"1\", \"2\"]," +
"\"test\":\"I'm test\",\"nullNode\":null,\"base\": {\"major\": \"物联网\",\"class\": \"3\"}}";
//读取rootNode
JsonNode rootNode = mapper.readTree(s);
//通过path获取
System.out.println("通过path获取值:" + rootNode.path("name").asText());
//通过JsonPointer可以直接按照路径获取
JsonPointer pointer = JsonPointer.valueOf("/base/major");
JsonNode node = rootNode.at(pointer);
System.out.println("通过at获取值:" + node.asText());
//通过get可以取对应的value
JsonNode classNode = rootNode.get("base");
System.out.println("通过get获取值:" + classNode.get("major").asText());

//获取数组的值
System.out.print("获取数组的值:");
JsonNode arrayNode2 = rootNode.get("array");
for (int i = 0; i < arrayNode2.size(); i++) {
System.out.print(arrayNode2.get(i).asText()+" ");
}
System.out.println();
//path和get方法看起来很相似,其实他们的细节不同,get方法取不存在的值的时候,会返回null。而path方法会
//返回一个"missing node",该"missing node"的isMissingNode方法返回值为true,如果调用该node的asText方法的话,
// 结果是一个空字符串。
System.out.println("get方法取不存在的节点,返回null:" + (rootNode.get("notExist") == null));
JsonNode notExistNode = rootNode.path("notExist");
System.out.println("notExistNode的value:" + notExistNode.asText());
System.out.println("isMissingNode方法返回true:" + notExistNode.isMissingNode());

//当key存在,而value为null的时候,get和path都会返回一个NullNode节点。
System.out.println(rootNode.get("nullNode") instanceof NullNode);
System.out.println(rootNode.path("nullNode") instanceof NullNode);
}
}

流式API
流式API是一套比较底层的API,速度快,但是使用起来特别麻烦。它主要是有两个核心类,一个是JsonGenerator,用来生成json,另一个是JsonParser,用来读取json内容。话不多说,直接上代码演示。

package com.xymxyg.json;

import com.fasterxml.jackson.core.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
* @author guangsheng.tang
* JsonParser和Generator的优点是速度快,缺点是写起来真的很复杂。
*/
public class StreamApi {
public static void main(String[] args) throws IOException {
JsonFactory factory = new JsonFactory();
String s = "{\"id\": 1,\"name\": \"小明\",\"array\": [\"1\", \"2\"]," +
"\"test\":\"I'm test\",\"nullNode\":null,\"base\": {\"major\": \"物联网\",\"class\": \"3\"}}";

//这里就举一个比较简单的例子,Generator的用法就是一个一个write即可。
File file = new File("/json.txt");
JsonGenerator jsonGenerator = factory.createGenerator(file, JsonEncoding.UTF8);
//对象开始
jsonGenerator.writeStartObject();
//写入一个键值对
jsonGenerator.writeStringField("name", "小光");
//对象结束
jsonGenerator.writeEndObject();
//关闭jsonGenerator
jsonGenerator.close();
//读取刚刚写入的json
FileInputStream inputStream = new FileInputStream(file);
int i = 0;
final int SIZE = 1024;
byte[] buf = new byte[SIZE];
StringBuilder sb = new StringBuilder();
while ((i = inputStream.read(buf)) != -1) {
System.out.println(new String(buf,0,i));
}
inputStream.close();

//JsonParser解析的时候,思路是把json字符串根据边界符分割为若干个JsonToken,这个JsonToken是一个枚举类型。
//下面这个小例子,可以看出JsonToken是如何划分类型的。
JsonParser parser = factory.createParser(s);
while (!parser.isClosed()){
JsonToken token = parser.currentToken();
System.out.println(token);
parser.nextToken();
}

JsonParser jsonParser = factory.createParser(s);
//下面是一个解析的实例
while (!jsonParser.isClosed()) {
JsonToken token = jsonParser.nextToken();
if (JsonToken.FIELD_NAME.equals(token)) {
String currentName = jsonParser.currentName();
token = jsonParser.nextToken();
if ("id".equals(currentName)) {
System.out.println("id:" + jsonParser.getValueAsInt());
} else if ("name".equals(currentName)) {
System.out.println("name:" + jsonParser.getValueAsString());
} else if ("array".equals(currentName)) {
token = jsonParser.nextToken();
while (!JsonToken.END_ARRAY.equals(token)) {
System.out.println("array:" + jsonParser.getValueAsString());
token = jsonParser.nextToken();
}
}
}
}
}

}

JackSon的常用注解
JackSon提供了一些的注解,可以用在类上或者是在字段上。通常是数据绑定的时候使用。下面几个是最常用的几个

@JsonInclude(Include.NON_EMPTY)
仅在属性不为空时序列化此字段,对于字符串,即null或空字符串

@JsonIgnore
序列化时忽略此字段

@JsonProperty(value = “user_name”)
指定序列化时的字段名,默认使用属性名

总结
JackSon使用起来还是十分方便的,提供的功能也很多,在使用的时候,需要结合自己的业务场景,选择合适的解析方式。

参考资料
http://blog.lifw.org/post/63088058v
https://www.yiibai.com/jackson/

Jackson使用的更多相关文章

  1. jackson简单使用,对象转json,json转对象,json转list

    添加jackson依赖: // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core compile g ...

  2. Jackson 通过自定义注解来控制json key的格式

    Jackson 通过自定义注解来控制json key的格式 最近我这边有一个需求就是需要把Bean中的某一些特殊字段的值进行替换.而这个替换过程是需要依赖一个第三方的dubbo服务的.为了使得这个转换 ...

  3. Jackson的简单用法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1简介 Jackson具有比较高的序列化和反序列化效率,据测试,无论是 ...

  4. jackson error 含义log

    1. 反序列化失败,类型不匹配 Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserial ize ...

  5. jackson annotations注解详解

    jackson中常用到的注解 猛击下面的连接地址 http://blog.csdn.net/sdyy321/article/details/40298081

  6. jackson官方快速入门文档

    官方地址: http://jackson.codehaus.org/ http://wiki.fasterxml.com/JacksonInFiveMinutes http://wiki.faster ...

  7. Jackson将json字符串转换成泛型List

    Jackson,我感觉是在Java与Json之间相互转换的最快速的框架,当然Google的Gson也很不错,但是参照网上有人的性能测试,看起来还是Jackson比较快一点 Jackson处理一般的Ja ...

  8. 使用Jackson解析Json示例

    原文http://blog.csdn.net/gebitan505/article/details/17005735 custom.json: {     "country":&q ...

  9. Json解析工具Jackson(使用注解)

    原文http://blog.csdn.net/nomousewch/article/details/8955796 接上一篇文章Json解析工具Jackson(简单应用),jackson在实际应用中给 ...

  10. Json解析工具Jackson(简单应用)

    原文http://blog.csdn.net/nomousewch/article/details/8955796 概述 Jackson库(http://jackson.codehaus.org),是 ...

随机推荐

  1. mnist卷积网络实现

    加载MNIST数据 from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_se ...

  2. mac使用poetry

    安装 为了防止依赖冲突不推荐使用pip的方式直接安装,当然你也可以这样做 curl -sSL https://raw.githubusercontent.com/sdispater/poetry/ma ...

  3. Emmet语法规则

    HTML速写之Emmet语法规则 Emmet-写HTML/CSS快到飞起 在前端开发的过程中,最费时间的工作就是写 HTML.CSS 代码.一堆的标签.属性.括号等,头疼.这里推荐一个Emmet语法规 ...

  4. Python自动化测试常用库

    基本库: sys 程序和Python解析器的交互 os 启动新进程:操作文件和目录 re 正则表达式,字符串匹配 string 基本字符串操作 inspect 提供自省和反射功能 importlib ...

  5. Android 9.0 Http不能访问网络

    最近在做公司产品,一期完成,打包给测试,然后....一台手机连服务器都访问不了看日志如下: UnityWebRequest返回code:0,显示Unknow error 服务器接口是http://非域 ...

  6. 第十二章 Python文件操作【转】

    12.1 open() open()函数作用是打开文件,返回一个文件对象. 用法格式:open(name[, mode[, buffering[,encoding]]]) -> file obj ...

  7. Unix下可用的五种 I/O 模型

    介绍 当TCP客户端同时处理两个输入时:标准输入和TCP套接字,当客户端fgets(在标准输入上)被阻塞并且服务器进程被终止时,我们遇到了问题.服务器TCP正确地将FIN发送到客户端TCP,但由于客户 ...

  8. Thread.currentThread与this的区别

    在看多线程的时候,看到这个知识点,感觉需要验证一下. 一:线程自启动 1.程序 package com.jun.it.thread; public class MyThread extends Thr ...

  9. Kali Linux软件更新日报20190623

    Kali Linux软件更新日报20190623   (1)payloadsallthethings更新到2.0-0kali4,此次更新增加帮助脚本. (2)tftpd32更新到4.50-0kali2 ...

  10. Docs-.NET-C#-指南-语言参考-预处理器指令:#pragma(C# 参考)

    ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:#pragma(C# 参考) 1.返回顶部 1. #pragma(C# 参考) 2015/07/20 #pragma 为编译器给 ...