쿼리 문자열 매개 변수의 Java URL 인코딩
URL이 있다고
http://example.com/query?q=
사용자가 입력 한 다음과 같은 쿼리가 있습니다.
임의의 단어 £ 500 bank $
결과가 올바르게 인코딩 된 URL이되기를 원합니다.
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
이를 달성하는 가장 좋은 방법은 무엇입니까? URLEncoder
URI / URL 개체를 시도 하고 생성했지만 어느 것도 제대로 나오지 않았습니다.
URLEncoder
갈 길이되어야합니다. 당신은 인코딩을 명심해야 할 유일한 확실하지 쿼리 문자열 매개 변수를 구분 문자, 개별 쿼리 문자열 매개 변수 이름 및 / 또는 값이 아닌 전체 URL &
이나 매개 변수 이름과 값의 분리 문자 =
.
String q = "random word £500 bank $";
String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");
쿼리 매개 변수의 공백 은 합법적으로 유효한이 +
아닌 으로 표시됩니다 %20
. 은 %20
통상 URI 자체 (URI에 쿼리 스트링 구분자 앞부분의 공간 표현하기 위해 사용되는 ?
하지 쿼리 스트링 () 부분을 후 ?
).
또한 두 가지 encode()
방법이 있습니다. 하나는 charset 인수가없고 다른 하나는 포함됩니다. charset 인수가없는 것은 더 이상 사용되지 않습니다. 절대 사용하지 말고 항상 charset 인수를 지정하십시오. javadoc에서는 의해 위임 심지어 명시 적으로 UTF-8 인코딩을 사용하는 것이 권고 RFC3986 및 W3C .
다른 모든 문자는 안전하지 않으며 먼저 일부 인코딩 체계를 사용하여 하나 이상의 바이트로 변환됩니다. 그런 다음 각 바이트는 3 자 문자열 "% xy"로 표시됩니다. 여기서 xy는 바이트의 두 자리 16 진수 표현입니다. 사용할 권장 인코딩 체계는 UTF-8 입니다. 그러나 호환성을 위해 인코딩이 지정되지 않은 경우 플랫폼의 기본 인코딩이 사용됩니다.
또한보십시오:
나는 사용하지 않을 것 URLEncoder
입니다. 이름이 잘못 지정되는 것 외에도 ( URLEncoder
URL과 관련이 없음) 비효율적 ( StringBuffer
Builder 대신를 사용하고 느린 몇 가지 다른 작업을 수행함) 또한 너무 쉽게 망칠 수 있습니다.
대신 나는 URIBuilder
또는 Spring org.springframework.web.util.UriUtils.encodeQuery
또는 Commons Apache를 사용HttpClient
합니다. 그 이유는 쿼리 매개 변수 이름 (즉 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 has now added a set of straightforward URL escapers.
Apache Http Components library provides a neat option for building and encoding query params -
With HttpComponents 4.x use - URLEncodedUtils
For HttpClient 3.x use - EncodingUtil
Here's a method you can use in your code to convert a url string and map of parameters to a valid encoded url string containing the query parameters.
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;
}
Use the following standard Java solution (passes around 100 of the testcases provided by Web Plattform Tests):
0. Test if URL is already encoded. Replace '+' encoded spaces with '%20' encoded spaces.
1. Split URL into structural parts. Use java.net.URL
for it.
2. Encode each structural part properly!
3. Use IDN.toASCII(putDomainNameHere)
to Punycode encode the host name!
4. Use java.net.URI.toASCIIString()
to percent-encode, NFC encoded unicode - (better would be NFKC!). For more info see: How to encode properly this 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);
Prints
http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$
Here are some examples that will also work properly
{
"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$"
}
In my case i just needed to pass the whole url and encode only the value of each parameters. I didn't find a common code to do that so (!!) so i created this small method to do the job :
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");
}
It uses org.apache.commons.lang3.StringUtils
In android I would use this code:
Uri myUI = Uri.parse ("http://example.com/query").buildUpon().appendQueryParameter("q","random word A3500 bank 24").build();
Where Uri
is a android.net.Uri
- Use this: URLEncoder.encode(query, StandardCharsets.UTF_8.displayName()); or this:URLEncoder.encode(query, "UTF-8");
You can use the follwing code.
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
'Development Tip' 카테고리의 다른 글
강제 메이븐 업데이트 (0) | 2020.09.30 |
---|---|
Git에서 로컬 작업 디렉토리를 지우려면 어떻게해야합니까? (0) | 2020.09.30 |
연속 스트림을 'grep'하는 방법은 무엇입니까? (0) | 2020.09.30 |
Git에서 HEAD ^와 HEAD ~의 차이점은 무엇입니까? (0) | 2020.09.30 |
“git clone git@remote.git”를 실행할 때 사용자 이름과 비밀번호를 어떻게 제공합니까? (0) | 2020.09.29 |