解决RestTemplate反序列化嵌套对象的问题

作者:小楼夜听雨QAQ 时间:2022-06-26 20:41:24 

RestTemplate反序列化嵌套对象

假设某个接口返回的数据如下格式

{
 "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
 }
}

仿写一个测试接口,用于返回这种格式的数据

@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();
   }

方案一

一般情况下,我们会创建一个与服务端一致的通用值返回对象。

@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());
   }

运行结果

解决RestTemplate反序列化嵌套对象的问题

看后台的代码我们可以知道,data是一个对象,里面有三个变量,id(整型),tasks(对象数组),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());
   }

结果

解决RestTemplate反序列化嵌套对象的问题

可以看到,数组被解析成了Arraylist, 基本类型被解析成对应的包装类型。

数组里面还是个对象,还会继续帮我们解析吗?测试代码如下

@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());
   }

结果

解决RestTemplate反序列化嵌套对象的问题

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

可以得到结论,在没有提供对象类型的情况下,RestTemplate默认情况下是这么帮我们解析的:

所有的对象都解析LinkedHashMap, 数组解析为ArrayList,基本类型解析为Integer(以及其他的包装类)。

方案二

为什么说是在&ldquo;没有提供对象类型的情况&rdquo;?

这个例子中,最外层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));
   }

测试结果

解决RestTemplate反序列化嵌套对象的问题

这种方法也是可以的。

来源:https://blog.csdn.net/qq_37855749/article/details/117691268

标签:RestTemplate,反序列化,嵌套,对象
0
投稿

猜你喜欢

  • 全面解析java final关键字

    2023-03-16 03:04:55
  • Java异常处理try catch的基本使用

    2023-11-24 05:04:38
  • Android自定义View实现开关按钮

    2021-09-08 08:53:22
  • Java日常练习题,每天进步一点点(46)

    2023-10-05 11:20:29
  • MaterialApp Flutter 应用全局配置与主题管理详解

    2023-05-03 18:50:48
  • Java拦截器和过滤器的区别分析

    2021-11-06 22:28:46
  • 详解android使用ItemDecoration 悬浮导航栏效果

    2022-05-07 18:17:09
  • C#利用正则判断输入是否为纯数字、容器类

    2022-10-10 03:00:39
  • Android Binder的原理与使用

    2023-04-06 04:08:49
  • Java实现快速排序算法的完整示例

    2022-10-15 11:57:40
  • android实现简单音乐播放器

    2021-06-28 22:07:26
  • Android拼图游戏 玩转从基础到应用手势变化

    2021-08-24 02:41:59
  • springboot vue测试平台开发调通前后端环境实现登录

    2021-08-13 03:54:02
  • Android Studio 中获取屏幕宽度实例

    2022-03-25 11:55:36
  • Unity游戏开发实现场景切换示例

    2022-12-12 16:06:20
  • Java数组队列概念与用法实例分析

    2023-11-18 04:18:31
  • Android ActionBarActivity设置全屏无标题的方法总结

    2023-01-23 04:49:37
  • IDEA类与方法注释模板设置图文教程(非常详细)

    2022-02-24 10:18:29
  • Android实现换肤的两种思路分析

    2023-03-25 13:54:18
  • Android取消EditText自动获取默认焦点

    2023-09-09 00:14:13
  • asp之家 软件编程 m.aspxhome.com