项目场景:
Spring Boot项目使用RestTemplate调用接口,使用嵌套实体对象接收的返回结果
实体对象TokenUser,其中TokenUserInfo是嵌套的对象:
@Data
public class TokenUser {private Integer code;private TokenUserInfo data;private Boolean success;
}
@Data
public class TokenUserInfo {/*** 用户id*/private String userId;/*** 用户名*/private String userName;}
使用RestTemplate调用接口
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);HttpEntity<String> formEntity= new HttpEntity<>(requestJson, headers);TokenUser tokenUser = null;
try {tokenUser = restTemplate.postForObject(url, formEntity, TokenUser.class);
} catch (Exception e) {logger.error("调用接口出错: ", e);
}
问题描述
Spring Boot项目使用RestTemplate调用接口,使用嵌套实体对象接收的返回结果
返回的嵌套对象为null不会有问题
{"data": null,"success": true,"code": 200
}
但是返回的嵌套对象是''空字符串就会报错
{"data": "","success": true,"code": 200
}
报错详情:
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 ('')at [Source: (PushbackInputStream); line: 1, column: 55] (through reference chain: com.test.dto.TokenUser["data"])
原因分析:
简单来说就是 json转化成对象失败了,失败的原因是TokenUserInfo对象中虽然有一个构造器,却是全参构造器或是无参构造器,就是缺少一个只有一个String类型参数的构造器,导致在解析 ' ' 空字符串时失败了。
解决方案:
第一种:实体类加上String类型参数的构造器
同时加上@NoArgsConstructor, @AllArgsConstructor 注解,提供无参数的构造函数和全参数的构造函数
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TokenUserInfo {/*** 防止返回值是空字符串,用string来接收*/public TokenUserInfo(String userId){this.userId = userId;}/*** 用户id*/private String userId;/*** 用户名*/private String userName;}
第二种:用String接收返回结果,再转json对象
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);HttpEntity<String> formEntity= new HttpEntity<>(requestJson, headers);TokenUser tokenUser = null;
try {String jsonResult = restTemplate.postForObject(url, formEntity, String.class);JSONObject userJson = JSON.parseObject(jsonResult);tokenUser = JSONObject.toJavaObject(userJson, TokenUser.class);
} catch (Exception e) {logger.error("调用接口出错: ", e);
}
我这里用的是alibaba的包
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.44</version>
</dependency>