使用restTemplate调用接口时,接口返回的响应头内content-type是text/plain;chartset=UTF-8;
异常详情:
no suitable HttpMessageConverter found for response type [class com.aliba ba.fastjson.JSONObject] and content type [text/plain;charset=UTF-8]
由于三方接口鉴权成功时返回json,所以我是用JSONObject来接的返回数据,但是它失败时返回了个text。
解决方案:
配置RestTemplate:
package com.peraglobal.restInterface.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
/**
* restTemplate config
* @author ChengXY
* @Date 2023年7月28日下午5:16:18
*/
@Configuration
public class WebConfiguration {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
RestTemplate restTemplate = new RestTemplate(factory);
// ChengXY 20231109 解决restTempalte解析不了text/plain
restTemplate.getMessageConverters().add(new MyMappingJackson2HttpMessageConverter());
return restTemplate;
}
public static class MyMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter{
public MyMappingJackson2HttpMessageConverter(){
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
setSupportedMediaTypes(mediaTypes);
}
}
}
配置后可以成功获取数据,但是要注意接收数据的类型。
错误的接收类型报异常:
org.springframework.http.converte r.HttpMessageNotReadableException: Could not read document: Unrecognized token 'xxx': was expecting (JSON St ring, Number, Array, Object or token 'null', 'true' or 'false') at [Source: (PushbackInputStream); line: 1, column: 16]; nested exception is com.fasterxml.jackson.core.JsonParseExcept ion: Unrecognized token 'xxx': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
可以用String来接收:
ResponseEntity<String> resultEntity = restTemplate.postForEntity(url, null, String.class);
附一个目前用的restTemplate配置类:
- text/plain;
- 关于restTemplate error时不返回
package com.peraglobal.restInterface.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
/**
* restTemplate config
* @author ChengXY
* @Date 2023年7月28日下午5:16:18
*/
@Configuration
public class WebConfiguration {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.setErrorHandler(new getErrorBodyHandler());
// ChengXY 20231109 解决restTempalte解析不了text/plain
restTemplate.getMessageConverters().add(new MyMappingJackson2HttpMessageConverter());
return restTemplate;
}
public static class getErrorBodyHandler implements ResponseErrorHandler{
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return false;
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
}
@Bean
public RestTemplate httpsRestTemplate(HttpComponentsClientHttpRequestFactory httpsFactory){
RestTemplate restTemplate = new RestTemplate(httpsFactory);
restTemplate.setErrorHandler(new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) {
return false;
}
@Override
public void handleError(ClientHttpResponse clientHttpResponse) {
//默认处理非200的返回,会抛异常
}
});
return restTemplate;
}
@Bean(name = "httpsFactory")
public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory() throws Exception{
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
// NoRedirectClientHttpRequestFactory httpRequestFactory = new NoRedirectClientHttpRequestFactory();// 此类型不能使用httpClient
httpRequestFactory.setConnectionRequestTimeout(2000);
httpRequestFactory.setConnectTimeout(10000);
httpRequestFactory.setReadTimeout(7200000);
HttpClient httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient();
// HttpClient httpClient = HttpClientBuilder.create().disableCookieManagement().disableRedirectHandling().build();
httpRequestFactory.setHttpClient(httpClient);
// RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
//
// HttpComponentsClientHttpRequestFactory httpsFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// httpsFactory.setReadTimeout(30000);
// httpsFactory.setConnectTimeout(2000);
return httpRequestFactory;
}
public static class MyMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter{
public MyMappingJackson2HttpMessageConverter(){
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
setSupportedMediaTypes(mediaTypes);
}
}
}