• 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>
  • 相关阅读:
    基于单片机的电源切换控制器设计(论文+源码)
    [Android][音频] 关于AudioTrack libaudioclient libaaudio
    ubuntu中使用QT、C++使用redis、hiredis记录
    [JSON] JSON基础知识
    2、中间件-CAP理论
    【设计模式】状态模式
    基于JAVA仁爱公益网站计算机毕业设计源码+系统+mysql数据库+lw文档+部署
    TRichView添加Android演示和实时拼写建议
    4、wireshark使用教程
    实验23:lcd1602实验
  • 原文地址:https://blog.csdn.net/u011974797/article/details/136480827