问题描述:与第三方公司对接接口,第三方提供了一个接口文档,里面有一些字段信息,很显然我们接收方一般根据接收过来的json数据转化为一个实体对象接收即可,但是有个问题存在,就是第三方公司后续版本针对此接口增加字段,如果我们接收的实体对象没有定义新增的字段,那么json转对象就会报错。
比如:json为
String json = "{\"pno\":\"test\",\"tn\":\"757C3F0B0291******E99E9855F\",\"ts\":\"20171124125469456\",\"sn\":\"14B5890BBC******A6D88A077D89DA51\",\"ve\":\"1.0\",\"dataItems\":[{\"itemId\":\"435FA12F3C4747B0BA48E945868FC420\",\"parkName\":\"测试车场\",\"parkCode\":\"00000\"}]}";
转化的实体类为
/**
* 通用请求参数
* @author zls
*
* @param <T>
*/
public class JhtCommParam<T> {
/**
* 平台编号
*/
private String pno;
/**
* 令牌
*/
private String tn;
/**
* 请求时间
*/
private String ts;
/**
* 签名
*/
private String sn;
/**
* 版本号
*/
private String ve;
/**
* 业务参数
*/
private List<T> dataItems;//省略get/set}
T为json里dataItems里面的字段对应的类,例如我们这里的json里面的dataItems里面的字段对应的实体类为:
public class JhtRecevEnter {
/**
* 记录id
*/
private String itemId;
/**
* 停车场名称
*/
private String parkName;
/**
* 停车场编号
*/
private String parkCode;
//省略get/set
}
此时调用json转为对象的方法:
JhtCommParam<JhtRecevEnter> ss = JsonUtils.json2Object(json, JhtCommParam.class);
如果后期json里面的dataItems里面的字段新增了,也就是第三方公司针对这个接口新加了字段,json2Object方法不能忽略新增字段属性,此时取到的dataItems属性的值就多了,超出了JhtRecevEnter.java定义的属性,如果此时获取JhtRecevEnter对象时就会报错:
如:
List<JhtRecevEnter> dataItems = ss.getDataItems();
for (JhtRecevEnter jhtRecevEnter : dataItems) {
//略
}
报错信息如下:
Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.XXXX.park.model.jht.JhtRecevEnter
josn2Object()方法如下:
public static <T> T json2Object(String json, Class<T> cls) {
T result = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
result = objectMapper.readValue(json, cls);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
解决方案:针对此类问题,可以使用以下方法:
JSONObject jsonObj =JSONObject.fromObject(json);
String dataItems = jsonObj.getString("dataItems");
List<JhtRecevEnter> list = (List<JhtRecevEnter>) JSONArray.toCollection(JSONArray.fromObject(dataItems),
JhtRecevEnter.class);
此方法如果dataItems里面的字段新增了,而转化的类JhtRecevEnter.java里面没有定义,可以自动属性忽略,这样就做到兼容了,有时第三方新增字段可能是为了其他客户提供的,并不是针对本公司的业务,所以加了字段,如果我们的代码没有做兼容的话,后果不堪设想。