[java] 쿼리 문자열 매개 변수의 Java URL 인코딩

URL이 있다고 가정 해보십시오.

http://example.com/query?q=

사용자가 입력 한 쿼리가 있습니다.

임의의 단어 £ 500 bank $

결과가 올바르게 인코딩 된 URL이되기를 원합니다.

http://example.com/query?q=random%20word%20%A3500%20bank%20%24

이것을 달성하는 가장 좋은 방법은 무엇입니까? URLEncoderURI / URL 객체를 만들 려고 시도했지만 그중 어느 것도 제대로 나오지 않았습니다.



답변

URLEncoder갈 길입니다. 쿼리 문자열 매개 변수 구분 문자 나 매개 변수 이름-값 구분 문자가 아닌 전체 URL이 아닌 개별 쿼리 문자열 매개 변수 이름 및 / 또는 값만 인코딩 하면됩니다 .&=

String q = "random word £500 bank $";
String url = "https://example.com?q=" + URLEncoder.encode(q, StandardCharsets.UTF_8);

쿼리 매개 변수의 공백 은 유효 +하지 않은 로 표시됩니다 %20. 은 %20통상 URI 자체 (URI에 쿼리 스트링 구분자 앞부분의 공간 표현하기 위해 사용되는 ?하지 쿼리 스트링 () 부분을 후 ?).

또한 세 가지 encode()방법이 있습니다. 하나 Charset는 두 번째 인수가없고 다른 하나 String는 검사 예외를 발생시키는 두 번째 인수가있는 것입니다. 없는 사람Charset인수가 것은 더 이상 사용되지 않습니다. 절대로 사용하지 말고 항상 Charset인수를 지정하십시오 . javadoc에서는 의해 위임 심지어 명시 적으로 UTF-8 인코딩을 사용하는 것이 권고 RFC3986W3C .

다른 모든 문자는 안전하지 않으며 일부 인코딩 체계를 사용하여 먼저 하나 이상의 바이트로 변환됩니다. 그런 다음 각 바이트는 3 자 문자열 “% xy”로 표시됩니다. 여기서 xy는 바이트의 두 자리 16 진수 표현입니다. 권장되는 인코딩 체계는 UTF-8 입니다. 그러나 호환성을 위해 인코딩을 지정하지 않으면 플랫폼의 기본 인코딩이 사용됩니다.

또한보십시오:


답변

나는 사용하지 않을 것이다 URLEncoder. 틀린 이름 외에 (URLEncoder URL과는 관련이 없음) 비효율적입니다 ( StringBuffer빌더 대신 사용하고 속도가 느린 몇 가지 다른 작업을 수행함) 또한 너무 쉽게 망칠 수 있습니다.

대신 URIBuilder또는 Spring org.springframework.web.util.UriUtils.encodeQuery또는 Commons Apache를 사용합니다.HttpClient 합니다. 쿼리 매개 변수 이름 (예 : BalusC ‘s answer q)을 매개 변수 값과 다르게 이스케이프해야하는 이유 입니다.

위의 유일한 단점은 (내가 고통스럽게 알게 된) URL URL의 진정한 하위 집합이 아니라는 것입니다 .

샘플 코드 :

import org.apache.http.client.utils.URIBuilder;

URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();

// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24

다른 답변에 링크하기 때문에 이것을 커뮤니티 위키로 표시했습니다. 자유롭게 편집하십시오.


답변

먼저 다음과 같은 URI를 작성해야합니다.

String urlStr = "http://www.example.com/CEREC® Materials & Accessories/IPS Empress® CAD.pdf"
URL url= new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());

그런 다음 해당 URI를 ASCII 문자열로 변환하십시오.

urlStr=uri.toASCIIString();

이제 URL 문자열이 완전히 인코딩됩니다. 먼저 간단한 URL 인코딩을 수행 한 다음 ASCII 문자열로 변환하여 US-ASCII 외부의 문자가 문자열에 남아 있지 않도록합니다. 이것이 바로 브라우저가하는 방식입니다.


답변


답변

Apache Http Components 라이브러리는 쿼리 매개 변수 작성 및 인코딩을위한 깔끔한 옵션을 제공합니다.

HttpComponents 4.x 사용
-URLEncodedUtils

HttpClient를 3.x를 사용하기 위해 –
EncodingUtil


답변

다음은 코드에서 URL 문자열과 매개 변수 맵을 쿼리 매개 변수가 포함 된 유효한 인코딩 된 URL 문자열로 변환하는 데 사용할 수있는 방법입니다.

String addQueryStringToUrlString(String url, final Map<Object, Object> parameters) throws UnsupportedEncodingException {
    if (parameters == null) {
        return url;
    }

    for (Map.Entry<Object, Object> parameter : parameters.entrySet()) {

        final String encodedKey = URLEncoder.encode(parameter.getKey().toString(), "UTF-8");
        final String encodedValue = URLEncoder.encode(parameter.getValue().toString(), "UTF-8");

        if (!url.contains("?")) {
            url += "?" + encodedKey + "=" + encodedValue;
        } else {
            url += "&" + encodedKey + "=" + encodedValue;
        }
    }

    return url;
}


답변

URL url= new URL("http://example.com/query?q=random word £500 bank $");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String correctEncodedURL=uri.toASCIIString();
System.out.println(correctEncodedURL);

인쇄물

http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$

여기서 무슨 일이 일어나고 있습니까?

1. URL을 구조 부분으로 분할 하십시오 . 사용하다java.net.URL 그것을 위해 .

2. 각 구조 부분을 올바르게 인코딩하십시오!

3. 사용 IDN.toASCII(putDomainNameHere)퓨니 코드 (Punycode) 호스트 이름을 인코딩!

4.java.net.URI.toASCIIString() NFC 인코딩 유니 코드를 퍼센트 인코딩하는 데 사용 합니다 (NFKC가 더 좋습니다). 자세한 내용은 이 URL을 올바르게 인코딩하는 방법을 참조하십시오.

경우에 따라 URL이 이미 인코딩 되어 있는지 확인하는 것이 좋습니다 . 또한 ‘+’인코딩 공간을 ‘% 20’인코딩 공간으로 바꿉니다.

제대로 작동하는 몇 가지 예는 다음과 같습니다.

{
      "in" : "http://نامه‌ای.com/",
     "out" : "http://xn--mgba3gch31f.com/"
},{
     "in" : "http://www.example.com/‥/foo",
     "out" : "http://www.example.com/%E2%80%A5/foo"
},{
     "in" : "http://search.barnesandnoble.com/booksearch/first book.pdf",
     "out" : "http://search.barnesandnoble.com/booksearch/first%20book.pdf"
}, {
     "in" : "http://example.com/query?q=random word £500 bank $",
     "out" : "http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$"
}

이 솔루션은 Web Plattform Tests에서 제공하는 약 100 개의 테스트 케이스를 통과 합니다.