我期待
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));
输出:
Hello%20World
(20是空格的ASCII十六进制代码)
然而,我得到的是:
Hello+World
我使用了错误的方法吗?我应该使用的正确方法是什么?
答案 0 :(得分:202)
这表现得如预期。 URLEncoder
实现了HTML规范,以便如何对HTML表单中的URL进行编码。
来自javadocs:
此类包含静态方法 将String转换为 application / x-www-form-urlencoded MIME 格式。
application / x-www-form-urlencoded
使用此内容类型提交的表单 必须编码如下:
- 转义控件名称和值。空格字符被替换 通过`+'
醇>
您必须更换它,例如:
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));
答案 1 :(得分:41)
空间在URL中编码为%20
,在表单提交的数据中编码为+
(内容类型application / x-www-form-urlencoded)。你需要前者。
使用Guava:
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,这只会对空间进行编码。改为使用库。
答案 2 :(得分:25)
此类执行application/x-www-form-urlencoded
- 类型编码而非百分比编码,因此将替换为
+
是正确的行为。
来自javadoc:
对String进行编码时,以下规则适用:
- 字母数字字符“a”到“z”,“A”到“Z”和“0”到“9”保持不变。
- 特殊字符“。”,“ - ”,“*”和“_”保持不变。
- 空格字符“”将转换为加号“+”。
- 所有其他字符都不安全,首先使用某种编码方案将其转换为一个或多个字节。然后每个字节由3个字符的字符串“%xy”表示,其中xy是字节的两位十六进制表示。建议使用的编码方案是UTF-8。但是,出于兼容性原因,如果未指定编码,则使用平台的默认编码。
答案 3 :(得分:13)
编码查询参数
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;
}
答案 4 :(得分:11)
Hello+World
是浏览器对application/x-www-form-urlencoded
请求的表单数据(GET
)进行编码的方式,这是URI的查询部分的普遍接受的形式。
http://host/path/?message=Hello+World
如果将此请求发送到Java servlet,则servlet将正确解码参数值。通常,这里唯一有问题的是编码不匹配。
严格地说,HTTP或URI规范中没有要求使用application/x-www-form-urlencoded
键值对来编码查询部分;查询部分只需要是Web服务器接受的形式。在实践中,这不太可能是一个问题。
将此编码用于URI的其他部分(例如路径)通常是不正确的。在这种情况下,您应该使用RFC 3986中描述的编码方案。
http://host/Hello%20World
更多here。
答案 5 :(得分:4)
“+”是正确的。如果你真的需要%20,那么之后自己更换加号。
答案 6 :(得分:4)
其他答案要么提供手动字符串替换,URLEncoder实际编码为HTML格式,Apache为abandoned URIUtil,要么使用Guava的UrlEscapers。最后一个很好,除了它没有提供解码器。
Apache Commons Lang提供URLCodec,它根据URL格式rfc3986对和进行编码。
String encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);
如果您已经在使用Spring,那么您也可以选择使用其 UriUtils类。
答案 7 :(得分:2)
这对我有用
org.apache.catalina.util.URLEncoder ul = new org.apache.catalina.util.URLEncoder().encode("MY URL");
答案 8 :(得分:2)
刚刚在Android上苦苦挣扎,设法偶然发现Uri.encode(String,String),而特定于android(android.net.Uri)可能对某些人有用。
static String encode(String s,String allow)
答案 9 :(得分:1)
如果您使用码头,那么org.eclipse.jetty.util.URIUtil
将解决问题。
String encoded_string = URIUtil.encodePath(not_encoded_string).toString();
答案 10 :(得分:0)
查看java.net.URI类。
答案 11 :(得分:0)
我使用了错误的方法吗?我应该使用的正确方法是什么?
是的,这个方法java.net.URLEncoder.encode没有用于转换&#34; &#34;到&#34; 20%&#34;根据规范(source)。
空间角色&#34; &#34;转换为加号&#34; +&#34;。
即使这不是正确的方法,您可以将其修改为:System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replaceAll("\\+", "%20"));
有一个美好的一天=)。
答案 12 :(得分:0)
尽管很老,但反应很快:
Spring提供了UriUtils-通过它您可以指定编码方式以及与URI相关的部分,例如
encodePathSegment
encodePort
encodeFragment
encodeUriVariables
....
我之所以使用它们,是因为我们已经在使用Spring,即不需要附加库!
答案 13 :(得分:0)
如果你想对 URI 路径组件进行编码,你也可以使用 standard 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 进行编码。
答案 14 :(得分:0)
它不是单行的,但您可以使用:
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
答案 15 :(得分:-1)
USE MyUrlEncode.URLencoding(String url,String enc)来处理问题
public class MyUrlEncode {
static BitSet dontNeedEncoding = null;
static final int caseDiff = ('a' - 'A');
static {
dontNeedEncoding = new BitSet(256);
int i;
for (i = 'a'; i <= 'z'; i++) {
dontNeedEncoding.set(i);
}
for (i = 'A'; i <= 'Z'; i++) {
dontNeedEncoding.set(i);
}
for (i = '0'; i <= '9'; i++) {
dontNeedEncoding.set(i);
}
dontNeedEncoding.set('-');
dontNeedEncoding.set('_');
dontNeedEncoding.set('.');
dontNeedEncoding.set('*');
dontNeedEncoding.set('&');
dontNeedEncoding.set('=');
}
public static String char2Unicode(char c) {
if(dontNeedEncoding.get(c)) {
return String.valueOf(c);
}
StringBuffer resultBuffer = new StringBuffer();
resultBuffer.append("%");
char ch = Character.forDigit((c >> 4) & 0xF, 16);
if (Character.isLetter(ch)) {
ch -= caseDiff;
}
resultBuffer.append(ch);
ch = Character.forDigit(c & 0xF, 16);
if (Character.isLetter(ch)) {
ch -= caseDiff;
}
resultBuffer.append(ch);
return resultBuffer.toString();
}
private static String URLEncoding(String url,String enc) throws UnsupportedEncodingException {
StringBuffer stringBuffer = new StringBuffer();
if(!dontNeedEncoding.get('/')) {
dontNeedEncoding.set('/');
}
if(!dontNeedEncoding.get(':')) {
dontNeedEncoding.set(':');
}
byte [] buff = url.getBytes(enc);
for (int i = 0; i < buff.length; i++) {
stringBuffer.append(char2Unicode((char)buff[i]));
}
return stringBuffer.toString();
}
private static String URIEncoding(String uri , String enc) throws UnsupportedEncodingException { //对请求参数进行编码
StringBuffer stringBuffer = new StringBuffer();
if(dontNeedEncoding.get('/')) {
dontNeedEncoding.clear('/');
}
if(dontNeedEncoding.get(':')) {
dontNeedEncoding.clear(':');
}
byte [] buff = uri.getBytes(enc);
for (int i = 0; i < buff.length; i++) {
stringBuffer.append(char2Unicode((char)buff[i]));
}
return stringBuffer.toString();
}
public static String URLencoding(String url , String enc) throws UnsupportedEncodingException {
int index = url.indexOf('?');
StringBuffer result = new StringBuffer();
if(index == -1) {
result.append(URLEncoding(url, enc));
}else {
result.append(URLEncoding(url.substring(0 , index),enc));
result.append("?");
result.append(URIEncoding(url.substring(index+1),enc));
}
return result.toString();
}
}
答案 16 :(得分:-3)
为URLEncoder使用字符集“ISO-8859-1
”