任何有关对未编码的URL执行URLDecoder的问题?

问题描述:

当前将URLEncoder和URLDecoder合并到一些代码中。 有很多已保存的URL将由URLDecoder例程处理,该例程最初未由URLEncoder例程处理。任何有关对未编码的URL执行URLDecoder的问题?

根据一些测试,它不会出现会有问题,但授予我没有测试过所有的情况。

我注意到一些像'/'这样的字符,即使最初没有编码,通常会得到编码的字符也会被解码例程处理。

这导致我过于简单的分析。看来URLDecoder例程主要检查'&'的URL和接下来的2个字节(使用UTF-8)。只要在之前保存的关闭网址中没有任何'&',那么在由URLDecoder例程处理时不应该存在问题。那个听起来是对的吗?

+0

我假设你的意思是“%”而不是“&”,对吧? :) –

+0

是的,我做到了。 Oooops。 –

是的,虽然它适用于“简单”情况,但如果对包含某些特殊字符的未编码URL调用URLDecoder.decode,您可能会遇到a)例外情况或b)意外行为。

请看下面的例子:它会抛出一个java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern的第三个测试,它会改变无一例外的URL第二个测试(而普通的编码/解码工作没有问题):

import java.net.URLDecoder; 
import java.net.URLEncoder; 

public class Test { 
    public static void main(String[] args) throws Exception { 
     test("http://www.foo.bar/"); 
     test("http://www.foo.bar/?q=a+b"); 
     test("http://www.foo.bar/?q=äöüß%"); // Will throw exception 
    } 

    private static void test(String url) throws Exception { 
     String encoded = URLEncoder.encode(url, "UTF-8"); 
     String decoded = URLDecoder.decode(encoded, "UTF-8"); 
     System.out.println("encoded: " + encoded); 
     System.out.println("decoded: " + decoded); 
     System.out.println(URLDecoder.decode(decoded, "UTF-8")); 
    } 
} 

输出(注意+符号怎么消失):

encoded: http%3A%2F%2Fwww.foo.bar%2F 
decoded: http://www.foo.bar/ 
http://www.foo.bar/ 
encoded: http%3A%2F%2Fwww.foo.bar%2F%3Fq%3Da%2Bb 
decoded: http://www.foo.bar/?q=a+b 
http://www.foo.bar/?q=a b 
encoded: http%3A%2F%2Fwww.foo.bar%2F%3Fq%3D%C3%A4%C3%B6%C3%BC%C3%9F%25 
decoded: http://www.foo.bar/?q=äöüß% 
Exception in thread "main" java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern 
    at java.net.URLDecoder.decode(Unknown Source) 
    at Test.test(Test.java:16) 

javadoc of URLDecoder为两种情况,以及:

  • 加号“+”被转换为空格字符“”。
  • “%xy”形式的序列将被视为表示一个字节,其中xy是8位的两位十六进制表示形式。 然后,连续包含这些字节序列中的一个或多个的所有子字符串将被其编码为 将导致那些连续字节的字符替换。可以指定用于对这些字符进行解码的编码方案,或者如果未指定,则将使用平台的默认编码。

如果你确信你的未编码的网址不包含+%话,我会说这是安全地调用URLDecoder.decode。否则,我建议实施额外的检查,例如尝试解码并与原始比较(参见this question on SO)。