tips: 提供内置的converter,并且根据当前运行环境(classload)提供增强型的converter
只看代码不说话:
/**
* 根据默认的配置创建RestTemplate实例
* 默认初始化 messageConverters
*/
public RestTemplate() {
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter());
this.messageConverters.add(new SourceHttpMessageConverter());
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
}
else if (jacksonPresent) {
this.messageConverters.add(new MappingJacksonHttpMessageConverter());
}
}
/**
* 检测当前环境(classload)是否含有指定的类,从而确定是否进行第三方MessageConverter的初始化
*/
private static boolean romePresent = ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", RestTemplate.class.getClassLoader());
/**
* MessageConverterExtractor 将reponse转化为指定的类型T
* 委托转器的优先级实现如下。同样,@ResponseBody 转化优先级亦如此,通用同样的messageConverters
*/
public T extractData(ClientHttpResponse response) throws IOException {
// ...
MediaType contentType = getContentType(response);
for (HttpMessageConverter messageConverter : this.messageConverters) {
//...
if (this.responseClass != null) {
if (messageConverter.canRead(this.responseClass, contentType)) {
//...
return (T) messageConverter.read(this.responseClass, response);
}
}
}
throw new RestClientException(
"Could not extract response: no suitable HttpMessageConverter found for response type [" +
this.responseType + "] and content type [" + contentType + "]");
}