Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java解析URL会给我URL中错误的编码字符_Java_Character Encoding_Url Encoding - Fatal编程技术网

用Java解析URL会给我URL中错误的编码字符

用Java解析URL会给我URL中错误的编码字符,java,character-encoding,url-encoding,Java,Character Encoding,Url Encoding,当我执行以下操作时: try { URL url = new URL(urlAsString); //using proxy may increase latency HttpURLConnection hConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); // force no follow hConn.setInstanceFollowRedirects(false);

当我执行以下操作时:

try {
    URL url = new URL(urlAsString);
    //using proxy may increase latency
    HttpURLConnection hConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
    // force no follow
    hConn.setInstanceFollowRedirects(false);
    // the program doesn't care what the content actually is       
    hConn.setRequestMethod("HEAD");
    // default is 0 => infinity waiting
    hConn.setConnectTimeout(timeout);
    hConn.setReadTimeout(timeout);
    hConn.connect();
    int responseCode = hConn.getResponseCode();
    hConn.getInputStream().close();
    if (responseCode == HttpURLConnection.HTTP_OK)
        return urlAsString;

    String loc = hConn.getHeaderField("Location");
    if (responseCode == HttpURLConnection.HTTP_MOVED_PERM && loc != null)
        return loc.replaceAll(" ", "+");

} catch (Exception ex) {
}
return "";
对于该url:我得到

-重新设计——然后一切都会破裂/

这是错误的。Firefox决心


代码中有什么错误?

没有错误。不同之处在于,m-破折号在不同的编码中表示不同。因此,如果Firefox使用的编码与您的程序不同,您将看到不同的字符

在你的情况下,两者都是正确的。这只是编码的问题。在Java中,您使用UTF-8,即:;而您在FF中看到的似乎是ISO-8859

如果要在Java中生成与Firefox相同的结果,请尝试以下操作:

System.out.print(URLEncoder.encode(loc.replace(" ", "+"), "ISO-8859-1"));

它将打印您在Firefox中看到的内容。(显然,它也会对
/
进行编码。但只是为了演示一下)

没有什么错。不同之处在于,m-破折号在不同的编码中表示不同。因此,如果Firefox使用的编码与您的程序不同,您将看到不同的字符

在你的情况下,两者都是正确的。这只是编码的问题。在Java中,您使用UTF-8,即:;而您在FF中看到的似乎是ISO-8859

如果要在Java中生成与Firefox相同的结果,请尝试以下操作:

System.out.print(URLEncoder.encode(loc.replace(" ", "+"), "ISO-8859-1"));
它将打印您在Firefox中看到的内容。(显然,它也将编码
/
。但仅用于演示)

根据,HTTP头值通常应使用ISO-8859-1进行编码

在这里,bit.ly发送了一个错误的响应-Location:header使用UTF-8编码,因此em破折号字符由三个单独的字节(0xe2、0x80、0x94)表示

HttpURLConnection
使用ISO-8859-1对字节进行解码,使它们变成三个字符(
和两个未定义的字符),但看起来好像在应用URL编码之前使用UTF-8对它们进行了重新编码(每个字符产生两个字节,因为这三个字符的值均大于等于0x80)

Firefox很可能将数据视为ISO-8859-1;然后,当稍后应用URL编码时,问题将自行消除

您也可以通过URL编码
getHeaderField()
返回的值来实现这一点;由于Unicode范围U+0080到U+00FF与ISO-8859-1字节范围0x80-0xFF相同,因此可以通过将非ASCII字符强制转换为
int
值对其进行编码:

/**
 * Takes a URI that was decoded as ISO-8859-1 and applies percent-encoding
 * to non-ASCII characters. Workaround for broken origin servers that send
 * UTF-8 in the Location: header.
 */
static String encodeUriFromHeader(String uri) {
    StringBuilder sb = new StringBuilder();

    for(char ch : badLocation.toCharArray()) {
        if(ch < (char)128) {
            sb.append(ch);
        } else {
            // this is ONLY valid if the uri was decoded using ISO-8859-1
            sb.append(String.format("%%%02X", (int)ch));
        }
    }

    return sb.toString();
}
/**
*获取已解码为ISO-8859-1的URI并应用百分比编码
*转换为非ASCII字符。发送数据的损坏源服务器的解决方法
*UTF-8位于位置:标头。
*/
静态字符串encodeUriFromHeader(字符串uri){
StringBuilder sb=新的StringBuilder();
for(char ch:badLocation.toCharArray()){
if(ch<(char)128){
某人附加(ch);
}否则{
//这仅在使用ISO-8859-1解码uri时有效
sb.append(String.format(“%%%02X”,(int)ch));
}
}
使某人返回字符串();
}
根据,HTTP头值通常应使用ISO-8859-1编码

在这里,bit.ly发送了一个错误的响应-Location:header使用UTF-8编码,因此em破折号字符由三个单独的字节(0xe2、0x80、0x94)表示

HttpURLConnection
使用ISO-8859-1对字节进行解码,使它们变成三个字符(
和两个未定义的字符),但看起来好像在应用URL编码之前使用UTF-8对它们进行了重新编码(每个字符产生两个字节,因为这三个字符的值均大于等于0x80)

Firefox很可能将数据视为ISO-8859-1;然后,当稍后应用URL编码时,问题将自行消除

您也可以通过URL编码
getHeaderField()
返回的值来实现这一点;由于Unicode范围U+0080到U+00FF与ISO-8859-1字节范围0x80-0xFF相同,因此可以通过将非ASCII字符强制转换为
int
值对其进行编码:

/**
 * Takes a URI that was decoded as ISO-8859-1 and applies percent-encoding
 * to non-ASCII characters. Workaround for broken origin servers that send
 * UTF-8 in the Location: header.
 */
static String encodeUriFromHeader(String uri) {
    StringBuilder sb = new StringBuilder();

    for(char ch : badLocation.toCharArray()) {
        if(ch < (char)128) {
            sb.append(ch);
        } else {
            // this is ONLY valid if the uri was decoded using ISO-8859-1
            sb.append(String.format("%%%02X", (int)ch));
        }
    }

    return sb.toString();
}
/**
*获取已解码为ISO-8859-1的URI并应用百分比编码
*转换为非ASCII字符。发送数据的损坏源服务器的解决方法
*UTF-8位于位置:标头。
*/
静态字符串encodeUriFromHeader(字符串uri){
StringBuilder sb=新的StringBuilder();
for(char ch:badLocation.toCharArray()){
if(ch<(char)128){
某人附加(ch);
}否则{
//这仅在使用ISO-8859-1解码uri时有效
sb.append(String.format(“%%%02X”,(int)ch));
}
}
使某人返回字符串();
}

事实上,情况正好相反。不正确的一个用ISO8859-1(或CP1252)编码,正确的一个用UTF-8编码。@BalusC-hmm。。。我没听懂你的意思。我说的是UTF-8是推荐的——这是正确的。FF可能使用依赖于平台的编码.Hmmh,但是为什么我需要对url位置进行编码呢?它不是已经编码了吗?是的,这个额外的编码不起作用。但我想我应该把标题读成ISO-8859-1,以获得正确的位置。hmmh,hConn.getContentType()是text/html;charset=utf-8实际上是相反的。不正确的一个用ISO8859-1(或CP1252)编码,正确的一个用UTF-8编码。@BalusC-hmm。。。我没听懂你的意思。我说的是UTF-8是推荐的——这是正确的。FF可能使用依赖于平台的编码.Hmmh,但是为什么我需要对url位置进行编码呢?它不是已经编码了吗?是的,这个额外的编码不起作用。但我想我应该把标题读成ISO-8859-1,以获得正确的位置。hmmh,hConn.getContentType()是text/html;charset=utf-8我是否需要为该位置应用url编码?顺便说一句:我应用编码是偶然的。我将url复制到firefox的url栏中,然后从那里粘贴到这个问题中。Firefox应用了编码。。。我把它修好了post@SimonJ所以我应该向bit.ly或c提交一份bug报告