欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解決RestTemplate反序列化嵌套對象的問題

 更新時間:2022年11月17日 15:03:31   作者:小樓夜聽雨QAQ  
這篇文章主要介紹了解決RestTemplate反序列化嵌套對象的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

RestTemplate反序列化嵌套對象

假設某個接口返回的數(shù)據(jù)如下格式

{
  "msg" : "ok",
  "code" : 0,
  "data" : {
    "id" : 1,
    "tasks" : [ {
      "id" : 300,
      "nodeId" : 801,
      "status" : 3,
      "actionName" : "pick",
      "wcsProcessName" : "rgv"
    }, {
      "id" : 301,
      "nodeId" : 720,
      "status" : 3,
      "actionName" : "move",
      "wcsProcessName" : "rgv"
    }, {
      "id" : 302,
      "nodeId" : 720,
      "status" : 3,
      "actionName" : "checker",
      "wcsProcessName" : "checker"
    }, {
      "id" : 303,
      "nodeId" : 801,
      "status" : 3,
      "actionName" : "checker",
      "wcsProcessName" : "checker"
    } ],
    "status" : 3
  }
}

仿寫一個測試接口,用于返回這種格式的數(shù)據(jù)

    @PostMapping("/aiot/task/info")
    public R queryTask(@RequestBody Map map) {
        Integer taskId = (Integer) map.get("taskId");
        Map res = new HashMap();
        res.put("id", taskId);
        res.put("tasks", Arrays.asList(
                new TaskProcess(300, 801, 3, "pick", "rgv"),
                new TaskProcess(301, 720, 3, "move", "rgv"),
                new TaskProcess(302, 720, 3, "checker", "checker"),
                new TaskProcess(303, 801, 3, "checker", "checker")
                ));
 
        res.put("status", 3);
        return R.ok(res);
    }

客戶端的代碼如下

    @Test
    public void test() {
 
        HashMap<String, Integer> map = new HashMap<>();
        map.put("taskId", 1);
        ResponseEntity<WcsR> wcsRResponseEntity = restTemplate.postForEntity("http://localhost:8081/aiot/task/info", map, WcsR.class);
        WcsR wcsR = wcsRResponseEntity.getBody();
    }

方案一

一般情況下,我們會創(chuàng)建一個與服務端一致的通用值返回對象。

@Data
public class WcsR {
    private String msg;
 
    private Integer code;
 
    private Object data;
}

data的類型無法確定。

在客戶端不知道類型的情況下,我們看下data會被解析成什么

    @Test
    public void test() {
 
        HashMap<String, Integer> map = new HashMap<>();
        map.put("taskId", 1);
        ResponseEntity<WcsR> wcsRResponseEntity = restTemplate.postForEntity("http://localhost:8081/aiot/task/info", map, WcsR.class);
        WcsR wcsR = wcsRResponseEntity.getBody();
        System.out.println(wcsR.getData().getClass().getName());
    }

運行結果

看后臺的代碼我們可以知道,data是一個對象,里面有三個變量,id(整型),tasks(對象數(shù)組),status(整型)。

下面嘗試獲取這些成員變量

    @Test
    public void test() {
 
        HashMap<String, Integer> map = new HashMap<>();
        map.put("taskId", 1);
        ResponseEntity<WcsR> wcsRResponseEntity = restTemplate.postForEntity("http://localhost:8081/aiot/task/info", map, WcsR.class);
        WcsR wcsR = wcsRResponseEntity.getBody();
        System.out.println(wcsR.getData().getClass().getName());
        LinkedHashMap dataMap = (LinkedHashMap) wcsR.getData();
        System.out.println("id:   " + dataMap.get("id").getClass().getName());
        System.out.println("tasks: " + dataMap.get("tasks").getClass().getName());
        System.out.println("status: " + dataMap.get("status").getClass().getName());
    }

結果

可以看到,數(shù)組被解析成了Arraylist, 基本類型被解析成對應的包裝類型。

數(shù)組里面還是個對象,還會繼續(xù)幫我們解析嗎?測試代碼如下

    @Test
    public void test() {
 
        HashMap<String, Integer> map = new HashMap<>();
        map.put("taskId", 1);
        ResponseEntity<WcsR> wcsRResponseEntity = restTemplate.postForEntity("http://localhost:8081/aiot/task/info", map, WcsR.class);
        WcsR wcsR = wcsRResponseEntity.getBody();
        LinkedHashMap dataMap = (LinkedHashMap) wcsR.getData();
//        System.out.println("id:   " + dataMap.get("id").getClass().getName());
//        System.out.println("tasks: " + dataMap.get("tasks").getClass().getName());
//        System.out.println("status: " + dataMap.get("status").getClass().getName());
        ArrayList tasks = (ArrayList) dataMap.get("tasks");
        System.out.println(tasks.get(0).getClass().getName());
    }

結果

即使再次嵌套,還是對象還是被解析成了LinkedHashMap。

