浅谈JackSon的几种用法
JackSon介绍
本文使用的JackSon版本为2.9.6。
JackSon是解析JSON和XML的一个框架,优点是简单易用,性能较高。
JackSon处理JSON的方式
JackSon提供了三种JSON的处理方式。分别是数据绑定,树模型,流式API。下面会分别介绍这三种方式。
JackSon数据绑定
数据绑定用于JSON转化,可以将JSON与POJO对象进行转化。数据绑定有两种,简单数据绑定和完整数据绑定。
完整数据绑定
packagecom.xymxyg.json;
importcom.fasterxml.jackson.databind.ObjectMapper;
importjava.io.IOException;
/**
*@authorguangsheng.tang
*下面是最常用的场景,将json字符串映射为对象,或者是将对象转化为json字符串。这是完整数据绑定。
缺点:这种方法十分方便,但是扩展性不强,增加一个字段便要修改POJO对象,这个操作有一定风险性。并且解析的时候,如果json缺少POJO中的某字段,映射出的对象对应值默认为null,直接使用有一定风险。如果json对象多了某一字段,解析过程中会抛出UnrecognizedPropertyException异常。并且如果json较为复杂的话,POJO对象会显得特别臃肿。
*/
publicclassCompleteDataBind{
publicstaticvoidmain(String[]args)throwsIOException{
Strings="{\"id\":1,\"name\":\"小明\",\"array\":[\"1\",\"2\"]}";
ObjectMappermapper=newObjectMapper();
//Json映射为对象
Studentstudent=mapper.readValue(s,Student.class);
//对象转化为Json
Stringjson=mapper.writeValueAsString(student);
System.out.println(json);
System.out.println(student.toString());
}
}
packagecom.xymxyg.json;
/**
*@authorguangsheng.tang
*/
publicclassStudent{
privateintid;
privateStringname;
privateStringsex;
privateArrayListarray;
publicintgetId(){
returnid;
}
publicvoidsetId(intid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetSex(){
returnsex;
}
publicvoidsetSex(Stringsex){
this.sex=sex;
}
publicArrayListgetArray(){
returnarray;
}
publicvoidsetArray(ArrayListarray){
this.array=array;
}
@Override
publicStringtoString(){
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来读取。
packagecom.xymxyg.json;
importcom.fasterxml.jackson.databind.ObjectMapper;
importjava.io.IOException;
importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.HashMap;
importjava.util.Map;
/**
*@authorguangsheng.tang
*简单数据绑定的示例,不用POJO对象,直接映射为一个Map,然后从Map中获取。
*/
publicclassSimpleDataBind{
publicstaticvoidmain(String[]args)throwsIOException{
Mapmap=newHashMap<>(16);
Strings="{\"id\":1,\"name\":\"小明\",\"array\":[\"1\",\"2\"],"+
"\"test\":\"I'mtest\",\"base\":{\"major\":\"物联网\",\"class\":\"3\"}}";
ObjectMappermapper=newObjectMapper();
map=mapper.readValue(s,map.getClass());
//获取id
IntegerstudentId=(Integer)map.get("id");
System.out.println(studentId);
//获取数据
ArrayListlist=(ArrayList)map.get("array");
System.out.println(Arrays.toString(list.toArray()));
//新增加的字段可以很方便的处理
Stringtest=(String)map.get("test");
System.out.println(test);
//不存在的返回null
StringnotExist=(String)map.get("notExist");
System.out.println(notExist);
//嵌套的对象获取
Mapbase=(Map)map.get("base");
Stringmajor=(String)base.get("major");
System.out.println(major);
}
}
树模型
针对JackSon的树模型结构,我下面写了一个比较完善的例子。同样Java树模型有优点,也有缺点。
packagecom.xymxyg.json;
importcom.fasterxml.jackson.core.JsonPointer;
importcom.fasterxml.jackson.databind.JsonNode;
importcom.fasterxml.jackson.databind.ObjectMapper;
importcom.fasterxml.jackson.databind.node.ArrayNode;
importcom.fasterxml.jackson.databind.node.NullNode;
importcom.fasterxml.jackson.databind.node.ObjectNode;
importjava.io.IOException;
/**
*@authorguangsheng.tang
*JackSon树模型结构,可以通过get,JsonPointer等进行操作,适合用来获取大Json中的字段,比较灵活。缺点是如果需要获取的内容较多,
*会显得比较繁琐。
*/
publicclassTreeModel{
publicstaticvoidmain(String[]args)throwsIOException{
ObjectMappermapper=newObjectMapper();
//以下是对象转化为Json
JsonNoderoot=mapper.createObjectNode();
((ObjectNode)root).putArray("array");
ArrayNodearrayNode=(ArrayNode)root.get("array");
((ArrayNode)arrayNode).add("args1");
((ArrayNode)arrayNode).add("args2");
((ObjectNode)root).put("name","小红");
Stringjson=mapper.writeValueAsString(root);
System.out.println("使用树型模型构建的json:"+json);
//以下是树模型的解析Json
Strings="{\"id\":1,\"name\":\"小明\",\"array\":[\"1\",\"2\"],"+
"\"test\":\"I'mtest\",\"nullNode\":null,\"base\":{\"major\":\"物联网\",\"class\":\"3\"}}";
//读取rootNode
JsonNoderootNode=mapper.readTree(s);
//通过path获取
System.out.println("通过path获取值:"+rootNode.path("name").asText());
//通过JsonPointer可以直接按照路径获取
JsonPointerpointer=JsonPointer.valueOf("/base/major");
JsonNodenode=rootNode.at(pointer);
System.out.println("通过at获取值:"+node.asText());
//通过get可以取对应的value
JsonNodeclassNode=rootNode.get("base");
System.out.println("通过get获取值:"+classNode.get("major").asText());
//获取数组的值
System.out.print("获取数组的值:");
JsonNodearrayNode2=rootNode.get("array");
for(inti=0;i
流式API
流式API是一套比较底层的API,速度快,但是使用起来特别麻烦。它主要是有两个核心类,一个是JsonGenerator,用来生成json,另一个是JsonParser,用来读取json内容。话不多说,直接上代码演示。
packagecom.xymxyg.json;
importcom.fasterxml.jackson.core.*;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.IOException;
/**
*@authorguangsheng.tang
*JsonParser和Generator的优点是速度快,缺点是写起来真的很复杂。
*/
publicclassStreamApi{
publicstaticvoidmain(String[]args)throwsIOException{
JsonFactoryfactory=newJsonFactory();
Strings="{\"id\":1,\"name\":\"小明\",\"array\":[\"1\",\"2\"],"+
"\"test\":\"I'mtest\",\"nullNode\":null,\"base\":{\"major\":\"物联网\",\"class\":\"3\"}}";
//这里就举一个比较简单的例子,Generator的用法就是一个一个write即可。
Filefile=newFile("/json.txt");
JsonGeneratorjsonGenerator=factory.createGenerator(file,JsonEncoding.UTF8);
//对象开始
jsonGenerator.writeStartObject();
//写入一个键值对
jsonGenerator.writeStringField("name","小光");
//对象结束
jsonGenerator.writeEndObject();
//关闭jsonGenerator
jsonGenerator.close();
//读取刚刚写入的json
FileInputStreaminputStream=newFileInputStream(file);
inti=0;
finalintSIZE=1024;
byte[]buf=newbyte[SIZE];
StringBuildersb=newStringBuilder();
while((i=inputStream.read(buf))!=-1){
System.out.println(newString(buf,0,i));
}
inputStream.close();
//JsonParser解析的时候,思路是把json字符串根据边界符分割为若干个JsonToken,这个JsonToken是一个枚举类型。
//下面这个小例子,可以看出JsonToken是如何划分类型的。
JsonParserparser=factory.createParser(s);
while(!parser.isClosed()){
JsonTokentoken=parser.currentToken();
System.out.println(token);
parser.nextToken();
}
JsonParserjsonParser=factory.createParser(s);
//下面是一个解析的实例
while(!jsonParser.isClosed()){
JsonTokentoken=jsonParser.nextToken();
if(JsonToken.FIELD_NAME.equals(token)){
StringcurrentName=jsonParser.currentName();
token=jsonParser.nextToken();
if("id".equals(currentName)){
System.out.println("id:"+jsonParser.getValueAsInt());
}elseif("name".equals(currentName)){
System.out.println("name:"+jsonParser.getValueAsString());
}elseif("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的几种用法的文章就介绍到这了,更多相关JackSon用法内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!