나는 기대하고있다
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"));
공백은 %20
URL 로 인코딩 되고+
제출 된 데이터 (콘텐츠 유형 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();
}
}