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);//对象转化为JsonString 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;}@Overridepublic 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());//获取idInteger 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);//不存在的返回nullString 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();//以下是对象转化为JsonJsonNode 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);//以下是树模型的解析JsonString s = "{\"id\": 1,\"name\": \"小明\",\"array\": [\"1\", \"2\"]," +"\"test\":\"I'm test\",\"nullNode\":null,\"base\": {\"major\": \"物联网\",\"class\": \"3\"}}";//读取rootNodeJsonNode 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可以取对应的valueJsonNode 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();//关闭jsonGeneratorjsonGenerator.close();//读取刚刚写入的jsonFileInputStream 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. Android Intent的几种用法全面总结

    Android Intent的几种用法全面总结 Intent, 用法 Intent应该算是Android中特有的东西.你可以在Intent中指定程序要执行的动作(比如:view,edit,dial), ...

  2. mysql中模糊查询的四种用法介绍

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示.  比如 SELECT * FROM [user ...

  3. javamap的用法_Java Map常用的几种用法。

    Java Map常用的几种用法. 通常,Map是由一组键值对组成的数据结构,每个键只能在映射中出现一次.这篇文章总结了有关如何使用Java Map及其实现的类的前9个常见问题解答.为了简单起见,我将在 ...

  4. using 的三种用法

    using 有哪三种用法? 1)引入命名空间. 2)给命名空间或者类型起别名. 3)划定作用域.自动释放资源,使用该方法的类型必须实现了 System.IDisposable接口,当对象脱离作用域之后 ...

  5. C++ operator两种用法【转】

    C++中的operator,有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).下面分别进行介绍: 1.operator ...

  6. java和python可以在一个项目中同时使用么-java调用python的几种用法(看这篇就够了)...

    java调用python的几种用法如下: 在java类中直接执行python语句 在java类中直接调用本地python脚本 使用Runtime.getRuntime()执行python脚本文件(推荐 ...

  7. static的三种用法,定义静态变量,静态函数,静态代码块!

    static的三种用法,定义静态变量,静态函数,静态代码块! 1.定义静态变量 class PersonStatic { //静态变量的特点 //1.静态变量无需生成对象就可被调用,可以使用类名和对象 ...

  8. Vue——基本的代码结构和插值表达式、v-cloak||Vue指令之v-text和v-html||v-bind的三种用法||Vue指令之v-on

    Vue的基本代码 <!DOCTYPE html> <html lang="en"><head><meta charset="UT ...

  9. js中继承的几种用法总结(apply,call,prototype)

    本篇文章主要介绍了js中继承的几种用法总结(apply,call,prototype) 需要的朋友可以过来参考下,希望对大家有所帮助 一,js中对象继承 js中有三种继承方式 1.js原型(proto ...

最新文章

  1. 今天你(L)China了吗?
  2. java中的abstract和interface差异
  3. ***组网不用愁之1-中小企业***网络组建应用实录
  4. Vue node.js商城-购物车模块
  5. 单片机c语言 oxfe,AVR单片机入门及C语言高效设计实践(五)
  6. 为List配置一个搜索按钮
  7. mysql数据库,当数据类型是float时,查询居然查询不出数据来
  8. linux能记录日志的终端,如何记录Linux终端下的操作日志
  9. NS2仿真过程中需要的语言及基本组件
  10. oracle触发器实例
  11. 微信会员卡 java请求_会员系统对接微信会员卡的好处
  12. 计算机视觉研究院手把手教你深度学习的部署(手势识别,源码已开源)
  13. huoshan_火山版 xl,xa,xg,xk 签名参数分析
  14. LTspice 电路仿真入门
  15. 华为nova7se能云闪付吗_华为nova7se支持NFC功能吗?可以用NFC来刷公交卡吗
  16. 计算机模拟多孔碳,华南农业大学刘应亮教授课题组:废弃板栗壳制备多孔碳材料,用于用于储能设备...
  17. 华为机试:非严格递增连续数字序列
  18. stm32 硬件spi半双工三线的一些研究心得
  19. CPU使用率低 内存使用率高
  20. 正则表达式(Regular Expression)基础使用、贪婪性、懒惰性以及常用方法

热门文章

  1. FrameLayout实现霓虹灯效果
  2. 操作系统课程ucore实验 lab1
  3. 怎么在电脑上用手机模拟器+618IP代理换不同的IP多开游戏
  4. Python改善生活 | 轻松实现APP自动化记账
  5. python:实现数组去重算法(附完整源码)
  6. 在线SQL转文本工具
  7. 推广下自己的JAVA开源游戏服务端框架
  8. java求路段平均旅行时间,基于电警卡口的旅行时间计算方法
  9. 【go】xxx is not in GOROOT 错误
  10. 计算机网络布线实训,计算机网络--综合布线实训报告.doc