這篇文章主要介紹了Jackson的用法實例分析,用於處理Java的json格式數據很是實用,須要的朋友能夠參考下php
通俗的來講,Jackson是一個 Java 用來處理 JSON 格式數據的類庫,其性能很是好。本文就來針對Jackson的用法作一個較爲詳細的實例分析。具體以下:html
1、簡介java
Jackson具備比較高的序列化和反序列化效率,據測試,不管是哪一種形式的轉換,Jackson > Gson > Json-lib,並且Jackson的處理能力甚至高出Json-lib近10倍左右,且正確性也十分高。相比之下,Json-lib彷佛已經中止更新,最新的版本也是基於JDK15,而Jackson的社區則較爲活躍。
下面,結合實例來對Jackson的用法進行簡單介紹。node
2、使用nginx
Jackson提供了不少類和方法,而在序列化和反序列化中使用的最多的類則是ObjectMapper這個類,此類比較相似於Json-lib中JsonObject和ArrayObject。此類中提供了readTree(),readValue(),writeValueAsString()等方法用於轉換。具體關於此類的說明文檔地址是:http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html。apache
爲了不重複描述,下面中所涉及到的objectMapper均是來至於ObjectMapper objectMapper = new ObjectMapper()。下面將按照序列化和反序列化兩個方面來簡單介紹用法。json
1.序列化數組
① 對java自帶類進行序列化ruby
測試例子
bash
List list=new ArrayList(); list.add(1); list.add(2); list.add(3);
實現序列化:
String teststringlist=objectMapper.writeValueAsString(list);
System.out.println(teststringlist);
在控制檯輸出的結果是:
[1,2,3]
結論:
Jackson對通常類型的序列化是能簡單實現的。
②對自定義類的序列化
測試例子:
public class student { private int age=10; private String name="hhh"; public String[] list={"hao","haouhao","keyi"}; public Date time=new Date(); public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
爲使例子更具備通用性,此類中包含了值類型int,引用類型String,String[],還包含了日期類型Date。
實現序列化
student st=new student();
String teststringstu=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 ]-compliant notation, 輸出相似以下格式的時間: "1970-01-01T00:00:00.000+0000"。
固然,也能夠自定義輸出的時間格式。
自定義時間格式的實現
例子還採用上面所介紹的student類。
student st=new student();
java.text.DateFormat myFormat = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); objectMapper.getSerializationConfig().setDateFormat(myFormat); String teststringstu=objectMapper.writeValueAsString(st); System.out.println(teststringstu);
控制檯上輸出的記過是:
{"list":["hao","haouhao","keyi"],"time":"2013-08-02 03:48:20","name":"hhh","age":10}
結論:
可見時間輸出格式變成了咱們想要的了。在Jackson中定義時間輸出格式的方法比在Json-lib中對時間格式的定義簡便不少。
④ 另外一種序列化方法
實現序列化
所用例子依然是以前的student類。
student st=new student();
JsonGenerator jsonGenerator = 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(String content, Class<testJsonClass> valueType)方法。此方法須要輸入Json串以及對應的須要填充的類的Class,返回填充後的類。
將Json串解析到自定義類中
當Json串爲:
String test1="{"objectID":357,"geoPoints":[{"x":504604.59802246094,"y":305569.9150390625}]}"
的時候。
首先自定義一個類:
public class testJsonClass { public int objectID; public List geoPoints=new ArrayList(); }
而後利用下面段代碼將Json反序列化到此類中:
testJsonClass testClass= objectMapper.readValue(test1, testJsonClass.class);
利用
System.out.println(testClass.objectID);
System.out.println(testClass.geoPoints)
能夠在控制檯上看到輸出的值爲:
357 [{x=504604.59802246094, y=305569.9150390625}]
將Json串反序列化到系統自帶的類中
當Json串是
String json = "{"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類來實現。
測試例子
String test="{"results":[{"objectID":357,"geoPoints":[{"x":504604.59802246094,"y":305569.9150390625}]},{"objectID":358,"geoPoints":[{"x":504602.2680053711,"y":305554.43603515625}]}]}";
此Json串比較複雜,包含了嵌套數組的形式,具備通用性。
實現反序列化
JsonNode node= objectMapper.readTree(test); //將Json串以樹狀結構讀入內存
JsonNode contents=node.get("results");//獲得results這個節點下的信息 for(int i=0;i<contents.size();i++) //遍歷results下的信息,size()函數能夠得節點所包含的的信息的個數,相似於數組的長度 { System.out.println(contents.get(i).get("objectID").getIntValue()); //讀取節點下的某個子節點的值 JsonNode geoNumber=contents.get(i).get("geoPoints"); for(int j=0;j<geoNumber.size();j++) //循環遍歷子節點下的信息 { System.out.println(geoNumber.get(j).get("x").getDoubleValue()+" "+geoNumber.get(j).get("y").getDoubleValue()); } }
在控制檯下輸出的結果是:
357 504604.59802246094 305569.9150390625 358 504602.2680053711 305554.43603515625
結論:
此方法相似於XML解析中的DOM方式解析,其好處是結構明細,便於提取想要的信息。固然,其缺點也和此方法同樣:耗時費空間。
三.總結
Jackson關於Json的操做主要如上所示,其方法使用起來很便利,並且也很靈活,即提供了一次性完成的操做,也提供了能夠按需讀取信息的操做。而且Jackson的功能很齊全,能夠對序列化和反序列化進行多種細節的控制,例如註解功能和對於Hibernate的延遲注入功能以及設置時間格式功能等,由於這些功能目前不太須要,因此仔細研究留待之後。同時,Jackson還支持對XML的一系列序列化和反序列化的操做,其思路與解析Json的大體相同。對於Jackson目前的缺點,網上有人測試所比Json-lib更佔內存一些。而利用空間換時間,通常是值得的。