URI getRawQuery 与 getQuery

Mar*_*tus 9 java uri

我认为使用getQuery会丢失信息,是危险的,应该只使用getRawQuery,并且应该&使用URLDecoder手动解码任何已知被编码的查询参数值(一旦原始查询在字符上拆分)。

举个例子:假设你的 URLwww.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

请注意,您已经丢失了信息,因为您无法确定是否dwww.example.com或 的查询参数www.otherexample.com

相反,如果您使用getRawQuery获取查询部分,则会得到以下信息:

url=www%2Eotherexample%2Ecom%3Fb%3D2%26c%3D3&d=4

这一次,没有信息丢失,一切都很好。url如果您愿意,您可以解析查询部分并对参数值进行 URL 解码。

我错过了什么吗?

Mar*_*tin 7

你是对的。URI.getQuery() 已损坏,您不应使用它。

奇怪的是,除了您的帖子之外,我找不到对此的任何确认,这让我觉得 URI.getQuery 可能对某些事情有用。但是经过我自己的一些测试后,我很确定它不应该被使用,除非您的应用程序的查询字符串不遵循用&符号分隔参数的约定。

编辑 11/11/2019

正如下面的评论所指出的,虽然您可以使用 URI.getRawQuery() 来解决损坏的 URI.getQuery() 方法,但您不能只使用原始查询作为多参数 URI 构造函数的查询参数,因为那个构造函数也坏了。

如果任何查询字符串参数包含与号,则不能使用多参数 URI 构造函数。您可能会争辩说这是一个错误,但预期行为的文档自相矛盾,因此不清楚哪种行为是正确的。多参数构造函数的 javadoc 说“任何不是合法 URI 字符的字符都被引用”。这意味着不应引用转义八位字节,因为主类文档将其包含为合法字符(“所有合法 URI 字符集由未保留、保留、转义和其他字符组成”)。但更进一步,它记录了观察到的行为,即百分比字符 ('%') 总是被多参数构造函数引用,人们假设它不考虑它是否是转义八位字节的一部分。

无论是否承认文档是矛盾的,或者正确的行为应该是什么,几乎可以肯定当前的行为永远不会改变。如果您需要 URI 最终包含带引号的 & 八位字节“%26”,则唯一的解决方法是不使用多参数构造函数。在完成自己的编码和特殊字符引用之后,请改用单参数构造函数。

  • 对于任何对 Oracle 所说的内容感兴趣的人,我已经针对此问题打开了错误报告:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8214423 (2认同)
  • 情况更糟。使用 getRawQuery() 也没有帮助。`======= URI u = 新的 URI("http://localhost/?x=Q%26A&y=2"); URI u2 = 新的 URI(u.getScheme()、u.getUserInfo()、u.getHost()、u.getPort()、u.getPath()、u.getRawQuery()、u.getFragment()); System.out.println(u2);` 打印:`http://localhost/?x=Q%2526A&y=2` **双**编码 (2认同)