博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RestTemplate--解决中文乱码
阅读量:7243 次
发布时间:2019-06-29

本文共 3367 字,大约阅读时间需要 11 分钟。

【原文链接】:https://www.tecchen.xyz/rest-template-messycode.html

我的个人博客:https://www.tecchen.xyz

在开发时,使用RestTemplate请求扇贝接口,并保存返回的数据。原本正常的代码,经过架构升级后,请求接口时,会返回乱码数据。经过直接访问接口等形式,最终确认是RestTemplate这个bean有问题。

对RestTemplate的声明也比较简单,通过对apache的httpclient进行封装,返回bean实例。代码如下:

@BeanRestTemplate 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<HttpMessageConverter<?>> messageConverters

根据RestTemplate的构造方法的源码得知所有的HttpMessageConverter都是放在final List<HttpMessageConverter<?>> messageConverters这个常量集合中。虽然集合不可修改,但是可以对其中的元素StringHttpMessageConverter进行修改。
解决方案思路都是将ISO-8859-1的StringHttpMessageConverter替换为UTF-8的StringHttpMessageConverter。

  • 示例代码一
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"));}

转载于:https://www.cnblogs.com/Candies/p/10398584.html

你可能感兴趣的文章
HashMap,HashTable,ConcurrentHashMap异同比较
查看>>
cpp
查看>>
linux dd实现磁盘完整全盘镜像备份backup,恢复recover(restore)
查看>>
android点滴(16)--ubuntu下android源代码以及内核的获取
查看>>
石子合并DP
查看>>
处理器管理与进程管理
查看>>
虚拟机扩容mac
查看>>
vuejs怎么在服务器部署?(知乎)
查看>>
VI的配置
查看>>
实验三 进程调度模拟程序 1.0
查看>>
Cannot connect to VM com.sun.jdi.connect.TransportTimeoutException
查看>>
Java的内存需要划分成为5个部分:
查看>>
《我是一只 IT 小小鸟》 - 书摘精要
查看>>
mysqldump之字符集问题解决
查看>>
Dockerfile
查看>>
LVS学习笔记
查看>>
Scala伴生类和伴生对象
查看>>
c# winform控件dock属性停造位置、摆放顺序详解
查看>>
leetcode 169求众数
查看>>
Lambda
查看>>