URI getRawQuery 与 getQuery
URI getRawQuery vs getQuery
我认为使用 getQuery loses information, is dangerous and that instead only getRawQuery should be used, and that any query parameter values that are known to be encoded should be manually decoded (once the raw query is split on the &
characters) with URLDecoder.
恰当的例子:假设您有 URL www.example.com
和两个查询参数:
- 一个参数
url
,值为=www.otherexample.com?b=2&c=3
- 一个不起眼的参数
d
,值为 4。
参数 url
应该是 url 编码的,所以您的应用程序看到的 URI 是:
www.example.com?url=www%2Eotherexample%2Ecom%3Fb%3D2%26c%3D3&d=4
现在,如果您使用 getQuery 获取查询部分,您将得到以下内容:
url=www.otherexample.com?b=2&c=3&d=4
请注意,您已经丢失了信息,因为您无法确定 d
是 www.example.com
还是 www.otherexample.com
.
的查询参数
如果您使用 getRawQuery 获取查询部分,您将得到以下内容:
url=www%2Eotherexample%2Ecom%3Fb%3D2%26c%3D3&d=4
这一次,没有丢失任何信息,一切都很好。如果愿意,您可以解析查询部分和 URL-解码 url
参数的值。
我错过了什么吗?
你是对的。
URI.getQuery() 已损坏,您不应该使用它。
奇怪的是,除了您的 post 之外,我找不到任何对此的证实,这让我觉得 URI.getQuery 可能对某些事情有用。但经过我自己的一些测试后,我很确定它不应该被使用,除非你的应用程序的查询字符串不遵循用&符号分隔参数的约定。
编辑 2019 年 11 月 11 日
正如下面的评论所指出的,虽然您可以使用 URI.getRawQuery() 来解决损坏的 URI.getQuery() 方法,但您不能只使用原始查询作为查询多参数 URI 构造函数的参数,因为该构造函数也已损坏。
如果任何查询字符串参数包含与号,则不能使用多参数 URI 构造函数。您可能会争辩说这是一个错误,但预期行为的文档自相矛盾,因此不清楚哪种行为是正确的。多参数构造函数的 javadoc 说 "Any character that is not a legal URI character is quoted"。这意味着不应引用转义的八位字节,因为主要 class 文档将其作为合法字符 ("The set of all legal URI characters consists of the unreserved, reserved, escaped, and other characters") 包含。但更进一步,它记录了观察到的行为,即百分比字符 ('%') 总是被多参数构造函数引用,人们假设它不考虑它是否是转义八位组的一部分。
无论是否承认文档自相矛盾,或者正确的行为应该是什么,几乎可以肯定的是,当前行为永远不会改变。唯一的解决方法是如果您需要 URI 最终包含带引号的 & 符号八位位组“%26”,则不要使用多参数构造函数。在对特殊字符进行自己的编码和引用之后,请改用单参数构造函数。
我认为使用 getQuery loses information, is dangerous and that instead only getRawQuery should be used, and that any query parameter values that are known to be encoded should be manually decoded (once the raw query is split on the &
characters) with URLDecoder.
恰当的例子:假设您有 URL www.example.com
和两个查询参数:
- 一个参数
url
,值为=www.otherexample.com?b=2&c=3
- 一个不起眼的参数
d
,值为 4。
参数 url
应该是 url 编码的,所以您的应用程序看到的 URI 是:
www.example.com?url=www%2Eotherexample%2Ecom%3Fb%3D2%26c%3D3&d=4
现在,如果您使用 getQuery 获取查询部分,您将得到以下内容:
url=www.otherexample.com?b=2&c=3&d=4
请注意,您已经丢失了信息,因为您无法确定 d
是 www.example.com
还是 www.otherexample.com
.
如果您使用 getRawQuery 获取查询部分,您将得到以下内容:
url=www%2Eotherexample%2Ecom%3Fb%3D2%26c%3D3&d=4
这一次,没有丢失任何信息,一切都很好。如果愿意,您可以解析查询部分和 URL-解码 url
参数的值。
我错过了什么吗?
你是对的。 URI.getQuery() 已损坏,您不应该使用它。
奇怪的是,除了您的 post 之外,我找不到任何对此的证实,这让我觉得 URI.getQuery 可能对某些事情有用。但经过我自己的一些测试后,我很确定它不应该被使用,除非你的应用程序的查询字符串不遵循用&符号分隔参数的约定。
编辑 2019 年 11 月 11 日
正如下面的评论所指出的,虽然您可以使用 URI.getRawQuery() 来解决损坏的 URI.getQuery() 方法,但您不能只使用原始查询作为查询多参数 URI 构造函数的参数,因为该构造函数也已损坏。
如果任何查询字符串参数包含与号,则不能使用多参数 URI 构造函数。您可能会争辩说这是一个错误,但预期行为的文档自相矛盾,因此不清楚哪种行为是正确的。多参数构造函数的 javadoc 说 "Any character that is not a legal URI character is quoted"。这意味着不应引用转义的八位字节,因为主要 class 文档将其作为合法字符 ("The set of all legal URI characters consists of the unreserved, reserved, escaped, and other characters") 包含。但更进一步,它记录了观察到的行为,即百分比字符 ('%') 总是被多参数构造函数引用,人们假设它不考虑它是否是转义八位组的一部分。
无论是否承认文档自相矛盾,或者正确的行为应该是什么,几乎可以肯定的是,当前行为永远不会改变。唯一的解决方法是如果您需要 URI 最终包含带引号的 & 符号八位位组“%26”,则不要使用多参数构造函数。在对特殊字符进行自己的编码和引用之后,请改用单参数构造函数。