我在期待

System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));

输出:

你好%20世界

(20是ASCII十六进制空格码)

然而,我得到的是:

你好+世界

我用错方法了吗?我应该使用的正确方法是什么?


当前回答

其他答案要么提供手动字符串替换,实际上编码HTML格式的URLEncoder, Apache放弃的URIUtil,或者使用Guava的UrlEscapers。最后一个很好,除了它没有提供解码器。

Apache Commons Lang提供了URLCodec,它根据URL格式rfc3986进行编码和解码。

String encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);

如果您已经在使用Spring,您也可以选择使用它的UriUtils类。

其他回答

这是预期的行为。URLEncoder实现了如何在HTML表单中编码url的HTML规范。

来自javadocs:

该类包含的静态方法 将String转换为 应用程序/ x-www-form-urlencoded MIME 格式。

和来自HTML规范:

应用程序/ x-www-form-urlencoded 使用此内容类型提交的表单 必须编码如下: 控件名称和值被转义。空格字符被替换 通过“+”

你必须更换它,例如:

System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));

试试下面的方法:

添加一个新的依赖项

<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina -->
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-catalina</artifactId>
    <version>10.0.13</version>
</dependency>

现在按照下面的步骤做:

String str = "Hello+World"; // For "Hello World", decoder is not required
// import java.net.URLDecoder;
String newURL = URLDecoder.decode(str, StandardCharsets.UTF_8);
// import org.apache.catalina.util.URLEncoder;
System.out.println(URLEncoder.DEFAULT.encode(newURL, StandardCharsets.UTF_8));

你会得到如下的输出:

Hello%20World

这对我很有效

org.apache.catalina.util.URLEncoder ul = new org.apache.catalina.util.URLEncoder().encode("MY URL");

该类执行application/x-www-form- urlenencoded -type编码,而不是百分比编码,因此替换为+是正确的行为。

从javadoc:

When encoding a String, the following rules apply: The alphanumeric characters "a" through "z", "A" through "Z" and "0" through "9" remain the same. The special characters ".", "-", "*", and "_" remain the same. The space character " " is converted into a plus sign "+". All other characters are unsafe and are first converted into one or more bytes using some encoding scheme. Then each byte is represented by the 3-character string "%xy", where xy is the two-digit hexadecimal representation of the byte. The recommended encoding scheme to use is UTF-8. However, for compatibility reasons, if an encoding is not specified, then the default encoding of the platform is used.

如果您正在使用jetty,那么org.eclipse.jetty.util.URIUtil将解决这个问题。

String encoded_string = URIUtil.encodePath(not_encoded_string).toString();