Apache HttpClient 读取响应乱码问题总结
Apache HttpClient 读取响应乱码问题总结
起因
最近公司产品线研发人员调整,集中兵力做战略产品,现在稳定产品迭代放慢。新的产品线当前有一个最初的版本,为了尽快了解业务,以 API 为入口,以 API 测试为手段,梳理当前版本的业务流程。
在通过 HttpClient 对 API 进行访问时,发现返回的字符串中包含的中文为乱码
环境
- JDK 1.8
- Servlet 3.0.x
- HttpClient 4.2.1
排查
疑因1
由于我们对 HttpClient 进行了再次封装,封装中使用 UTF-8 对响应数据进行编码,之前其它产品线也都使用此 Jar 进行后端 Http API 访问,均未出现乱码的情况,所以初步怀疑是服务没有设置响应编码为 UTF-8
HttpClient 封装代码如下:
HttpEntity entity = response.getEntity();
if (code >= 200 && code < 400) {
return EntityUtils.toString(entity, Charset.forName("UTF-8"));
} else {
EntityUtils.consume(entity);
throw new IllegalArgumentException("请检查连接是否正确,http return code=" + code);
}
查看服务端代码,发现设置了响应的字符编码
response.setCharacterEncoding("UTF-8");
这样服务端编码与客户端编码都是 UTF-8,理论上不应出现乱码的情况。
继续看代码,发现后端代码没有设置响应的 Content-Type,加上如下代码:
response.setContentType("application/json;charset=utf-8");
再次进行测试,发现中文显示正常。
疑因2
排除掉疑因1后,怀疑 setContentType() 方法和 setCharacterEncoding() 方法的处理不一致,遂查看源码,如下:

发现 setContentType 方法内部也会调用 setCharacterEncoding 方法,唯一的区别就是 setContentType 方法设置了 Content-Type 头信息
疑因3
排除掉2后,怀疑是 HttpClinet 对 ContentType 的处理有问题,并且 EntityUtils.toString(entity, Charset.forName("UTF-8"));
中的编码没有起作用。
查看其源码,如下:


从图1中可以看出来,如果没有设置响应 ContentType,它会设置一个默认的 ContentType,从图2中可以看来,设置的默认
Content-Type : text/plain;Charset=ISO-8859-1
Httpclient 会优先使用 ContentType 的编码,只在 ContentType 编码取不到的情况下,才会使用传入的编码(defaultCharset),而默认的 ContentType 始终带有编码(ISO-8859-1)。
所以,当服务端未显式设置 ContentType 时,Httpclient 会使用 ISO-8859-1 编码格式对响应数据进行编码,而不是显式传入的 UTF-8 编码,所以中文会出现乱码。
总结
问题找到原因了,就好办了。
我们只需要显示设置服务端响应 Content-Type 即可,而且这样可以避免通过浏览器访问接口时出现乱码,兼容性更好。
个人认为这是 HttpClient 的一个 bug ,本想给官方提个 issue,但没找到提 Bug 的入口(笑哭),如有人知道,烦请告知,不胜感激!
Apache HttpClient 读取响应乱码问题总结的更多相关文章
- HttpClient读取数据乱码的解决方案
博主是一个近十年的老书虫了,从高中那会儿就开始看网络小说.每天半天看晚上看啊,终于眼睛也近视了,成绩也下降了(....好像说远了) 最近在追辰东的<圣墟>,最近写到精彩部分了,一直等更新. ...
- Apache HttpClient 5 使用详细教程
点赞再看,动力无限. 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 超文本传输协议(HTTP)可能是当今 ...
- HttpClient读取ASP.NET Web API错误信息的简单方法
在C#中,用HttpClient调用Web API并且通过Content.ReadAsStringAsync()读取响应内容时,如果出现500错误(InternalServerError),会得到一个 ...
- 《Apache HttpClient 4.3开发指南》
转载自:http://blog.csdn.net/chszs/article/details/16854747 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chs ...
- 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据
1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...
- Apache HttpClient之fluent API的使用
该方法为Apache HttpClient 4.5以上的版本支持,在官网有明确的说明. 对比以前的方式,其优点是代码更简洁,同时为线程安全的.仅举一个最简单的post栗子 JAR包信息: <de ...
- 1 - Apache HttpClient 简单使用
Apache HttpClient 是Apache 开源的实现Http协议的java开源库. HttpClien 是客户端的HTTP通信实现库,实现HTTP GET 和POST请求,获取响应内容. A ...
- .Net Core HttpClient处理响应压缩
前言 在上篇文章[ASP.NET Core中的响应压缩]中我们谈到了在ASP.NET Core服务端处理关于响应压缩的请求,服务端的主要工作就是根据Content-Encoding头信息判断采 ...
- 如何在Apache HttpClient中设置TLS版本
1.简介 Apache HttpClient是一个底层.轻量级的客户端HTTP库,用于与HTTP服务器进行通信. 在本教程中,我们将学习如何在使用HttpClient时配置支持的传输层安全(TLS)版 ...
随机推荐
- 四、IDEA创建SpringBoot项目
1.从官网下载之后直接导入IDEA: 下载完成解压之后如下图: IDEA导入该项目: 之后一路next即可 导入成功之后你可能会发现左下角一直有个进度条在进行,傻傻的同学可能以为是在下载jar包,下个 ...
- python - DBUtils 连接池减少oracle数据库的连接数
问题: 接到需求,告知项目的oracle连接次数过多,对系统造成太过大的负担,要求减少oracle数据库的连接次数 分析: 仔细分析代码以后,发现产生问题的原因,在于之前要求提升oracle监控的监控 ...
- EDM邮件营销的七个重要参考指标
如何做好EDM邮件营销,已经成为EDM工作人员面临的实际问题.当你发送邮件之前, 你可以先想想:我自己的电子邮件的目标是什么?邮件能否吸引收件人?能带来更多客户吗?无论你的目标是什么,以下的这些指标是 ...
- Cloudera-JDBC-Driver-for-Impala
Cloudera-JDBC-Driver-for-Impala-Install-Guide-2-5-5.pdf https://github.com/FlowerBirds/flowerbirds.g ...
- 7.k8s.调度器scheduler 亲和性、污点
#k8s. 调度器scheduler 亲和性.污点 默认调度过程:预选 Predicates (过滤节点) --> 优选 Priorities(优先级排序) --> 优先级最高节点 实际使 ...
- TField中的GetText和SetText
在数据表中的某些字段出于性能或数据规范化的考虑,会用组编号代替,就像学生有学号,员工有员工ID一样,但我们看的时候如果直接输入这样的编号看的人可能就会头痛了,这时就可用TField中的GetText转 ...
- 【SSH】---【Struts2、Hibernate5、Spring4】【散点知识】
一.Struts21.1.Struts2的概念Struts2是一个用来开发MVC应用程序的框架,它提供了Web应用程序开发过程中的一些常见问题的解决方案: ->对来自用户的输入数据进行合法 ...
- Activity启动流程(三)
这里对启动Activity过程中涉及到的ActivityStack.TaskRecord.ActivityRecord.ActivityStackSupervisor进行简单的分析,实际上一张时序图就 ...
- yum基本使用方法
yum 是 Fedora RHEL Centos SUSE等linux 发行版的 软件包管理工具 通过 执行 man yum 查看yum的帮助信息 可以知道 yum makecache 是将服务器上的 ...
- 关于Goroutine与Channel
关于Goroutine的原理 原理上的内容比较多,比如goroutine启动的时候要执行哪些相关的操作,一点一点的补充一下. channel的基本原理 channel是go语言中的特殊的机制,既可以同 ...