Java-Java中HttpURLConnection返回头Location域中文乱码问题

发布于 2017-09-05 19:49:00 字数 554 浏览 1907 评论 4

Java使用HttpURLConnection访问某个网页时,如果该网页返回头中的数据包含中文,结果中文就成了乱码

URL url = new URL(urlstr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//一些配置
// 连接
conn.connect();
Map<String, List<String>> header = conn.getHeaderFields();
for (Map.Entry<String, List<String>> entry : header.entrySet()) {
String key = entry.getKey();
for (String value : entry.getValue()) {
System.out.println(key + ":" + value);
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

灵芸 2017-10-26 22:10:07

如果是tomcat作为容器的话可以通过配置server.xml中的Connector解决
具体为:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
在其中添加URIEncoding="UTF-8"使之变成:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
容器会自动处理编码

虐人心 2017-10-22 23:58:54

http://blog.csdn.net/competerh_programing/article/details/6731806
你可以看看这里的中文问题解决方案,大多数都能在这找到答案

夜无邪 2017-10-22 17:15:06

我在php中设置一个header, 可以重现楼主的问题:

header("newheader:  中");

但因为我的php是gbk编码, 所以使用

new String(value.getBytes("ISO-8859-1"), "gbk");

可以解决问题.

下面来具体分析一下:
看HttpURLConnection的getHeaderField代码最终追到sun.net.www.MessageHeader类的mergeHeader(InputStream paramInputStream)方法,反编译可见此方法的处理过程:

//从流中每次读一个字节, 按ascii码处理,比较有用的信息: 
int i = paramInputStream.read();     //读一个字节
...
Object localObject1 = new char[10];  
...
localObject1[(j++)] = (char)i;       //字节转为char(2字节)
...
str = String.copyValueOf(localObject1, k, j - k); //生成最后的string
...

当然代码要复杂很多了. 上面摘取的代码可以帮我们理解一下发生了什么.

所以这里也不是按iso8859-1来处理,对我的例子来说:

1. '中' gbk编码为 0xD6 0xD0; 
2. 按字节处理转为unicode char后为0x00D6 0x00D0(因为char为2字节);注意java里char其实是用unicode来存储.
3. 把 0x00D6 0x00D0按gbk解码, 因为gbk和unicode不兼容, 0x00D6在gbk里是非法字符, 所以直接转为0x3f, 也就是?.
4. 把字符串 0x00D6 0x00D0按iso8859-1解码, 因为unicode兼容iso8859-1, char 0x00D6转为字节0xD6.0x00D0转为0xD0; 这样就转回到了一开始 '中' 的gbk编码

所以new String(value.getBytes("ISO-8859-1"), "gbk");可以解决上述乱码问题.

甜柠檬 2017-09-06 01:34:09

HttpURLConnection的getHeaderField默认所有header是用iso-8859-1编码的,但是中文实际是用uft8编码,所以出现了乱码问题。

new String(conn.getHeaderField("location").getBytes("ISO-8859-1"), "UTF-8")

这样就可以解决中文乱码的问题了。

---------------------------------------------------

看了@brayden 的答案,再深入了解一下。

除了分析源码,也可以从编码的方面去解析。

这里可以分为调用端的编码设置,被调用端的编码设置。

被调用端的编码
在这里是Server端,以Tomcat为例,request/response的body默认是ISO-8859-1编码的。
可参考:
http://wiki.apache.org/tomcat/FAQ/CharacterEncoding
Header根据Http 1.1标准,也是用ISO-8859-1编码的
可参考:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
调用端的编码
这要看具体设置,如果也是Tomcat调用的话,默认也是用ISO-8859-1解析的

所以

conn.getHeaderField("location").getBytes("ISO-8859-1")

这样,是获取HTTP传输过程中,location的值。但是这个值用什么字符集,调用端是不知道的。(有可能是GBK,也有可能是utf-8)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文