复杂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}

原文地址:https://www.cnblogs.com/researcher/p/7298579.html