可以得到結論,在沒有提供對象類型的情況下,RestTemplate默認情況下是這么幫我們解析的:

所有的對象都解析LinkedHashMap, 數(shù)組解析為ArrayList,基本類型解析為Integer(以及其他的包裝類)。

方案二

為什么說是在“沒有提供對象類型的情況”?

這個例子中,最外層WcsR是我們自己提供的對象,假設我們提供所有的嵌套對象,

則可以定義以下對象用于接收返回值

最外層對象

@Data
public class WcsR {
    private String msg;
 
    private Integer code;
 
//    private Object data;
 
    private TaskDetail tasks;
}

第二層對象

@Data
public class TaskDetail {
    private Integer id;
 
    private List<TaskProcess>tasks;
 
    private Integer status;
}

第三層對象

@Data
public class TaskProcess {
    private Integer id;
 
    private Integer nodeId;
 
    private Integer status;
 
    private String actionName;
 
    private String wcsProcessName;
}

測試類

    @Test
    public void test() {
 
        HashMap<String, Integer> map = new HashMap<>();
        map.put("taskId", 1);
        ResponseEntity<WcsR> wcsRResponseEntity = restTemplate.postForEntity("http://localhost:8081/aiot/task/info", map, WcsR.class);
        WcsR wcsR = wcsRResponseEntity.getBody();
        System.out.println(wcsR.getData());
        System.out.println(wcsR.getData().getId());
        System.out.println(wcsR.getData().getTasks());
        System.out.println(wcsR.getData().getStatus());
        System.out.println(wcsR.getData().getTasks().get(0));
    }

測試結果

這種方法也是可以的。

總結

可以看出,反序列化的方案與SpringMvc的HttpMessageConvert有點類似,如果你提供了對象,則會按照對象的結構反序列化。如果沒有提供變量,則會轉化成map、List等結構。

如果接口比較少、字段比較多,可以用第二種方案。

如果接口比較多,字段比較少,并且字段數(shù)量都比較少時,為了避免定義過多的無用類,可以用第一種方案。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java中線程用法總結

    Java中線程用法總結

    這篇文章主要介紹了Java中線程用法,實例總結了java中線程的常見使用技巧,需要的朋友可以參考下
    2015-06-06
  • Springboot Websocket Stomp 消息訂閱推送

    Springboot Websocket Stomp 消息訂閱推送

    本文主要介紹了Springboot Websocket Stomp 消息訂閱推送,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • MyBatis查詢無記錄時的返回值問題

    MyBatis查詢無記錄時的返回值問題

    這篇文章主要介紹了MyBatis查詢無記錄時的返回值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java實現(xiàn)的校驗銀行卡功能示例

    Java實現(xiàn)的校驗銀行卡功能示例

    這篇文章主要介紹了Java實現(xiàn)的校驗銀行卡功能,結合完整實例形式分析了java針對銀行卡類型、歸屬地等信息的判斷、讀取相關操作技巧,需要的朋友可以參考下
    2018-06-06
  • Java注冊郵箱激活驗證實現(xiàn)代碼

    Java注冊郵箱激活驗證實現(xiàn)代碼

    這篇文章主要介紹了Java注冊郵箱激活驗證實現(xiàn)代碼,有需要的朋友可以參考一下
    2013-12-12
  • 淺談JavaWeb中的web.xml配置部署描述符文件

    淺談JavaWeb中的web.xml配置部署描述符文件

    下面小編就為大家?guī)硪黄獪\談JavaWeb中的web.xml配置部署描述符文件。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Java中synchronized關鍵字引出的多種鎖 問題

    Java中synchronized關鍵字引出的多種鎖 問題

    synchronized關鍵字是JAVA中常用的同步功能,提供了簡單易用的鎖功能。這篇文章主要介紹了Java中synchronized關鍵字引出的多種鎖問題,需要的朋友可以參考下
    2019-07-07
  • Java運用SWT插件編寫桌面記事本應用程序

    Java運用SWT插件編寫桌面記事本應用程序

    這篇文章主要為大家介紹了一個Java項目實戰(zhàn),一步步教你實現(xiàn)記事本,步驟很詳細,運用SWT插件手把手編寫記事本,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 實例解析JAVA中代碼的加載順序

    實例解析JAVA中代碼的加載順序

    這篇文章主要介紹了舉例說明Java中代碼塊的執(zhí)行順序,需要的朋友可以參考下
    2017-04-04
  • 解決springcloud 配置gateway 出現(xiàn)錯誤的問題

    解決springcloud 配置gateway 出現(xiàn)錯誤的問題

    今天給大家分享springcloud 配置gateway 出現(xiàn)錯誤的問題,其實解決方法很簡單,只需要降低springcloud版本,改成Hoxton.SR5就好了,再次改成Hoxton.SR12,也不報錯了,下面給大家展示下,感興趣的朋友一起看看吧
    2021-11-11

最新評論