쿼리 문자열 매개 변수의 Java URL 인코딩
URL이 있다고 합니다.
http://example.com/query?q=
사용자가 입력한 다음과 같은 쿼리가 있습니다.
500파운드 은행 달러라는 임의의 단어
결과가 올바르게 인코딩된 URL이어야 합니다.
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
이를 실현하는 가장 좋은 방법은 무엇입니까?나는 노력했다.URLEncoder
URI/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에서는 RFC3986 및 W3C에 따라 UTF-8 인코딩 사용을 명시적으로 권장합니다.
다른 모든 문자는 안전하지 않으며 일부 인코딩 방식을 사용하여 먼저 하나 이상의 바이트로 변환됩니다.그런 다음 각 바이트는 3자 문자열 "%xy"로 표시됩니다. 여기서 xy는 바이트의 두 자리 16진수 표현입니다.권장되는 인코딩 방식은 UTF-8입니다.단, 호환성을 위해 인코딩이 지정되지 않은 경우 플랫폼의 기본 인코딩이 사용됩니다.
다음 항목도 참조하십시오.
나는 사용하지 않을 것이다.URLEncoder
이름이 잘못 기재된 것 외에 (URLEncoder
(URL과는 무관), 비효율적(사용하는 것은StringBuffer
Builder 대신 느린 몇 가지 작업을 수행합니다.망치기엔 너무 쉬워요
대신 스프링스나 커먼스 아파치를 사용합니다.쿼리 파라미터명을 이스케이프해야 하는 이유(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(스트링 유틸리티)
- URLEncoder.encode(쿼리, StandardCharsets)를 사용합니다.UTF_8.displayName(); 또는 다음과 같습니다.URLEncoder.encode(쿼리, UTF-8);
다음 코드를 사용할 수 있습니다.
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
'programing' 카테고리의 다른 글
특정 테이블에서 왼쪽 조인 속도가 매우 느립니다. (0) | 2022.09.23 |
---|---|
AssertEquals 2 리스트는 순서를 무시합니다. (0) | 2022.09.22 |
왜 일부 리터럴의 경우 반환이 거짓입니까? (0) | 2022.09.18 |
Java에 Mutex가 있나요? (0) | 2022.09.18 |
시스템에 설치되어 있는 TensorFlow 버전을 확인하려면 어떻게 해야 합니까? (0) | 2022.09.18 |