【问题标题】:How do I encode URI parameter values?如何编码 URI 参数值?
【发布时间】:2010-10-01 10:36:19
【问题描述】:

我想发送一个 URI 作为查询/矩阵参数的值。在将其附加到现有 URI 之前,我需要根据 RFC 2396 对其进行编码。例如,给定输入:

http://google.com/resource?key=value1 & value2

我期望输出:

http%3a%2f%2fgoogle.com%2fresource%3fkey%3dvalue1%2520%26%2520value2

java.net.URLEncoderjava.net.URI 都不会生成正确的输出。 URLEncoder 用于 HTML 表单编码,它与 RFC 2396 不同。URI 没有一次编码单个值的机制,因此它无法知道 value1 和 value2 是同一个键的一部分。

【问题讨论】:

  • 我不确定我是否理解您期望的结果。我会使用 URLEncoder。
  • 根据 Javadoc for URL:“也可以使用 URLEncoder 和 URLDecoder 类,但仅用于 HTML 表单编码,与 RFC2396 中定义的编码方案不同。”
  • @Peter:同意,但后者已经死了。至少有一个投票赞成的答案,因此即使答案在技术上是错误的,它也不会出现在未回答的问题列表中。如果您想提供帮助,请投票为零。
  • 我想知道例如你在你的问题中给出的结果。
  • 抱歉,我删除了关于这是 stackoverflow.com/questions/304806/… 重复的评论

标签: java url rest urlencode rfc2396


【解决方案1】:

Jersey 的 UriBuilder 根据需要使用 application/x-www-form-urlencoded 和 RFC 3986 对 URI 组件进行编码。根据Javadoc

根据查询参数的 application/x-www-form-urlencoded 媒体类型规则和所有其他组件的 RFC 3986 规则,构建器方法执行相应 URI 组件中不允许的字符的上下文编码。请注意,只有特定组件中不允许的字符才需要进行编码,例如,提供给路径方法之一的路径可能包含矩阵参数或多个路径段,因为分隔符是合法字符并且不会被编码。在允许的情况下,百分比编码值也会被识别,并且不会被双重编码。

【讨论】:

  • 网址无法访问。但是download.oracle.com/javaee/6/api/javax/ws/rs/core/… 已经可以使用了
  • 您是如何使用 UriBuilder 生成上述预期输出的?我不知道如何告诉它对“?”之前的部分进行编码。谢谢!
  • 如果你不使用 JAX-RS 而使用 Spring,你可以使用 Spring 的 UriUtils
  • @tbh,我想说的是,如果您使用 UriBuilder,它将对需要为您编码的内容进行编码。如果您想手动编码文本部分,那么stackoverflow.com/questions/304806/… 将起作用。或者,你可以使用 UriBuilder.fromPath("host/").matrixParam("key", "google.com/resource?key=value1 & value2").build() 你会得到 "host/…"。
  • 谨防将 UriBuilder 用于不使用带有花括号的 JAX-RS 参数方案的“免费”URL。即使它可能是一个奇异的值,试试这个:UriBuilder.fromPath("http://www.query.example/").queryParam("key", "{val}").build(); 会失败。 "http://www.query.example?key=" + URLEncoder.encode("{val}", "UTF-8") 会起作用。
【解决方案2】:

你也可以使用 Spring 的UriUtils

