나는 기대하고있다
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));
출력 :
Hello%20World
(20은 공백을위한 ASCII 16 진 코드입니다)
그러나 내가 얻는 것은 다음과 같습니다.
Hello+World
잘못된 방법을 사용하고 있습니까? 사용해야하는 올바른 방법은 무엇입니까?
나는 기대하고있다
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8"));
출력 :
Hello%20World
(20은 공백을위한 ASCII 16 진 코드입니다)
그러나 내가 얻는 것은 다음과 같습니다.
Hello+World
잘못된 방법을 사용하고 있습니까? 사용해야하는 올바른 방법은 무엇입니까?
답변:
이것은 예상대로 동작합니다. URLEncoder구현 HTML 양식에서 어떻게 인코딩 된 URL에 대한 HTML 사양.
로부터 의 javadoc :
이 클래스에는 문자열을 application / x-www-form-urlencoded MIME 형식으로 변환하기위한 정적 메소드가 포함되어 있습니다.
그리고 HTML 사양에서 :
application / x-www-form-urlencoded
이 컨텐츠 유형으로 제출 된 양식은 다음과 같이 인코딩되어야합니다.
- 제어 이름 및 값이 이스케이프됩니다. 공백 문자는`+ '로 대체됩니다
다음과 같이 교체해야합니다.
System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));
t.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replace("\\+", "%20"));
공백은 %20URL 로 인코딩 되고+ 제출 된 데이터 (콘텐츠 유형 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는 퍼센트 인코딩이 아닌 -type 인코딩을 수행 하므로으로 대체 하는 +것이 올바른 동작입니다.
javadoc에서 :
문자열을 인코딩 할 때 다음 규칙이 적용됩니다.
- 영숫자 문자 "a"~ "z", "A"~ "Z"및 "0"~ "9"는 동일하게 유지됩니다.
- 특수 문자 ".", "-", "*"및 "_"는 동일하게 유지됩니다.
- 공백 문자 ""는 더하기 부호 "+"로 변환됩니다.
- 다른 모든 문자는 안전하지 않으며 일부 인코딩 체계를 사용하여 먼저 하나 이상의 바이트로 변환됩니다. 그런 다음 각 바이트는 3 자 문자열 "% xy"로 표시됩니다. 여기서 xy는 바이트의 두 자리 16 진수 표현입니다. 권장되는 인코딩 체계는 UTF-8입니다. 그러나 호환성을 위해 인코딩을 지정하지 않으면 플랫폼의 기본 인코딩이 사용됩니다.
url의 공간으로 해석되어야한다 %20. 그래서 우리는해야합니까 url.replaceAll("\\+", "%20")? 그리고 그것이 자바 스크립트라면, escape함수를 사용해서는 안됩니다 . encodeURI또는 encodeURIComponent대신 사용하십시오 . 그것이 내가 생각했던 거죠.
쿼리 매개 변수 인코딩
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하는 것이 문제를 해결하는 가장 효율적인 방법 인 것 같습니다!
Hello+World브라우저가 요청에 application/x-www-form-urlencoded대한 양식 데이터 ( )를 인코딩하는 방법 GET이며 이는 URI의 쿼리 부분에 일반적으로 허용되는 양식입니다.
http://host/path/?message=Hello+World
이 요청을 Java 서블릿으로 보낸 경우 서블릿은 매개 변수 값을 올바르게 디코딩합니다. 일반적으로 여기에 문제가있는 유일한 시간은 인코딩이 일치하지 않는 경우입니다.
엄밀히 말하면 HTTP 또는 URI 사양에는 쿼리 부분을 사용하여 인코딩해야 할 요구 사항이 없습니다. application/x-www-form-urlencoded 키-값 쌍을 . 쿼리 부분은 웹 서버가 허용하는 형식이어야합니다. 실제로 이것은 문제가되지 않을 것입니다.
URI의 다른 부분 (예 : 경로)에이 인코딩을 사용하는 것은 일반적으로 올바르지 않습니다. 이 경우 RFC 3986에 설명 된 대로 인코딩 체계를 사용해야합니다 .
http://host/Hello%20World
더 여기에 .
다른 답변은 수동 문자열 대체, 실제로 HTML 형식으로 인코딩하는 URLEncoder , Apache의 버려진 URIUtil 또는 Guava의 UrlEscapers를 사용하는 것 입니다. 마지막은 디코더를 제공하지 않는 한 괜찮습니다.
Apache Commons Lang은 URL 형식 rfc3986 에 따라 인코딩 하고 디코딩 하는 URLCodec을 제공합니다 .
String encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);
이미 Spring을 사용 하고 있다면 UriUtils 클래스 를 사용하도록 선택할 수도 있습니다 .
"+"가 맞습니다. % 20이 정말로 필요하다면, 나중에 Plusses를 교체하십시오.
+원래 텍스트 문자로 인코딩 할 예정이다 %2B.
+상황을 알지 못하고 옳다고 말하는 것은 적어도 pedantic이다. 공감. + 또는 % 20을 언제 사용해야하는지에 대한 다른 답변을 읽으십시오.
Android 에서도이 문제로 어려움을 겪고 있으며 Android (android.net.Uri)에만 해당되는 Uri.encode (String, String)를 우연히 발견 할 수 있었지만 일부는 유용 할 수 있습니다.
정적 문자열 인코딩 (문자열 s, 문자열 허용)
java.net.URI 클래스를 확인하십시오.
잘못된 방법을 사용하고 있습니까? 사용해야하는 올바른 방법은 무엇입니까?
예,이 메소드 java.net.URLEncoder.encode는 spec ( source ) 에 따라 ""를 "20 %"로 변환하기 위해 만들어지지 않았습니다 .
공백 문자 ""는 더하기 부호 "+"로 변환됩니다.
이것이 올바른 방법이 아니더라도, System.out.println(java.net.URLEncoder.encode("Hello World", "UTF-8").replaceAll("\\+", "%20"));좋은 하루 되세요 =).
URLEncoder.encode)을 사용 replaceAll하고이 특정 경우에만 작동 하는 방법으로 패치 하는 것이 좋습니다. 대신 올바른 클래스와 방법을 사용하십시오. 다른 답변을 참조하십시오.
사용 MyUrlEncode.URLencoding (문자열 URL, 문자열 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();
}
}