RestTemplate--解决中文乱码
【原文链接】: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<String> {
    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<HttpMessageConverter<?>> converter = restTemplate.getMessageConverters().stream().filter(c -> c instanceof StringHttpMessageConverter).findAny();
if(converter.isPresent()) {
    ((StringHttpMessageConverter) converter.get()).setDefaultCharset(Charset.forName("UTF-8"));
}
												
											RestTemplate--解决中文乱码的更多相关文章
- 增加UBUNTU字符集 解决中文乱码问题
		
对GBK,GB2312,GB18030字符集的支持是UBUNTU中文乱码的罪魁祸首,其实我们可以在保持UTF-8为默认编码的条件下添加对这几个编码的支持,以解决中文乱码问题. 我想这个问题肯定有其他人 ...
 - Sublime Text 2—解决中文乱码
		
Sublime Text 2是一个非常棒的代码及文本编辑器,绿色小巧.速度飞快,跨平台支持Win/Mac/Linux,支持32与64位,支持各种流行编程语言的语法高亮.代码补全等,有着许多其他编辑器没 ...
 - zabbix解决中文乱码问题(没有测试成功)
		
zabbix解决中文乱码问题 1.在windows系统中找一个自己喜欢的字体,这里我们用:msyh.ttf 2.将字体上传至/var/www/html/zabbix/fonts目录下 [root@za ...
 - 【原创】通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 ‘incorrect string value: '\xF0...
		
这篇blog重点在解决问题,如果你对字符编码并不是特别了解,建议先看看 < [原创]通俗易懂地解决中文乱码问题(1) --- 跨平台乱码 >. 当然,如果只是针对解决这个Mysql插入报错 ...
 - Debian 6解决中文乱码
		
DEBIAN下中文显示 一.首先检查LOCALE情况 说明:DEBIAN因为基于GNU所以,对不同地域进行了不同的包支持,以LOCALE形式存在. 1.挂载ISO文件包,前8个ISO包就可以(这里不在 ...
 - 04_过滤器Filter_02_Filter解决中文乱码问题
		
[过滤器解决中文乱码问题实例] [工程截图] [web.xml] <?xml version="1.0" encoding="UTF-8"?> &l ...
 - Web---演示servlet技术(servlet生命周期),解决中文乱码问题
		
本节讲解决中文乱码问题的4种方法. 还有更好的方法,也就是用过滤器,这里就不演示了,博主目前也不会~呼♪(^∇^*)~过段时间才会学. servlet生命周期演示: index.jsp: <%@ ...
 - 通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 ‘incorrect string value: '\xF0...
		
原文:[原创]通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 'incorrect string value: '\xF0... 这篇blog重点在解决问题,如果你对 ...
 - 解决中文乱码( jsp表单提交中文时出现乱码)
		
有三种方法: 1.建立一个filter中文解决乱码 2.Struts2在struts.xml中修改默认的编码设定 3.用Spring解决中文乱码 4.直接在jsp中修改解决 1.建立一个filter解 ...
 - java web 中有效解决中文乱码问题-pageEncoding与charset区别, response和request的setCharacterEncoding 区别
		
这里先写几个大家容易搞混的编码设置代码: 在jsp代码中的头部往往有这两行代码 pageEncoding是jsp文件本身的编码contentType的charset是指服务器发送给客户端时的内容编码J ...
 
随机推荐
- jquery.cookie 介绍 和 用法
			
1.依赖jQuery库 2.浏览器兼容性情况 3.下载 官方github:https://github.com/carhartl/jquery-cookie 4.使用 创建一个整站cookie $.c ...
 - Linux服务器上如何设置MySQL的max_allowed_packe
			
mysql根据配置文件会限制server接受的数据包大小. 有时候大的插入和更新会被max_allowed_packet 参数限制掉,导致失败. 查看目前配置 show VARIABLES like ...
 - win7下面iis错误汇总
			
1.分析器错误消息: 无法识别的属性“targetFramework”.请注意属性名称区分大小写 解决方法: 修改.NET Framework 版本为相应版本即可,我以前用的是2.0换成4.0的时候出 ...
 - mongon命令(转)
			
原文:http://www.cnblogs.com/blueness-sunshine/p/6139092.html 连接mongodb: mongo -u --authenticationDat ...
 - 洛谷P4556 [Vani有约会]雨天的尾巴(线段树合并)
			
题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连根拔起,以及田地 ...
 - Android-bindService本地服务-初步-Service返回对象
			
在Android开发过程中,Android API 已经有了startService方式,为什么还需要bindService呢? 答:是因为bindService可以实现Activity-->S ...
 - CentOS6.4 X86_64 kvm+PXE备忘
			
Install 安装 1 2 3 4 5 # yum install qemu-kvm qemu-img # 使用kvm至少要安装的包,一个提供用户级别kvm模拟器,一个提供磁盘镜像的管理 # 安装虚 ...
 - Linux Guard Service - 进程分裂与脱离
			
进程分裂更名 void set_ps_name(char *name) { prctl(PR_SET_NAME, name); } 修改进程长名称 备份进程环境变量空间 for (i = 1; i & ...
 - mysqldump的简单使用
			
背景 需要搞mysql数据同步,从一台服务器把数据库同步到另外一台服务器上,如果折腾过的话,就知道有个这玩意--mysqldump,其实就是mysql自带的一个命令而已 操作步骤 1. 认识mysql ...
 - 自己从0开始学习Unity的笔记 VII (C#中类继承练习)
			
好久都没有写了.今天做了类继承的练习,做了一个小队,进行简单的判定. namespace 兵团建立练习 { class ServantBasics { public string name; //pr ...