异常信息
nested exception is org.springframework.web.client.RestClientException: Could not
extract response: no suitable HttpMessageConverter found for response type [class
java.util.Map] and content type [application/javascript;charset=utf-8]] with root cause
触发异常的代码
Map weatherMap = restTemplate.getForObject(url, Map.class);
分析原因
- 异常信息说的是:没给content-type是[application/javascript;charset=utf-8]的response找到合适的HttpMessageConverter
- 如果content-type=application/json就没问题
- 所以异常是application/javascript导致的,即:RestTemplate自带的HttpMessageConverters中没用能处理content-type=application/javascript的response的HttpMessageConverter
解决方法
Map weatherMap = restTemplate.getForObject(url, Map.class);
url是别人的接口,所以无法修改response的content-type,只能给restTemplate加一个能处理content-type=application/javascript的response的HttpMessageConverter
- RestTemplate默认自带了几个HttpMessageConverter(在RestTemplate的无参构造方法中)
public RestTemplate() {
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter(false));
try {
this.messageConverters.add(new SourceHttpMessageConverter<>());
}
catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}
...
}
- 自定义能处理content-type=application/javascript的response的HttpMessageConverter
**
* 解决:RestTemplate自带的HttpMessageConverters中没用能处理
* content-type=application/javascript的response的HttpMessageConverter
*/
public class MyApplicationJavascriptHttpMessageConverter extends AbstractHttpMessageConverter {
/**
* restTemplate获得的响应的content-type满足下面的条件
* 才会被该HttpMessageConverter处理
*/
public MyApplicationJavascriptHttpMessageConverter() {
// application/javascript
super(new MediaType("application", "javascript", Charset.forName("UTF-8")));
}
/**
* 检查传入的字节码是否符合要求
*
* @param clazz
* @return 返回true才会执行readInternal()
*/
@Override
protected boolean supports(Class clazz) {
return true;
}
/**
* 将restTemplate获得的响应转化成clazz对应的类型
*
* @param clazz
* @param inputMessage restTemplate获得的响应
* @return
*/
@Override
protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
//restTemplate发送请求后获得的响应
InputStream body = inputMessage.getBody();
//将响应转成对应类型
// 就是restTemplate.getForObject(url, Map.class)的返回值
return JSON.parseObject(body, clazz);
}
/**
* 还不知道该方法的功能
* 该方法也不会被执行到
*
* @param o
* @param outputMessage
* @throws IOException
* @throws HttpMessageNotWritableException
*/
@Override
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//do nothing
System.out.println("do nothing");
}
}
- 将自定义的HttpMessageConverter加到restTemplate的HttpMessageConverters中
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
//处理content-type=application/javascript的HttpMessageConverter
restTemplate.getMessageConverters().add(new MyApplicationJavascriptHttpMessageConverter());
return restTemplate;
}
版权声明:本文为csdn17355456893原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。