場景:
調用后台接口后返回這么一串數據,不知道是在哪里又作了一次轉義,現在得到的字符串格式是:
"\"{\\\"A\\\":\\\"a\\\",\\\"B\\\":\\\"b\\\"}\""
也就是說,前后多了兩個雙引號,中間的轉義字符也被轉義了。
用System.out.println()打印出來就是
"{\"A\":\"a\",\"B\":\"b\"}"
關於JSON反序列化的坑(JAVA)
RestTemplate的getForObject()
public void test() {
// 使用方法一,不帶參數
String url = "https:/://xxx/xx/x?id=666106231640";
Data data = restTemplate.getForObject(url, InnerRes.class);
System.out.println(data);
// 使用方法二,map傳參
url = "https://://xxx/xx/x?id={id}";
Map<String, Object> params = new HashMap<>();
params.put("id", 123);
Data = restTemplate.getForObject(url, Data.class, params);
System.out.println(data);
這個方法在大多數情況下都沒問題,還有postForObject()等好用的方法可以用
但是如果返回的值很奇怪,不是嚴格的JSON,那會報錯了,比如遇到一個返回的JSON,內部嵌套的內容有的在大括號外還多了雙引號,有的沒有,比如:
{
"result":"{"name":"mike","addr":"beijing"}",
"code":"200",
"error":""
}
也不懂對面接口為什么要這么做,也可能是本人見得比較少,不過也沒辦法了,只能當字符串來處理了
先使用
String str = restTemplate.getForObject(url, String.class);
然后處理字符串,先替換掉轉義的""和大括號兩邊的雙引號,假設取到下面這串str
str= "{\"result\":\"{\"name\":\"mike\",\"addr\":\"beijing\"}\",\"code\":\"200\",\"error\":\"\"}";
str = str.replace("\\","");
str = str.replace("\"{","{");
str = str.replace("}\"","}");
然后使用ObjectMapper的readValue()轉化為對象
// 創建ObjectMapper ObjectMapper mapper = new ObjectMapper(); // 下面這步的作用就是忽略json中存在,但java中的目標類中不存在的字段,否則會反序列化報錯 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); MyObj obj = mapper.readValue(str,MyObj);
如果MyObj嵌套多個內部類的話,不能夠越級訪問,如:
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class test{
private String one;
private String two;
private Mytest mytest;
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Mytest{
private String mytest1;
private String mytest2;
}
}
JSON中存在
{
"one": "valone",
"two": "valtwo",
"mytest": {
"mytest1": "t1",
"mytest2": "t2"
}
}
想要獲取mytest1的內容,就要創建一個Mytest的內部類,然后才會匹配
最好要把里面各個字段都設為public static,如果是private的話,mapper.readValue()返回的對應字段是null,具體原因未知…
猜想,可能是與ObjectMapper的反射機制有關,private就訪問不到了,但是后來發現我有一個三層的內部類,外面兩層用private的字段是可以獲取到的,第三層后就是null了,
必須改成public才能獲取到
我使用了lombok,不知道會不會於此有關,希望有知道原因的大佬希望能指點
