Java URI类:构造函数确定查询是否被编码?

时间:2011-04-29 06:32:56

标签: java uri

这种行为是故意的吗?

//create the same URI using two different constructors

URI foo = null, bar = null;
try { 
    //constructor: URI(uri string)
    foo = new URI("http://localhost/index.php?token=4%2F4EzdsSBg_4vX6D5pzvdsMLDoyItB");
} catch (URISyntaxException e) {} 
try { 
    //constructor: URI(scheme, authority, path, query, fragment) 
    bar = new URI("http", "localhost", "/index.php", "token=4%2F4EzdsSBg_4vX6D5pzvdsMLDoyItB", null);
} catch (URISyntaxException e) {}

//the output:
//foo.getQuery() = token=4/4EzdsSBg_4vX6D5pzvdsMLDoyItB
//bar.getQuery() = token=4%2F4EzdsSBg_4vX6D5pzvdsMLDoyItB

URI(string uri)构造函数似乎正在解码URI的查询部分。我认为查询部分应该被编码?为什么其他构造函数不解码查询部分?

2 个答案:

答案 0 :(得分:1)

来自URI JavaDoc

  

单参数构造函数要求引用其参数中的任何非法字符,并保留任何转义的八位字节和其他存在的字符。

     

多参数构造函数引用它们出现的组件所需的非法字符。百分比字符('%')始终由这些构造函数引用。保留任何其他字符。

因此,URI(String)要求您正确编码所有内容,并假设%2F是一个编码的octed,将被解码为/

其他构造函数会对%字符进行重新编码(导致%252F输入%2F),因此在解码后仍然会得到%2F

我假设构造函数之间偏差的目的是允许new URI(otherUri.toString())toString()之类的内容返回完全编码的URI。

答案 1 :(得分:0)

快速分析:

<强> FOO

构造函数解析输入URI并将文字%2F取消引用到/。这就是我们的期望。

<强>巴

使用bar示例中使用的构造函数,片段部分将被视为具有非法字符的原始字符串和编码,其效果为{{1} }被翻译为%2F然后它被解析,现在没有引用的查询部分(再次)%252F

获得的经验:使用第一个构造函数,我们传递符合RFC 2396的URI。其他构造函数使用普通字符串(不带引号的非法字符)和%2F构造符合RFC 2396的表示形式。

Here's a working example on IDEONE (with extra supporting output)