programing

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

shortcode 2022. 9. 22. 23:58
반응형

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

URL이 있다고 합니다.

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

사용자가 입력한 다음과 같은 쿼리가 있습니다.

500파운드 은행 달러라는 임의의 단어

결과가 올바르게 인코딩된 URL이어야 합니다.

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

이를 실현하는 가장 좋은 방법은 무엇입니까?나는 노력했다.URLEncoderURI/URL 오브젝트를 작성하는데 어느 것도 올바르게 표시되지 않습니다.

URLEncoder 가는 길이에요.쿼리 문자열 매개 변수 구분 문자가 아닌 개별 쿼리 문자열 매개 변수 이름 및/또는 값만 인코딩해야 합니다.&파라미터 이름-값 구분 문자도 사용할 수 없습니다.=.

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

Java 10 이후 버전을 아직 사용하지 않을 경우StandardCharsets.UTF_8.toString()charset 인수로 지정하거나 Java 7 이후 버전을 사용하지 않을 경우 를 사용합니다."UTF-8".


쿼리 파라미터의 공백은 다음과 같이 표시됩니다.+,것은 아니다.%20이는 합법적으로 유효합니다.%20보통 URI 자체의 공백(URI 쿼리 문자열 구분 문자 앞 부분)을 나타내기 위해 사용됩니다.?쿼리 문자열(다음 부분)에 없습니다.?).

또, 3개의 IP 주소가 있습니다.encode()방법들.없는 것Charset와의 두 번째 논쟁과 또 다른 논쟁으로서String체크된 예외를 발생시키는 두 번째 인수입니다.없는 사람Charset인수는 권장되지 않습니다.절대 사용하지 않고 항상 다음을 지정합니다.Charset논쟁.javadoc에서는 RFC3986W3C에 따라 UTF-8 인코딩 사용을 명시적으로 권장합니다.

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

다음 항목도 참조하십시오.

나는 사용하지 않을 것이다.URLEncoder이름이 잘못 기재된 것 외에 (URLEncoder(URL과는 무관), 비효율적(사용하는 것은StringBufferBuilder 대신 느린 몇 가지 작업을 수행합니다.망치기엔 너무 쉬워요

대신 스프링스나 커먼스 아파치를 사용합니다.쿼리 파라미터명을 이스케이프해야 하는 이유(BalusC의 답변)q)는 파라미터 값과 다릅니다.

위의 유일한 단점은 URL이 URI의 진정한 서브셋이 아니라는 것입니다.

샘플 코드:

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 인코딩을 실행한 후 US-ASCII 이외의 문자가 문자열에 남아 있지 않도록 ASCII 문자열로 변환했습니다.브라우저가 바로 이런 식입니다.

Guava 15는 이제 간단한 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()percent-encode, NFC 부호화 Unicode - (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 테스트에 의해 제공되는 테스트 케이스 중 약 100개를 통과합니다.

Apache Http Components 라이브러리는 쿼리 매개 변수를 구축하고 인코딩하기 위한 깔끔한 옵션을 제공합니다.

Http Components 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;
}

Spring의 URI Components Builder 사용:

UriComponentsBuilder
        .fromUriString(url)
        .build()
        .encode()
        .toUri()

Android에서는 다음 코드를 사용합니다.

Uri myUI = Uri.parse ("http://example.com/query").buildUpon().appendQueryParameter("q","random word A3500 bank 24").build();

어디에Uri는 입니다.android.net.Uri

제 경우 url 전체를 전달하고 각 파라미터의 값만 인코딩하면 됩니다.공통의 코드를 찾을 수 없었기 때문에(!) 이 작업을 수행하기 위해 다음과 같은 작은 방법을 만들었습니다.

public static String encodeUrl(String url) throws Exception {
    if (url == null || !url.contains("?")) {
        return url;
    }

    List<String> list = new ArrayList<>();
    String rootUrl = url.split("\\?")[0] + "?";
    String paramsUrl = url.replace(rootUrl, "");
    List<String> paramsUrlList = Arrays.asList(paramsUrl.split("&"));
    for (String param : paramsUrlList) {
        if (param.contains("=")) {
            String key = param.split("=")[0];
            String value = param.replace(key + "=", "");
            list.add(key + "=" +  URLEncoder.encode(value, "UTF-8"));
        }
        else {
            list.add(param);
        }
    }

    return rootUrl + StringUtils.join(list, "&");
}

public static String decodeUrl(String url) throws Exception {
    return URLDecoder.decode(url, "UTF-8");
}

org.apache.commons.lang3을 사용합니다.String Utils(스트링 유틸리티)

  1. URLEncoder.encode(쿼리, StandardCharsets)를 사용합니다.UTF_8.displayName(); 또는 다음과 같습니다.URLEncoder.encode(쿼리, UTF-8);
  2. 다음 코드를 사용할 수 있습니다.

    String encodedUrl1 = UriUtils.encodeQuery(query, "UTF-8");//not change 
    String encodedUrl2 = URLEncoder.encode(query, "UTF-8");//changed
    String encodedUrl3 = URLEncoder.encode(query, StandardCharsets.UTF_8.displayName());//changed
    
    System.out.println("url1 " + encodedUrl1 + "\n" + "url2=" + encodedUrl2 + "\n" + "url3=" + encodedUrl3);
    

언급URL : https://stackoverflow.com/questions/10786042/java-url-encoding-of-query-string-parameters

반응형