• Spring使用RestTemplate返回的嵌套实体对象为空,转换json报错


    项目场景:

    Spring Boot项目使用RestTemplate调用接口,使用嵌套实体对象接收的返回结果

    实体对象TokenUser,其中TokenUserInfo是嵌套的对象:

    1. @Data
    2. public class TokenUser {
    3. private Integer code;
    4. private TokenUserInfo data;
    5. private Boolean success;
    6. }
    1. @Data
    2. public class TokenUserInfo {
    3. /**
    4. * 用户id
    5. */
    6. private String userId;
    7. /**
    8. * 用户名
    9. */
    10. private String userName;
    11. }

     使用RestTemplate调用接口

    1. HttpHeaders headers = new HttpHeaders();
    2. headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
    3. HttpEntity formEntity= new HttpEntity<>(requestJson, headers);
    4. TokenUser tokenUser = null;
    5. try {
    6. tokenUser = restTemplate.postForObject(url, formEntity, TokenUser.class);
    7. } catch (Exception e) {
    8. logger.error("调用接口出错: ", e);
    9. }

    问题描述

    Spring Boot项目使用RestTemplate调用接口,使用嵌套实体对象接收的返回结果

    返回的嵌套对象为null不会有问题

    1. {
    2. "data": null,
    3. "success": true,
    4. "code": 200
    5. }

    但是返回的嵌套对象是''空字符串就会报错

    1. {
    2.     "data": "",
    3.     "success": true,
    4.     "code": 200
    5. }

    报错详情:

    1. Error while extracting response for type [class com.test.dto.TokenUser] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.test.dto.TokenUserInfo` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value (''); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.test.dto.TokenUserInfo` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('')
    2. at [Source: (PushbackInputStream); line: 1, column: 55] (through reference chain: com.test.dto.TokenUser["data"])

    原因分析:

            简单来说就是 json转化成对象失败了,失败的原因是TokenUserInfo对象中虽然有一个构造器,却是全参构造器或是无参构造器,就是缺少一个只有一个String类型参数的构造器,导致在解析 ' ' 空字符串时失败了。


    解决方案:

    第一种:实体类加上String类型参数的构造器

    1. @Data
    2. public class TokenUserInfo {
    3. /**
    4. * 防止返回值是空字符串,用string来接收
    5. */
    6. public TokenUserInfo(String userId){
    7. this.userId = userId;
    8. }
    9. /**
    10. * 用户id
    11. */
    12. private String userId;
    13. /**
    14. * 用户名
    15. */
    16. private String userName;
    17. }

    第二种:用String接收返回结果,再转json对象

    1. HttpHeaders headers = new HttpHeaders();
    2. headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
    3. HttpEntity formEntity= new HttpEntity<>(requestJson, headers);
    4. TokenUser tokenUser = null;
    5. try {
    6. String jsonResult = restTemplate.postForObject(url, formEntity, String.class);
    7. JSONObject userJson = JSON.parseObject(jsonResult);
    8. tokenUser = JSONObject.toJavaObject(userJson, TokenUser.class);
    9. } catch (Exception e) {
    10. logger.error("调用接口出错: ", e);
    11. }

    我这里用的是alibaba的包

    1. <dependency>
    2. <groupId>com.alibabagroupId>
    3. <artifactId>fastjsonartifactId>
    4. <version>1.2.44version>
    5. dependency>
  • 相关阅读:
    数据管理70个名词解析
    mysql备份与还原
    【Leetcode】140.单词拆分II(Hard)
    SAP VA02R批量修改销售订单拒绝原因的BAPI:BAPI_SALESORDER_CHANGE
    测试必备工具 —— Postman实战教程
    基于MATLAB的迭代学习控制(Iterative Learning Control,ILC)算法的仿真与分析
    如何利用Requestly提升前端开发与测试的效率,让你事半功倍?
    配电站房门禁监控、气体监测、视频监控系统 设备安装
    自定义注+切面控制方法执行步骤
    基于STM32蓝牙控制的app智能台灯设计
  • 原文地址:https://blog.csdn.net/u011974797/article/details/136480827