背景描述:
在开发一个后端接口过程中,使用了RestTemplate类方法exchange,
,没有能正常返回值,实体类值为空。
问题排查
- 检查实体类字段命名和返回结果的命名是否一致,包括类型等
- 查看请求体是否正常
问题回溯
于是我开始了debug的痛苦流程,一步步去找问题。就这样debug不知道过了多久,发现
@Override
@SuppressWarnings({"unchecked", "rawtypes", "resource"})
public T extractData(ClientHttpResponse response) throws IOException {
MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response);
if (!responseWrapper.hasMessageBody() || responseWrapper.hasEmptyMessageBody()) {
return null;
}
MediaType contentType = getContentType(responseWrapper);
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
if (messageConverter instanceof GenericHttpMessageConverter) {
GenericHttpMessageConverter<?> genericMessageConverter =
(GenericHttpMessageConverter<?>) messageConverter;
if (genericMessageConverter.canRead(this.responseType, null, contentType)) {
if (logger.isDebugEnabled()) {
logger.debug("Reading [" + this.responseType + "] as "" +
contentType + "" using [" + messageConverter + "]");
}
return (T) genericMessageConverter.read(this.responseType, null, responseWrapper);
}
}
if (this.responseClass != null) {
if (messageConverter.canRead(this.responseClass, contentType)) {
if (logger.isDebugEnabled()) {
logger.debug("Reading [" + this.responseClass.getName() + "] as "" +
contentType + "" using [" + messageConverter + "]");
}
return (T) messageConverter.read((Class) this.responseClass, responseWrapper);
}
}
}
throw new RestClientException("Could not extract response: no suitable HttpMessageConverter found " +
"for response type [" + this.responseType + "] and content type [" + contentType + "]");
}
该方法中的 this.messageConverters在遍历过程中会去判断整个序列化的类,偶然发现,我们需要在实体类的字段上加注解@JsonProperty 到这里,整个人emo了,怎么会这样呢?是不是这个方法如果在返回的实体类不加上述注解就不能进行序列化和反序列化? 好吧,为了验证这个问题,对实体类进行了测试:
@Data
public class GoogleTranslations implements Serializable {
private static final long serialVersionUID = -3571741016201574968L;
@JsonProperty("translatedText")
private String translatedText;
@JsonProperty("detectedSourceLanguage")
private String detectedSourceLanguage;
}
- 去掉@JsonProperty 保留implements Serializable
- 加上@JsonProperty 去掉implements Serializable
- 都去掉
上述三种方式只有加上@JsonProperty才会正常返回,也就是说这个方法才能够让这个实体类正常进行序列化
好吧,继续郁闷中,得好好翻下底层代码了,后续更新。。。
另:
RestTemplate是 Spring 提供的一个用于同步客户端 HTTP 访问的类。它简化了与 HTTP 服务器的交互,并且内部使用了 Java 的标准类如java.net.HttpURLConnection或者第三方库如 Apache HttpComponents、OKHttp 等来执行 HTTP 请求。