Jackson的用法实例分析
通俗的来说,Jackson是一个Java用来处理JSON格式数据的类库,其性能非常好。本文就来针对Jackson的用法做一个较为详细的实例分析。具体如下:
一、简介
Jackson具有比较高的序列化和反序列化效率,据测试,无论是哪种形式的转换,Jackson>Gson>Json-lib,而且
下面,结合实例来对Jackson的用法进行简单介绍。
二、使用
Jackson提供了很多类和方法,而在序列化和反序列化中使用的最多的类则是ObjectMapper这个类,此类比较类似于Json-lib中JsonObject和ArrayObject。此类中提供了readTree(),readValue(),writeValueAsString()等方法用于转换。具体关于此类的说明文档地址是:http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html。
为了避免重复描述,下面中所涉及到的objectMapper均是来至于ObjectMapperobjectMapper=newObjectMapper()。下面将按照序列化和反序列化两个方面来简单介绍用法。
1.序列化
①对java自带类进行序列化
测试例子
Listlist=newArrayList(); list.add(1); list.add(2); list.add(3);
实现序列化:
Stringteststringlist=objectMapper.writeValueAsString(list); System.out.println(teststringlist);
在控制台输出的结果是:
[1,2,3]
结论:
②对自定义类的序列化
测试例子:
publicclassstudent{ privateintage=10; privateStringname="hhh"; publicString[]list={"hao","haouhao","keyi"}; publicDatetime=newDate(); publicintgetAge(){ returnage; } publicvoidsetAge(intage){ this.age=age; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } }
为使例子更具有通用性,此类中包含了值类型int,引用类型String,String[],还包含了日期类型Date。
实现序列化
studentst=newstudent(); Stringteststringstu=objectMapper.writeValueAsString(st); System.out.println(teststringstu);
在控制台输出的结果是:
{"list":["hao","haouhao","keyi"],"time":1375429228382,"name":"hhh","age":10}
结论:
通过输出,可见转换得到的Json串是符合格式的。但是,时间的表示有点不符合标准。下面将介绍对时间格式的修改。
③对时间格式的定义
Jackson有自己的默认时间格式,即timestamps形式,其效果即如上结果所显示的(例如:1375429228382)。如果想设置此格式是无效,通过
objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,false)
便可设置,这样将使时间生成使用所谓的使用[ISO-8601]-compliantnotation,输出类似如下格式的时间:"1970-01-01T00:00:00.000+0000"。
当然,也可以自定义输出的时间格式。
自定义时间格式的实现
例子还采用上面所介绍的student类。
studentst=newstudent(); java.text.DateFormatmyFormat=newjava.text.SimpleDateFormat("yyyy-MM-ddhh:mm:ss"); objectMapper.getSerializationConfig().setDateFormat(myFormat); Stringteststringstu=objectMapper.writeValueAsString(st); System.out.println(teststringstu);
控制台上输出的记过是:
{"list":["hao","haouhao","keyi"],"time":"2013-08-0203:48:20","name":"hhh","age":10}
结论:
可见时间输出格式变成了我们想要的了。
④另一种序列化方法
实现序列化
所用例子依然是之前的student类。
studentst=newstudent(); JsonGeneratorjsonGenerator=objectMapper.getJsonFactory().createJsonGenerator(System.out,JsonEncoding.UTF8); jsonGenerator.writeObject(st); System.out.println();
控制台上的输出结果是:
{"list":["hao","haouhao","keyi"],"time":1375429228382,"name":"hhh","age":10}
结论:
此方法同样可以得到上面方法的值。但是注意此方法中的这个函数:createJsonGenerator(),它需要两个参数,一个是OutputStream类型参数,一个是JsonEncoding类型参数。通过这两个参数,我们可以了解到,此方法不仅可以将Json直接写入网络流,还可以将Json写入文件流或者内存流。所以用途更广。
2.反序列化
①一次性反序列化
此方法中主要利用ObjectMapper提供的<testJsonClass>readValue(Stringcontent,Class<testJsonClass>valueType)方法。此方法需要输入Json串以及对应的需要填充的类的Class,返回填充后的类。
将Json串解析到自定义类中
当Json串为:
Stringtest1="{"objectID":357,"geoPoints":[{"x":504604.59802246094,"y":305569.9150390625}]}"
的时候。
首先自定义一个类:
publicclasstestJsonClass { publicintobjectID; publicListgeoPoints=newArrayList(); }
然后利用下面段代码将Json反序列化到此类中:
testJsonClasstestClass=objectMapper.readValue(test1,testJsonClass.class);
利用
System.out.println(testClass.objectID); System.out.println(testClass.geoPoints)
可以在控制台上看到输出的值为:
357 [{x=504604.59802246094,y=305569.9150390625}]
将Json串反序列化到系统自带的类中
当Json串是
Stringjson="{"error":0,"data":{"name":"ABC","age":20,"phone":{"home":"abc","mobile":"def"},"friends":[{"name":"DEF","phone":{"home":"hij","mobile":"klm"}},{"name":"GHI","phone":{"home":"nop","mobile":"qrs"}}]},"other":{"nickname":[]}}"。
用系统自带的Map定义一个变量:Map<String,Map<String,Object>> maps。然后利用maps=objectMapper.readValue(json,Map.class)便可将Json反序列化到变量maps中。
通过
System.out.println(maps.get("error")); System.out.println((Object)(maps.get("data").get("phone")))
可在控制台中得到下面的结果:
0 {home=abc,mobile=def}
②渐次反序列化
此方法更灵活,可以只将用户感兴趣的Json串信息值提取出来。主要利用ObjectMapper提供的readTree和Jackson提供的JsonNode类来实现。
测试例子
Stringtest="{"results":[{"objectID":357,"geoPoints":[{"x":504604.59802246094,"y":305569.9150390625}]},{"objectID":358,"geoPoints":[{"x":504602.2680053711,"y":305554.43603515625}]}]}";
此Json串比较复杂,包含了嵌套数组的形式,具有通用性。
实现反序列化
JsonNodenode=objectMapper.readTree(test);//将Json串以树状结构读入内存 JsonNodecontents=node.get("results");//得到results这个节点下的信息 for(inti=0;i<contents.size();i++)//遍历results下的信息,size()函数可以得节点所包含的的信息的个数,类似于数组的长度 { System.out.println(contents.get(i).get("objectID").getIntValue());//读取节点下的某个子节点的值 JsonNodegeoNumber=contents.get(i).get("geoPoints"); for(intj=0;j<geoNumber.size();j++)//循环遍历子节点下的信息 { System.out.println(geoNumber.get(j).get("x").getDoubleValue()+""+geoNumber.get(j).get("y").getDoubleValue()); } }
在控制台下输出的结果是:
357 504604.59802246094305569.9150390625 358 504602.2680053711305554.43603515625
结论:
此方法类似于XML解析中的DOM方式解析,其好处是结构明细,便于提取想要的信息。当然,其缺点也和此方法一样:耗时费空间。
三.总结
Jackson关于Json的操作主要如上所示,其方法使用起来很便利,而且也很灵活,即提供了一次性完成的操作,也提供了可以按需读取信息的操作。并且Jackson的功能很齐全,可以对序列化和反序列化进行多种细节的控制,例如注解功能和对于Hibernate的延迟注入功能以及设置时间格式功能等,因为这些功能目前不太需要,所以仔细研究留待以后。同时,Jackson还支持对XML的一系列序列化和反序列化的操作,其思路与解析Json的大致相同。
对于Jackson目前的缺点,网上有人测试所比Json-lib更占内存一些。而利用空间换时间,一般是值得的。
相关文章
- jwplayer html插件,jQuery插件JWPlayer视频播放器用法实例分析
- 【Java 代码实例 14】BeanUtils用法详解,附源码分析
- STM32状态机编程实例——全自动洗衣机(上)
- 随机梯度下降法概述与实例分析_梯度下降法推导
- Qt QListWidget和QToolButton用法详解(实例分析)
- Qt QTreeWidget和QDockWidget用法完全攻略(实例分析)
- Linux多线程编程实例分析(linux线程例子)
- 分析Linux共享内存实例深度分析(linux共享内存实例)
- Linux Sed实例分析:轻松掌握字符串处理技巧(linuxsed实例)
- MySQL中NOT操作的使用方法与实例分析(mysql中not)
- MySQL内联合查询优化实例三表联合查询(mysql三表内联合查询)
- 分析Redis缓存技术现实应用实例分析(redis缓存技术 实例)
- 实例学习mssql存储过程分析
- jQuery与ExtJS之选择实例分析
- Js(JavaScript)中,弹出是或否的选择框示例(confirm用法的实例分析)
- C++中引用(&)的用法与应用实例分析
- JQuery验证jsp页面属性是否为空(实例代码)
- jQuerytoggleClass应用实例(附效果图)
- C#中参数个数可变的方法实例分析
- gearman的安装启动及pythonAPI使用实例
- C#使用listView增删操作实例
- Objective-C中常用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect实例分析
- C++结构体用法实例分析
- Android入门之AlertDialog用法实例分析
- javascript中sort()的用法实例分析
- javascript中cookie对象用法实例分析
- javascript中AJAX用法实例分析
- C#中is和as用法实例分析
- php的XML文件解释类应用实例