url重定向中的Java HttpUrlConnection国际字符

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中(重定向

我在获取某些网站的内容时遇到问题。当我尝试导航到重定向到另一个包含国际字符的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.. ..