【问题标题】:URI getRawQuery vs getQueryURI getRawQuery 与 getQuery
【发布时间】:2018-02-13 22:05:39
【问题描述】:

我认为使用getQuery 会丢失信息,是危险的,而应该只使用getRawQuery,并且任何已知被编码的查询参数值都应该手动解码(一旦原始查询被拆分& 字符)和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

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

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

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

这一次,没有信息丢失,一切都很好。您可以根据需要解析查询部分并对 url 参数的值进行 URL 解码。

我错过了什么吗?

【问题讨论】:

    标签: java uri


    【解决方案1】:

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

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

    编辑 2019 年 11 月 11 日

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

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

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

    【讨论】:

    • 对于任何对 Oracle 所说的内容感兴趣的人,我已经为此问题打开了一个错误报告:bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8214423
    • 情况更糟。使用 getRawQuery() 也无济于事。 ======= URI u = new URI("http://localhost/?x=Q%26A&y=2"); URI u2 = new 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 双重编码
    • 更新了我的答案以注意 URI 构造函数的这种限制。谢谢@GeorgeDimitrov
    猜你喜欢
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 2014-05-25
    • 2013-04-06
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多