java querystring_Java URL encoding of query string parameters

可以将文章内容翻译成中文,广告屏蔽插件会导致该功能失效:

问题:

Say I have a URL

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

and I have a query entered by the user such as:

random word £500 bank $

I want the result to be a properly encoded URL:

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

What's the best way to achieve this? I tried URLEncoder and creating URI/URL objects but none of them come out quite right.

回答1:

URLEncoder should be the way to go. You only need to keep in mind to encode only the individual query string parameter name and/or value, not the entire URL, for sure not the query string parameter separator character & nor the parameter name-value separator character =.

String q = "random word £500 bank $";

String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");

Note that spaces in query parameters are represented by +, not %20, which is legitimately valid. The %20 is usually to be used to represent spaces in URI itself (the part before the URI-query string separator character ?), not in query string (the part after ?).

Also note that there are two encode() methods. One without charset argument and another with. The one without charset argument is deprecated. Never use it and always specify the charset argument. The javadoc even explicitly recommends to use the UTF-8 encoding, as mandated by RFC3986 and W3C.

All other characters are unsafe and are first converted into one or more bytes using some encoding scheme. Then each byte is represented by the 3-character string "%xy", where xy is the two-digit hexadecimal representation of the byte. The recommended encoding scheme to use is UTF-8. However, for compatibility reasons, if an encoding is not specified, then the default encoding of the platform is used.

See also:

回答2:

I would not use URLEncoder. Besides being incorrectly named (URLEncoder has nothing to do with URLs), inefficient (it uses a StringBuffer instead of Builder and does a couple of other things that are slow) Its also way too easy to screw it up.

Instead I would use URIBuilder or Spring's org.springframework.web.util.UriUtils.encodeQuery or Commons Apache HttpClient. The reason being you have to escape the query parameters name (ie BalusC's answer q) differently than the parameter value.

The only downside to the above (that I found out painfully) is that URL's are not a true subset of URI's.

Sample code:

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

Since I'm just linking to other answers I marked this as a community wiki. Feel free to edit.

回答3:

You need to first create a URI like:

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());

Then convert that Uri to ASCII string:

urlStr=uri.toASCIIString();

Now your url string is completely encoded first we did simple url encoding and then we converted it to ASCII String to make sure no character outside US-ASCII are remaining in string. This is exactly how browsers do.

回答4:

回答5:

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

回答6:

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 parameters) throws UnsupportedEncodingException {

if (parameters == null) {

return url;

}

for (Map.Entry 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;

}

回答7:

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$"

}

回答8:

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 list = new ArrayList<>();

String rootUrl = url.split("\?")[0] + "?";

String paramsUrl = url.replace(rootUrl, "");

List 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

回答9:

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

回答10:

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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值