【objectMapper實體轉換異常】 com.fasterxml.jackson.databind.exc.MismatchedInputException
阿新 • • 發佈:2018-12-29
大家好,我是烤鴨:
採坑實錄,想把json資料直接轉成物件,其中有個屬性是list<T>:
異常 1
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token
這個是獲取到前端傳遞的引數:
String str = "{\"vv\":\"1.6.6\",\"authCode\":\"1111\",\"appid\":\"2\",\"apptype\":\"2\",\"userPhone\":\"11111111111\",\"latitude\":\"39.92183\",\"phoneInfo\":\"[{\"name\":\"於金坡\",\"mobile\":\"13102039019\"}]\",\"time\":\"1540970481\",\"longitude\":\"116.28041\"}";
ObjectMapper objectMapper = new ObjectMapper();
UserInfoRequest userInfoRequest = objectMapper.readValue(str, UserInfoRequest.class);
System.out.println(userInfoRequest);
報上面的錯。UserInfoRequest 就不貼了,屬性都是能對應上的。其中有個List<phoneInfo>屬性。
查了一些資料。改成下面的程式碼:
String str = "{\"vv\":\"1.6.6\",\"authCode\":\"1111\",\"appid\":\"2\",\"apptype\":\"2\",\"userPhone\":\"11111111111\",\"latitude\":\"39.92183\",\"phoneInfo\":\"[{\"name\":\"於金坡\",\"mobile\":\"13102039019\"}]\",\"time\":\"1540970481\",\"longitude\":\"116.28041\"}"; ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true) ; objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); UserInfoRequest userInfoRequest = objectMapper.readValue(str, UserInfoRequest.class); System.out.println(userInfoRequest);
就報異常2的錯。
異常 2
com.fasterxml.jackson.databind.exc.MismatchedInputException:
Cannot construct instance of `com.xxx.xxx` (although at least one Creator exists):
no String-argument constructor/factory method to deserialize from String value
因為自己測試的時候沒有這個問題,就仔細對比了測試的時候str和前端的傳值。
錯誤的:
String str = "{\"vv\":\"1.6.6\",\"authCode\":\"1111\",\"appid\":\"2\",\"apptype\":\"2\",\"userPhone\":\"11111111111\",\"latitude\":\"39.92183\",\"phoneInfo\":\"[{\"name\":\"於金坡\",\"mobile\":\"13102039019\"}]\",\"time\":\"1540970481\",\"longitude\":\"116.28041\"}";
正確的:
String str = "{\"vv\":\"1.6.6\",\"authCode\":\"1111\",\"appid\":\"2\",\"apptype\":\"2\",\"userPhone\":\"11111111111\",\"latitude\":\"39.92184\",\"phoneInfo\":[{\"name\":\"張三\",\"mobile\":\"15899996666\"},{\"name\":\"李四\",\"mobile\":\"138556688\"},{\"name\":\"王五\",\"mobile\":\"13855661118\"}],\"time\":\"1540969882\",\"longitude\":\"116.28033\"}";
關鍵就在於 phoneInfo 後面跟的是字串(""包括住的)還是 陣列後者list物件。如果是字串就報這個錯了。
\"phoneInfo\":\"[{\"name\":\"於金坡\",\"mobile\":\"13102039019\"}]\"
簡單一點的方式: 把你的字串去這個網站看一下是否是標準json。下面兩個圖一眼就看出問題了。
總結:
知道問題在哪了,就好改了。因為獲取到前端引數的是v=1&x=2&b=3這種形式的。
解析引數的時候,放到map<String,String>中,最後把map轉成json字串的格式。
沒有考慮到前端傳遞的是list這種的格式,判斷如果是 [ ]這種的話,就轉成jsonArray放到map。
map的格式是 <String,Object>。程式碼如下:(pheader 是解密後的引數,v=1&x=2&b=3這種形式)
public static String getParam(String cipher)throws Exception{
Map<String, Object> params = new HashMap<String,Object>();
//解析引數
String pheader = "";
pheader = AESUtil.decrypt(PpsConfig.getString("appkey"), cipher);
String[] pArr = pheader.split("&");
for (int i = 0; i < pArr.length; i++) {
String[] tmp = pArr[i].split("=");
if (tmp.length == 2) {
//說明是陣列
if(tmp[1].startsWith("[")){
JSONArray array = JSONArray.parseArray(tmp[1]);
params.put(tmp[0], array);
}else {
params.put(tmp[0], tmp[1]);
}
}else{
params.put(tmp[0], "");
}
}
return JSONObject.toJSONString(params);
}