【原文链接】:https://blog.tecchen.xyz ,博文同步发布到博客园。
由于精力有限,对文章的更新可能不能及时同步,请点击上面的原文链接访问最新内容。
欢迎访问我的个人网站:https://www.tecchen.xyz 。
在开发扇贝-每日一句时,使用RestTemplate请求扇贝接口,并保存返回的数据。原本正常的代码,经过架构升级后,请求接口时,会返回乱码数据。经过直接访问接口等形式,最终确认是RestTemplate这个bean有问题。
对RestTemplate的声明也比较简单,通过对apache的httpclient进行封装,返回bean实例。代码如下:
@Bean
RestTemplate restTemplate() {
return new RestTemplate(httpRequestFactory());
}
通过断点debug发现以String格式接收数据时,底层采用的是StringHttpMessageConverter来处理请求。查看RestTemplate的构造方法如下:
public RestTemplate() {
this.messageConverters = new ArrayList();
this.errorHandler = new DefaultResponseErrorHandler();
this.uriTemplateHandler = new DefaultUriBuilderFactory();
this.headersExtractor = new RestTemplate.HeadersExtractor();
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter(false));
this.messageConverters.add(new SourceHttpMessageConverter());
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (jackson2XmlPresent) {
this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
} else if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
} else if (gsonPresent) {
this.messageConverters.add(new GsonHttpMessageConverter());
} else if (jsonbPresent) {
this.messageConverters.add(new JsonbHttpMessageConverter());
}
if (jackson2SmilePresent) {
this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
}
if (jackson2CborPresent) {
this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
}
}
其中的StringHttpMessageConverter构造方法使用了默认字符集:ISO-8859-1。
public class StringHttpMessageConverter extends AbstractHttpMessageConverter {
public static final Charset DEFAULT_CHARSET;
......
public StringHttpMessageConverter() {
this(DEFAULT_CHARSET);
}
......
static {
DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
}
}
private final List
- 示例代码一
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
- 示例代码二
for (HttpMessageConverter httpMessageConverter : restTemplate.getMessageConverters()) {
if (httpMessageConverter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));
}
}
- 示例代码三
// stream .findFirst(); 也是可以的
Optional> converter = restTemplate.getMessageConverters().stream().filter(c -> c instanceof StringHttpMessageConverter).findAny();
if(converter.isPresent()) {
((StringHttpMessageConverter) converter.get()).setDefaultCharset(Charset.forName("UTF-8"));
}
Original: https://www.cnblogs.com/Candies/p/10398584.html
Author: Candyメ奶糖
Title: RestTemplate–解决中文乱码
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574349/
转载文章受原作者版权保护。转载请注明原作者出处!