Java和RFC 3986 URI编码

18

是否有一个类可以按照RFC 3986规范对通用的String进行编码?

即: "hello world" => "hello%20world",而不是(RFC 1738)"hello+world"

谢谢。

5个回答


6
如果是一个URL,使用URI。
URI uri = new URI("http", "//hello world", null);
String urlString = uri.toASCIIString();
System.out.println(urlString);

1
只需将第一个参数传递为 null。 - user207421
java.net.URI 实现了 RFC2396 而非 RFC3986;如果混淆使用,将得到不同的规范形式(如小写主机名或非小写主机名)。 - Jurgen Vinju

4

来源:Twitter RFC3986 兼容的编码函数。

该方法接受字符串并将其转换为 RFC3986 特定的编码字符串。

/** The encoding used to represent characters as bytes. */
public static final String ENCODING = "UTF-8";

public static String percentEncode(String s) {
    if (s == null) {
        return "";
    }
    try {
        return URLEncoder.encode(s, ENCODING)
                // OAuth encodes some characters differently:
                .replace("+", "%20").replace("*", "%2A")
                .replace("%7E", "~");
        // This could be done faster with more hand-crafted code.
    } catch (UnsupportedEncodingException wow) {
        throw new RuntimeException(wow.getMessage(), wow);
    }
}

2
scribejava 同样采用该方法,但如果您按照[ RFC 5849(OAuth 1.0)](https://tools.ietf.org/html/rfc5849#section-3.4)给出的示例,则此方法无法正确编码类似 a3=2+q 的参数,因为它将字符串编码为 a3=2%2Bq 而不是 a3=2%20q,因为 URLEncoder 在替换之前对字符串进行了编码。 - Roman Vottner

0
在Spring Web应用程序的情况下,我能够使用这个:

http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html

UriComponentsBuilder.newInstance()
  .queryParam("KEY1", "Wally's crazy empôrium=")
  .queryParam("KEY2", "Horibble % sign in value")
  .build().encode("UTF-8") // or .encode() defaults to UTF-8

返回字符串

?KEY1=Wally's%20crazy%20emp%C3%B4rium%3D&KEY2=Horibble%20%25%20sign%20in%20value

对我最喜欢的网站之一进行交叉检查,结果相同,“URI的百分比编码”。看起来不错。http://rishida.net/tools/conversion/


0

我不知道是否有这样一个类。有一个提供编码的类,但它将“ ”转换为“+”。但您可以使用String类中的replaceAll方法将“+”转换为您想要的内容。

str.repaceAll("+","%20")


1
这不仅仅是关于“+”的问题,而是完全遵循RFC 3986规范,而不是适用于查询参数(需要“+”)的RFC 1738规范。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接