復雜JSON反序列化為類對象


有3種常用的反序列化庫,gson和fastjson都很棒,json-lib有很大的局限性不推薦使用!

1. net.sf.json(json-lib)

只能用於解析簡單的JSON,稍微復雜點的例如,類里面有含有List屬性,這個沒有問題(在0.9這個版本不行,但2.3可以,應該是bug修復了),但是List屬性中類中再含有List就不支持了,言外之意,類中含有List只能一層,再深就會報如下錯誤:

net.sf.json.JSONException: java.lang.NoSuchMethodException: Unknown property 

代碼如下:

Object object = restTemplate.getForObject(interfaceUrl, Object.class);
net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(object);
Map<String, Class> classMap = new HashMap<String, Class>();
classMap.put("productInfoList", ProductInfoList.class);
CobraProductInfoListDto j = (CobraProductInfoListDto) net.sf.json.JSONObject.toBean(json,
CobraProductInfoListDto.class, classMap);

2.gson

String interfaceUrl = globalSettingsMapper.getValueByKey(Constant.Product.interfaceUrl);
RestTemplate restTemplate = new RestTemplate();
Object object = restTemplate.getForObject(interfaceUrl, Object.class);
Gson gs= new Gson();
String json = gs.toJson(object);
CobraProductInfoListDto j = gs.fromJson(json, CobraProductInfoListDto.class);
System.out.println(j.getProductInfoList().get(0).getPLogo().getLogoName());

3.fastjson

String interfaceUrl = globalSettingsMapper.getValueByKey(Constant.Product.interfaceUrl);
RestTemplate restTemplate = new RestTemplate();
Object object = restTemplate.getForObject(interfaceUrl, Object.class);
Gson gs = new Gson();
String json = gs.toJson(object);
CobraProductInfoListDto j =JSON.parseObject(json, CobraProductInfoListDto.class);
String rateType = j.getProductInfoList().get(1).getPInterest().getCurrency();

另外推薦一個非常棒的根據Json生成Java/C#實體類的工具:http://tool.chinaz.com/tools/json2entity.aspx,很是方便!但是注意生成的代碼可能需要優化,比如有些重復的類可以合為一個,數據類型上需要把DateTime改為String,因為轉換時存在數據的特例,可能某些字段需要由int改為double

在反序列化時,在如何定義類文件方式上,如下2種都可以,根據實際情況選取

CobraProductInfoListDto j = JSON.parseObject(json, CobraProductInfoListDto.class);  //優勢:訪問方便,所有的全封裝在一個類中,缺點是可能會多定義一些類

Map<String, List<ProductInfoList>> k = JSON.parseObject(json,
new TypeReference<Map<String, List<ProductInfoList>>>() {
}); //優勢:和上面的方式比較起來可以少定義一些類文件

--------------------------------------------------------------

Json轉換的時候切記:收尾不能包含引號,否則會報錯,例子:

正確: {"name":"yuanyuan","description":"Randy chinese name"}

錯誤: "{"name":"yuanyuan","description":"Randy chinese name"}"

JSON字符串前面用引號包含,fastjson/gson所報錯誤的區別,感覺阿里的更易懂,google也不不能算錯,但是理解起來費勁
com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 0
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $

截取字符串收尾字符,例如去引號:.substring(1,json.length()-1 )

轉義工具類:從StringEscapeUtils.escapeJava/unescapeJava

-----------------------------------------

發現google的gson在轉換日期類型的時候會報錯,但用阿里的fastjson就沒有問題

Failed to parse date ["1454032939000']: Invalid time zone indicator '3'

期待的結果是://CST是中國標准時

Fri Jan 29 10:02:19 CST 2016

---------------------------------------------

反序列化json報錯如下:

com.alibaba.fastjson.JSONException: illegal identifier : \pos 1, json : {\"appStatus\":\"MADELOAN|MADELOANCOMPLETED\",\"category\":\"CREDIT_LOAN\",\"changedTime\":1454032939000,\"cobraAppStatus\":\"MADELOAN\",\"createdTime\":1454032581000,\"id\":64}

解決辦法是把下面多余的轉義字符給去掉:StringEscapeUtils.unescapeJava(String str)

{\"appStatus\":\"MADELOAN|MADELOANCOMPLETED\",\"category\":\"CREDIT_LOAN\",\"changedTime\":1454032939000,\"cobraAppStatus\":\"MADELOAN\",\"createdTime\":1454032581000,\"id\":64}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM