url重定向中的Java HttpUrlConnection国际字符
我在获取某些网站的内容时遇到问题。当我尝试导航到重定向到另一个包含国际字符的url时,java通常会出现错误404。当我在浏览器中跟踪这个url时,我会得到有效的数据 例如,我想导航到hXXp://shar.es/cISmv(不能发布超过2个有效链接) 浏览器将我正确重定向到hXXp://www.dandy-magazine.com/la-griffe-de-la-tour-d%E2%80%99银色。从wget中,我可以看到最初站点返回重定向301,其中包含现有的“位置”: 在java中(重定向已关闭),它返回带有“url重定向中的Java HttpUrlConnection国际字符,java,httpurlconnection,urlconnection,Java,Httpurlconnection,Urlconnection,我在获取某些网站的内容时遇到问题。当我尝试导航到重定向到另一个包含国际字符的url时,java通常会出现错误404。当我在浏览器中跟踪这个url时,我会得到有效的数据 例如,我想导航到hXXp://shar.es/cISmv(不能发布超过2个有效链接) 浏览器将我正确重定向到hXXp://www.dandy-magazine.com/la-griffe-de-la-tour-d%E2%80%99银色。从wget中,我可以看到最初站点返回重定向301,其中包含现有的“位置”: 在java中(重定向
Location:http://www.dandy-magazine.com/la-griffe-de-la-tour-d-银色
”。使用url编码时,ot如下所示:“http://www.dandy-magazine.com/la-griffe-de-la-tour-d%C3%A2%C2%80%C2%99argent
”。正如你所看到的,这是一个完全不同的网站
示例代码(基本上版本1和版本2做相同的事情):
Thx for help据我所知,当位置头的值为UTF-8编码时,Java没有处理它
00e0 65 70 2d 61 6c 69 76 65 0d 0a 4c 6f 63 61 74 69 ep-alive ..Locati
00f0 6f 6e 3a 20 68 74 74 70 3a 2f 2f 77 77 77 2e 64 on: http ://www.d
0100 61 6e 64 79 2d 6d 61 67 61 7a 69 6e 65 2e 63 6f andy-mag azine.co
0110 6d 2f 6c 61 2d 67 72 69 66 66 65 2d 64 65 2d 6c m/la-gri ffe-de-l
0120 61 2d 74 6f 75 72 2d 64 e2 80 99 61 72 67 65 6e a-tour-d ...argen
0130 74 0d 0a 0d 0a 30 0d 0a 0d 0a t....0.. ..
URL应该看起来像…/la-griffe-de-la-tour-d'argent。请注意,在上一句中,我使用的是ASCII单引号字符。但是,网站没有使用单引号字符,而是选择使用unicode字符
00002019 RIGHT SINGLE QUOTATION MARK
Glyph: ’
UTF-8: E2 80 99
wireshark跟踪显示返回的位置标头已编码此字符UTF-8
00e0 65 70 2d 61 6c 69 76 65 0d 0a 4c 6f 63 61 74 69 ep-alive ..Locati
00f0 6f 6e 3a 20 68 74 74 70 3a 2f 2f 77 77 77 2e 64 on: http ://www.d
0100 61 6e 64 79 2d 6d 61 67 61 7a 69 6e 65 2e 63 6f andy-mag azine.co
0110 6d 2f 6c 61 2d 67 72 69 66 66 65 2d 64 65 2d 6c m/la-gri ffe-de-l
0120 61 2d 74 6f 75 72 2d 64 e2 80 99 61 72 67 65 6e a-tour-d ...argen
0130 74 0d 0a 0d 0a 30 0d 0a 0d 0a t....0.. ..
我不知道这是否合法。网络上肯定有很多关于这方面的问题。不管它是否合法,HttpURLConnection类都不能很好地处理它。呼吁
String loc = con.getHeaderField("Location");
应该已返回字符串http://www.dandy-magazine.com/la-griffe-de-la-tour-d'银色
在d
和argent
之间有一个字符(2019)。相反,它通过将这3个UTF-8字节中的每一个都哑转换为字符(E28099)来返回一个无效字符串。此时,“loc”字符串是无用的。它不是有效的unicode字符串
以下是一个可能有帮助的解决方法:
String loc = con.getHeaderField("Location");
byte [] locbytes = new byte[loc.length()];
for (int index = 0; index < locbytes.length; index++)
{
locbytes[index] = (byte) loc.charAt(index);
}
// use this loc instead
String loc2 = new String(locbytes, "UTF-8");
String loc=con.getHeaderField(“位置”);
byte[]locbytes=新字节[loc.length()];
对于(int index=0;index
将伪字符串(其中每个字符都有web服务器发送的字节值)转换回字节数组。然后使用适当的字符集将字节数组转换回字符串。现在使用loc2作为URL打开一个新连接
也许有更好的方法可以做到这一点,但我还没有检查源代码实现,以找出一种方法来告诉HttpURLConnection类将头值视为UTF-8编码。据我所知,当其值为UTF-8编码时,Java没有处理位置头
00e0 65 70 2d 61 6c 69 76 65 0d 0a 4c 6f 63 61 74 69 ep-alive ..Locati
00f0 6f 6e 3a 20 68 74 74 70 3a 2f 2f 77 77 77 2e 64 on: http ://www.d
0100 61 6e 64 79 2d 6d 61 67 61 7a 69 6e 65 2e 63 6f andy-mag azine.co
0110 6d 2f 6c 61 2d 67 72 69 66 66 65 2d 64 65 2d 6c m/la-gri ffe-de-l
0120 61 2d 74 6f 75 72 2d 64 e2 80 99 61 72 67 65 6e a-tour-d ...argen
0130 74 0d 0a 0d 0a 30 0d 0a 0d 0a t....0.. ..
URL应该看起来像…/la-griffe-de-la-tour-d'argent。请注意,在上一句中,我使用的是ASCII单引号字符。但是,网站没有使用单引号字符,而是选择使用unicode字符
00002019 RIGHT SINGLE QUOTATION MARK
Glyph: ’
UTF-8: E2 80 99
wireshark跟踪显示返回的位置标头已编码此字符UTF-8
00e0 65 70 2d 61 6c 69 76 65 0d 0a 4c 6f 63 61 74 69 ep-alive ..Locati
00f0 6f 6e 3a 20 68 74 74 70 3a 2f 2f 77 77 77 2e 64 on: http ://www.d
0100 61 6e 64 79 2d 6d 61 67 61 7a 69 6e 65 2e 63 6f andy-mag azine.co
0110 6d 2f 6c 61 2d 67 72 69 66 66 65 2d 64 65 2d 6c m/la-gri ffe-de-l
0120 61 2d 74 6f 75 72 2d 64 e2 80 99 61 72 67 65 6e a-tour-d ...argen
0130 74 0d 0a 0d 0a 30 0d 0a 0d 0a t....0.. ..
我不知道这是否合法。网络上肯定有很多关于这方面的问题。不管它是否合法,HttpURLConnection类都不能很好地处理它。呼吁
String loc = con.getHeaderField("Location");
应该已返回字符串http://www.dandy-magazine.com/la-griffe-de-la-tour-d'银色
在d
和argent
之间有一个字符(2019)。相反,它通过将这3个UTF-8字节中的每一个哑巴转换为字符(E280 99)来返回无效字符串。此时,“loc”字符串是无用的。它不是有效的unicode字符串
以下是一个可能有帮助的解决方法:
String loc = con.getHeaderField("Location");
byte [] locbytes = new byte[loc.length()];
for (int index = 0; index < locbytes.length; index++)
{
locbytes[index] = (byte) loc.charAt(index);
}
// use this loc instead
String loc2 = new String(locbytes, "UTF-8");
String loc=con.getHeaderField(“位置”);
byte[]locbytes=新字节[loc.length()];
对于(int index=0;index
将伪字符串(其中每个字符都有web服务器发送的字节值)转换回字节数组。然后使用适当的字符集将字节数组转换回字符串。现在使用loc2作为URL打开一个新连接
可能有更好的方法可以做到这一点,但我还没有检查源代码实现以找出一种方法来告诉HttpURLConnection类将头值视为UTF-8编码。小心使用正确的字符集编码。您发布的第一个链接可能是用iso 8859-1编码的,而第二个链接是用unicode.hi编码的,供评论使用。我稍微澄清了这个问题。基本上,我的问题是,当我想从java和web浏览器访问同一个站点时,会得到不同的重定向结果。我怀疑问题可能出在字符编码上,但是我怎么知道使用了什么编码呢?如何设置它?请小心使用正确的字符集编码。您发布的第一个链接可能是用iso 8859-1编码的,而第二个链接是用unicode.hi编码的,供评论使用。我稍微澄清了这个问题。基本上,我的问题是,当我想从java和web浏览器访问同一个站点时,会得到不同的重定向结果。我怀疑问题可能出在字符编码上,但是我怎么知道使用了什么编码呢?我该怎么设置呢?
00e0 65 70 2d 61 6c 69 76 65 0d 0a 4c 6f 63 61 74 69 ep-alive ..Locati
00f0 6f 6e 3a 20 68 74 74 70 3a 2f 2f 77 77 77 2e 64 on: http ://www.d
0100 61 6e 64 79 2d 6d 61 67 61 7a 69 6e 65 2e 63 6f andy-mag azine.co
0110 6d 2f 6c 61 2d 67 72 69 66 66 65 2d 64 65 2d 6c m/la-gri ffe-de-l
0120 61 2d 74 6f 75 72 2d 64 e2 80 99 61 72 67 65 6e a-tour-d ...argen
0130 74 0d 0a 0d 0a 30 0d 0a 0d 0a t....0.. ..