我期望
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));
输出应该是:
Hello%20World
(20是空格的ASCII十六进制码)
然而我得到的是:
Hello+World
我使用的方法有误吗?应该使用什么正确的方法?
我期望
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));
输出应该是:
Hello%20World
(20是空格的ASCII十六进制码)
然而我得到的是:
Hello+World
我使用的方法有误吗?应该使用什么正确的方法?
这个方法表现正常。 URLEncoder
实现了用于在 HTML 表单中编码 URL 的 HTML 规范。
来自javadocs:
该类包含将字符串转换为应用程序/x-www-form-urlencoded MIME 格式的静态方法。
以及来自HTML 规范:
application/x-www-form-urlencoded
使用此内容类型提交的表单必须进行如下编码:
- 控件名称和值需要进行转义。空格字符被替换为 `+'。
您需要进行替换,例如:
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));
%20
,在表单提交的数据中(内容类型为application/x-www-form-urlencoded),则被编码为+
。你需要使用前者。dependencies {
compile 'com.google.guava:guava:23.0'
// or, for Android:
compile 'com.google.guava:guava:23.0-android'
}
您可以使用UrlEscapers:String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);
不要使用String.replace,这只会对空格进行编码。相反,请使用一个库。
这个类执行的是application/x-www-form-urlencoded
类型的编码,而不是百分比编码,因此用+
替换是一种正确的行为。
根据 javadoc:
在对字符串进行编码时,请遵循以下规则:
- 字母数字字符 "a" 到 "z","A" 到 "Z" 和 "0" 到 "9" 保持不变。
- 特殊字符 "."、"-"、"*" 和 "_" 保持不变。
- 空格字符 " " 转换为加号 "+"。
- 所有其他字符都不安全,并且首先使用某些编码方案将其转换为一个或多个字节。然后,每个字节由三个字符的字符串 "%xy" 表示,其中 xy 是字节的两位十六进制表示法。建议使用 UTF-8 编码方案。但是,出于兼容性原因,如果没有指定编码,则使用平台的默认编码。
url
中,空格应该被解释为 %20
。所以我们需要做 url.replaceAll("\\+", "%20")
吗?如果是 JavaScript,我们不应该使用 escape
函数。而是应该使用 encodeURI
或 encodeURIComponent
。这就是我想的。 - Alston编码查询参数
org.apache.commons.httpclient.util.URIUtil
URIUtil.encodeQuery(input);
或者,如果您想在URI中转义字符
public static String escapeURIPathParam(String input) {
StringBuilder resultStr = new StringBuilder();
for (char ch : input.toCharArray()) {
if (isUnsafe(ch)) {
resultStr.append('%');
resultStr.append(toHex(ch / 16));
resultStr.append(toHex(ch % 16));
} else{
resultStr.append(ch);
}
}
return resultStr.toString();
}
private static char toHex(int ch) {
return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
}
private static boolean isUnsafe(char ch) {
if (ch > 128 || ch < 0)
return true;
return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
}
org.apache.commons.httpclient.util.URIUtil
似乎是解决该问题最有效的方法! - Stéphane AmmarHello+World
是浏览器在进行 GET
请求时对表单数据 (application/x-www-form-urlencoded
) 进行编码的方式,这也是 URI 查询部分的普遍接受形式。
http://host/path/?message=Hello+World
http://host/Hello%20World
更多这里。
如果您想对URI路径组件进行编码,也可以使用标准JDK函数,例如:
public static String encodeURLPathComponent(String path) {
try {
return new URI(null, null, path, null).toASCIIString();
} catch (URISyntaxException e) {
// do some error handling
}
return "";
}
URI类也可以用于编码URI的不同部分或整个URI。
更新:我刚意识到,如果路径中有冒号和斜杠之前的部分不是有效的URI方案,则此方法无法正常工作。
我也在Android上遇到了这个问题,后来偶然发现了Uri.encode(String, String)方法,虽然它是特定于Android的(android.net.Uri),但对于一些人可能会很有用。
static String encode(String s, String allow)
虽然不是一行代码,但你可以使用以下代码:
URL url = new URL("https://some-host.net/dav/files/selling_Rosetta Stone Case Study.png.aes");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
System.out.println(uri.toString());
https://some-host.net/dav/files/selling_Rosetta%20Stone%20Case%20Study.png.aes
uri.toURL().openStream();
- Oliver虽然很老,但是回答很快:
Spring提供了UriUtils - 使用它可以指定如何对URI进行编码以及与之相关的部分,例如:
encodePathSegment
encodePort
encodeFragment
encodeUriVariables
....
我使用它们是因为我们已经在使用Spring,即不需要额外的库!
getForObject
(RestTemplate
的一部分)进行测试请求时,它输出的URL会保留未编码的逗号,但是UriUtils.encode(...)
会对逗号进行编码,这意味着如果我使用UriUtils.encode
的输出,则我的MockRestServiceServer
无法匹配路径。 - IpsRichString encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);