【讨论】:

    【解决方案3】:

    我没有足够的声誉来评论答案,但我只想指出,单独下载 JSR-311 api 是行不通的。您需要下载参考实现 (jersey)。

    当 api 试图在运行时寻找实现时,只有从 JSR 页面下载 api 会给你一个 ClassNotFoundException。

    【讨论】:

    • 具体来说,您需要 jsr311-api、jersey-server 和 jersey-core jars。
    【解决方案4】:

    我自己写的,很短,超级简单,喜欢的话可以复制一下: http://www.dmurph.com/2011/01/java-uri-encoder/

    【讨论】:

    • 我猜人们对喜欢这个解决方案犹豫不决,因为他们可能担心它会有错误等。它看起来很全面,并且已经解决了几个错误,所以我想我会尝试一下. Java 和 Objective C 都没有内置例程来进行这种编码,这只是......令人困惑
    • 嗯,这是针对 URI 本身而不是针对参数?
    • 空格应该被转义:) 它只包含数字、字母和“标记”字符为未转义
    • @HerrGrumps 什么? Obj-C def 早就内置了 URL 编码。
    • @Jadar 哦?好的,也许我在 Obj-C 和/或 Java 上没有它是错误的 - 抱歉 :) 作为参考,也许您可​​以发布带有一些类/方法名称的回复,以防它可能会帮助可能不知道去哪里的人看起来(像我;))
    【解决方案5】:

    看来来自 Google GData-java-client 的 CharEscapers 有你想要的。它具有 uriPathEscaper 方法、uriQueryStringEscaper 和通用 uriEscaper。 (全部返回执行实际转义的 Escaper 对象)。 Apache 许可证。

    【讨论】:

    • 不幸的是它使用了一些其他的类和接口,但我认为你可以修改它以满足你的需要。
    • “一定有比这更简单的方法”。令我惊讶的是,这个常见的用例(构建 URI)并不容易做到。 java.net.URI 应该做得更好。
    • 我对这个区域的混乱程度感到惊讶(老实说,我什至不知道有特殊的 URI 编码之类的东西......我学到了一些东西)。
    • 彼得,我刚刚意识到这可能会起作用:jsr311.dev.java.net/nonav/releases/1.0/javax/ws/rs/core/… 我正在为我的应用程序使用 JAX-RS。我会尝试并报告。
    • 彼得,请添加以下内容,我会将其标记为已接受的答案:“ javax.ws.rs.core.UriBuilder 会做你想做的事:jsr311.dev.java.net/nonav/releases/1.0/javax/ws/rs/core/…
    【解决方案6】:

    我认为URI class 是您正在寻找的那个。

    【讨论】:

    • 它没有帮助,因为它希望我传递一个完整的查询字符串。它无法知道字符串的哪一部分需要编码,哪一部分不需要。我需要一个接收原始参数值并传递 URL 编码形式的方法。
    • 是的。如果问题被投票一次,Stackoverflow 会将问题标记为已回答。这个答案被一个人投了赞成票,而我投了反对票。它仍然将我的问题标记为上次我检查时已回答。
    • 我的错。你说得对。我认为“赞成的答案”是指......你知道,左边有一个正数的答案......
    • 我会更新问题。无法对完整 URI 进行编码的原因是,如果我传入“key=value with spaces&still part of value”,则构造函数无法知道值的开始和结束位置。
    【解决方案7】:

    嗯,我知道你已经放弃了 URLEncoder,但不管文档怎么说,我还是决定试一试。

    你说:

    例如,给定一个输入:

    http://google.com/resource?key=value

    我期望输出:

    http%3a%2f%2fgoogle.com%2fresource%3fkey%3dvalue

    所以:

    C:\oreyes\samples\java\URL>type URLEncodeSample.java
    import java.net.*;
    
    public class URLEncodeSample {
        public static void main( String [] args ) throws Throwable {
            System.out.println( URLEncoder.encode( args[0], "UTF-8" ));
        }
    }
    
    C:\oreyes\samples\java\URL>javac URLEncodeSample.java
    
    C:\oreyes\samples\java\URL>java URLEncodeSample "http://google.com/resource?key=value"
    http%3A%2F%2Fgoogle.com%2Fresource%3Fkey%3Dvalue
    

    正如预期的那样。

    这会有什么问题?

    【讨论】:

    • 与RFC2396类似但又不一样。例如,尝试编码空格。 URLEncoder 会将其编码为“+”,URI 需要 %20。还有其他区别。
    • 好的,但你不会是这样编码的:“value with space”而是“value+with+space”:
    • like:java URLEncodeSample "google.com/resource?key=value+with+spaces" http%3A%2F%2Fgoogle.com%2Fresource%3Fkey%3Dvalue%2Bwith%2Bspaces
    • 对于 RFC 2369,必须遵循一大堆规则。与其用输入字符串玩游戏,我宁愿找到一个能正确编码的类。
    • 你打算做什么?知道这将非常有帮助,以便为您提供正确的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2020-01-04
    • 1970-01-01
    • 2011-12-29
    相关资源
    最近更新 更多