1. 程式人生 > >【objectMapper實體轉換異常】 com.fasterxml.jackson.databind.exc.MismatchedInputException

【objectMapper實體轉換異常】 com.fasterxml.jackson.databind.exc.MismatchedInputException

 

大家好,我是烤鴨:

    採坑實錄,想把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。下面兩個圖一眼就看出問題了。

http://www.bejson.com/ ​

 

總結:

知道問題在哪了,就好改了。因為獲取到前端引數的是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);
	}