JackSon的几种用法
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的几种用法相关推荐
- Android Intent的几种用法全面总结
Android Intent的几种用法全面总结 Intent, 用法 Intent应该算是Android中特有的东西.你可以在Intent中指定程序要执行的动作(比如:view,edit,dial), ...
- mysql中模糊查询的四种用法介绍
下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user ...
- javamap的用法_Java Map常用的几种用法。
Java Map常用的几种用法. 通常,Map是由一组键值对组成的数据结构,每个键只能在映射中出现一次.这篇文章总结了有关如何使用Java Map及其实现的类的前9个常见问题解答.为了简单起见,我将在 ...
- using 的三种用法
using 有哪三种用法? 1)引入命名空间. 2)给命名空间或者类型起别名. 3)划定作用域.自动释放资源,使用该方法的类型必须实现了 System.IDisposable接口,当对象脱离作用域之后 ...
- C++ operator两种用法【转】
C++中的operator,有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).下面分别进行介绍: 1.operator ...
- java和python可以在一个项目中同时使用么-java调用python的几种用法(看这篇就够了)...
java调用python的几种用法如下: 在java类中直接执行python语句 在java类中直接调用本地python脚本 使用Runtime.getRuntime()执行python脚本文件(推荐 ...
- static的三种用法,定义静态变量,静态函数,静态代码块!
static的三种用法,定义静态变量,静态函数,静态代码块! 1.定义静态变量 class PersonStatic { //静态变量的特点 //1.静态变量无需生成对象就可被调用,可以使用类名和对象 ...
- Vue——基本的代码结构和插值表达式、v-cloak||Vue指令之v-text和v-html||v-bind的三种用法||Vue指令之v-on
Vue的基本代码 <!DOCTYPE html> <html lang="en"><head><meta charset="UT ...
- js中继承的几种用法总结(apply,call,prototype)
本篇文章主要介绍了js中继承的几种用法总结(apply,call,prototype) 需要的朋友可以过来参考下,希望对大家有所帮助 一,js中对象继承 js中有三种继承方式 1.js原型(proto ...
最新文章
- 今天你(L)China了吗?
- java中的abstract和interface差异
- ***组网不用愁之1-中小企业***网络组建应用实录
- Vue node.js商城-购物车模块
- 单片机c语言 oxfe,AVR单片机入门及C语言高效设计实践(五)
- 为List配置一个搜索按钮
- mysql数据库,当数据类型是float时,查询居然查询不出数据来
- linux能记录日志的终端,如何记录Linux终端下的操作日志
- NS2仿真过程中需要的语言及基本组件
- oracle触发器实例
- 微信会员卡 java请求_会员系统对接微信会员卡的好处
- 计算机视觉研究院手把手教你深度学习的部署(手势识别,源码已开源)
- huoshan_火山版 xl,xa,xg,xk 签名参数分析
- LTspice 电路仿真入门
- 华为nova7se能云闪付吗_华为nova7se支持NFC功能吗?可以用NFC来刷公交卡吗
- 计算机模拟多孔碳,华南农业大学刘应亮教授课题组:废弃板栗壳制备多孔碳材料,用于用于储能设备...
- 华为机试:非严格递增连续数字序列
- stm32 硬件spi半双工三线的一些研究心得
- CPU使用率低 内存使用率高
- 正则表达式(Regular Expression)基础使用、贪婪性、懒惰性以及常用方法