Java 和 RFC 3986 URI 编码

Posted

技术标签:

【中文标题】Java 和 RFC 3986 URI 编码【英文标题】:Java and RFC 3986 URI encoding 【发布时间】:2011-08-17 10:07:53 【问题描述】:

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

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

谢谢

【问题讨论】:

【参考方案1】:

不知道有没有。有一个类提供编码,但它将“”更改为“+”。但是你可以使用String类中的replaceAll方法将“+”转换成你想要的。

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

【讨论】:

这不仅仅是关于“+”,而是完全遵循 RFC 3986 规范,而不是适用于查询参数(需要“+”)的 RFC 1738。【参考方案2】:

如果是url,使用URI

URI uri = new URI("http", "//hello world", null);
String urlString = uri.toASCIIString();
System.out.println(urlString);

【讨论】:

第一个参数传入null即可。【参考方案3】:

解决了这个问题:

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

方法encodeUri

【讨论】:

【参考方案4】:

对于 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/

【讨论】:

【参考方案5】:

来源:推特 符合 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);
    

【讨论】:

scribejava 也使用该方法,但如果您使用RFC 5849 (OAuth 1.0) 中给出的示例,此方法无法正确编码a3=2+q 之类的参数,因为这会将字符串编码为a3=2%2Bq而不是 a3=2%20q 因为 URLEncoder 在替换发生之前对字符串进行编码

以上是关于Java 和 RFC 3986 URI 编码的主要内容,如果未能解决你的问题,请参考以下文章

RFC3986 - 哪些 pchars 需要进行百分比编码?

如何对 RFC 3986 字符串进行转义

当相对 URI 包含空路径时,Java 的 URI.resolve 是不是与 RFC 3986 不兼容?

Java URL 类 getPath()、getQuery() 和 getFile() 与 RFC3986 URI 语法不一致

如何对URL字符串进行百分号编码

urlbase64 编码规则