URLEncoder无法翻译空格字符
我期待
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));
输出:
Hello%20World
(20是空格的ASCIIhex代码)
但是,我得到的是:
Hello+World
我使用错误的方法吗? 什么是我应该使用的正确的方法?
这performance如预期。 URLEncoder
实现HTML规范如何在HTML表单中编码URL。
从javadocs :
该类包含将string转换为application / x-www-form-urlencoded MIME格式的静态方法。
并从HTML规范 :
应用程序/ x-WWW窗体-urlencoded
使用此内容types提交的表单必须编码如下:
- 控制名称和值被转义。 空格字符被replace为“+”
你将不得不取代它,例如:
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));
这个类执行application/x-www-form-urlencoded
types编码而不是百分比编码,因此replace
+
是一个正确的行为。
来自javadoc:
编码string时,应用下列规则:
- 字母数字字符“a”到“z”,“A”到“Z”和“0”到“9”保持不变。
- 特殊字符“。”,“ – ”,“*”和“_”保持不变。
- 空格字符“”被转换成加号“+”。
- 所有其他字符都是不安全的,首先使用某种编码scheme将其转换为一个或多个字节。 然后每个字节由3个字符的string“%xy”表示,其中xy是该字节的两位hex表示。 推荐使用的编码scheme是UTF-8。 但是,出于兼容性原因,如果未指定编码,则使用平台的默认编码。
空格在URL中被编码为%20
,在提交的数据(内容types为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,这只会编码空间。 使用库来代替。
Hello+World
是浏览器如何为GET
请求编码表单数据( application/x-www-form-urlencoded
),这是URI的查询部分的普遍接受forms。
http://host/path/?message=Hello+World
如果您将此请求发送给Java Servlet,则Servlet将正确解码参数值。 通常这里唯一的问题是编码不匹配。
严格地说,在HTTP或URI规范中没有要求使用application/x-www-form-urlencoded
键值对来编码查询部分; 查询部分只需要在Web服务器接受的forms。 在实践中,这不太可能是一个问题。
对URI的其他部分(例如path)使用这种编码通常是不正确的。 在这种情况下,您应该使用RFC 3986中描述的编码scheme。
http://host/Hello%20World
更多在这里 。
编码查询参数
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; }
“+”是正确的。 如果你真的需要%20,那么在之后你自己更换。
查看java.net.URI类。
使用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(); } }
这对我有效
org.apache.catalina.util.URLEncoder ul = new org.apache.catalina.util.URLEncoder().encode("MY URL");
刚刚在Android上也一直在挣扎,设法绊倒Uri.encode(string,string),而具体到android(android.net.Uri)可能是有用的一些。
静态string编码(String s,string允许)
我使用错误的方法吗? 什么是我应该使用的正确方法?
是的,这个方法java.net.URLEncoder.encode没有根据spec( source )将“”转换为“20%”。
空格字符“”被转换成加号“+”。
即使这不是正确的方法,您可以将其修改为: System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replaceAll("\\+", "%20"));
有一个愉快的一天=)。
对URLEncoder使用字符集“ ISO-8859-1
”