fasterxml jackson反序列化時(shí)對(duì)于非靜態(tài)內(nèi)部類報(bào)錯(cuò)問(wèn)題及解決
fasterxml jackson反序列化時(shí)對(duì)于非靜態(tài)內(nèi)部類報(bào)錯(cuò)
java中通常使用jackson、fastjson兩個(gè)庫(kù)來(lái)處理json。后者的api使用起來(lái)比較方便,但是安全漏洞太多了。
在使用jackson反序列化json字符串時(shí),遇到了一個(gè)問(wèn)題:
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `json.TransferResp$TransforData` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor
很多文章沒(méi)有解釋清楚,本文做了一個(gè)實(shí)驗(yàn)。
對(duì)于嵌套結(jié)構(gòu),定義了一個(gè)包含內(nèi)部類的java類來(lái)接收,如果這個(gè)復(fù)雜結(jié)構(gòu)是一個(gè)數(shù)組形式,那么反序列化時(shí)會(huì)報(bào)上面錯(cuò)誤。
實(shí)驗(yàn)一
1)java實(shí)體類
@Data public class TransforResponse { private Integer code; private Map<String, String> defaultData; private TransforData data; @Data public static class TransforData{ private Long encyId; private int score; private Map<String, String> other; } }
2)測(cè)試
private static ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) throws Exception { String jsonStr = serialization(); //{\"code\":200,\"data\":{\"encyId\":123,\"other\":{\"a\":\"test\"},\"score\":5}} deSerialization(jsonStr); //TransferResp(code=200, data=TransferResp.TransforData(encyId=123, score=5, other={a=test})) System.out.println("----------"); String jsonStr2 = serialization2(); //{\"code\":200,\"data\":{\"encyId\":123,\"other\":{\"a\":\"test\"},\"score\":5}} deSerialization2(jsonStr2); //TransferResp(code=200, data=TransferResp.TransforData(encyId=123, score=5, other={a=test})) } private static TransferResp createObj() { TransferResp tr = new TransferResp(); TransforData transforData = tr.new TransforData(); transforData.setEncyId(123L); transforData.setScore(5); Map<String, String> hashMap = new HashMap<>(1); hashMap.put("a", "test"); transforData.setOther(hashMap); tr.setCode(200); tr.setData(transforData); return tr; } private static String serialization() { TransferResp tr = createObj(); String jsonString = JSONObject.toJSONString(tr); System.out.println(jsonString); return jsonString; } private static void deSerialization(String jsonStr) { TransferResp parseObject = JSONObject.parseObject(jsonStr, TransferResp.class); System.out.println(parseObject.toString()); } private static String serialization2() throws JsonProcessingException { TransferResp tr = createObj(); String jsonString = objectMapper.writeValueAsString(tr); System.out.println(jsonString); return jsonString; } private static void deSerialization2(String jsonStr) throws JsonParseException, JsonMappingException, IOException { TransferResp parseObject = objectMapper.readValue(jsonStr, TransferResp.class); System.out.println(parseObject.toString()); }
運(yùn)行后正常。
實(shí)驗(yàn)二
1)java實(shí)體類
@Data public class TransferResp { private Integer code; private List<TransforData> data; @Data public class TransforData{ private Long encyId; private Integer score; private Map<String, String> other; } }
2)測(cè)試
private static ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) throws Exception { String jsonStr = serialization(); //{"code":200,"data":[{"encyId":123,"other":{"a":"test"},"score":5}]} deSerialization(jsonStr); //TransferResp(code=200, data=[TransferResp.TransforData(encyId=123, score=5, other={a=test})]) System.out.println("----------"); String jsonStr2 = serialization2(); //{"code":200,"data":[{"encyId":123,"score":5,"other":{"a":"test"}}]} deSerialization2(jsonStr2); //error } private static TransferResp createObj() { TransferResp tr = new TransferResp(); TransforData transforData = tr.new TransforData(); transforData.setEncyId(123L); transforData.setScore(5); Map<String, String> hashMap = new HashMap<>(1); hashMap.put("a", "test"); transforData.setOther(hashMap); List<TransforData> list = new ArrayList<>(); list.add(transforData); tr.setCode(200); tr.setData(list); return tr; } private static String serialization() { TransferResp tr = createObj(); String jsonString = JSONObject.toJSONString(tr); System.out.println(jsonString); return jsonString; } private static void deSerialization(String jsonStr) { TransferResp parseObject = JSONObject.parseObject(jsonStr, TransferResp.class); System.out.println(parseObject.toString()); } private static String serialization2() throws JsonProcessingException { TransferResp tr = createObj(); String jsonString = objectMapper.writeValueAsString(tr); System.out.println(jsonString); return jsonString; } private static void deSerialization2(String jsonStr) throws JsonParseException, JsonMappingException, IOException { TransferResp parseObject = objectMapper.readValue(jsonStr, TransferResp.class); System.out.println(parseObject.toString()); }
運(yùn)行時(shí)會(huì)報(bào)錯(cuò):
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `json.TransferResp$TransforData` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor
3)解決方法
A、使用靜態(tài)內(nèi)部類
@Data public class TransferResp { private Integer code; private List<TransforData> data; @Data public static class TransforData{ private Long encyId; private Integer score; private Map<String, String> other; } }
B)將內(nèi)部類定義在一個(gè)單獨(dú)的類文件中。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中Thread和Runnable創(chuàng)建線程的方式對(duì)比
本文主要介紹了Java中Thread和Runnable創(chuàng)建線程的方式對(duì)比,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Java 實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)框架詳細(xì)代碼
這篇文章主要介紹了Java 實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)框架,主要是用于爬取網(wǎng)絡(luò)上一些內(nèi)容,比如超鏈接之類的,需要的朋友可以參考下面文章內(nèi)容2021-09-09SpringBoot詳解實(shí)現(xiàn)自定義異常處理頁(yè)面方法
SpringBoot是Spring全家桶的成員之一,是一種整合Spring技術(shù)棧的方式(或者說(shuō)是框架),同時(shí)也是簡(jiǎn)化Spring的一種快速開(kāi)發(fā)的腳手架2022-06-06Java實(shí)現(xiàn)的Excel列號(hào)數(shù)字與字母互相轉(zhuǎn)換功能
這篇文章主要介紹了Java實(shí)現(xiàn)的Excel列號(hào)數(shù)字與字母互相轉(zhuǎn)換功能,涉及java針對(duì)Excel相關(guān)數(shù)值與字符串操作技巧,需要的朋友可以參考下2018-03-03IntelliJ IDEA修改新建文件自動(dòng)生成注釋的user名
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA修改新建文件自動(dòng)生成注釋的user名,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10