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-クエリ文字列の区切り文字の?
の前の部分)のスペースを表すために使用されます。
2つのencode()
メソッドがあることにも注意してください。文字セット引数のないものとあります。 charset引数のないものは推奨されません。絶対に使用せず、常にcharset引数を指定してください。 javadoc は、 RFC 3986 および W 3 C で規定されているように、UTF-8エンコーディングの使用を明示的に推奨します。
他のすべての文字は安全ではなく、まず何らかの符号化方式を使用して1つ以上のバイトに変換されます。その後、各バイトは3文字の文字列 "%xy"で表されます。ここで、xyはバイトの2桁の16進表現です。 推奨されるエンコード方式はUTF-8です。ただし、互換性の理由から、エンコーディングが指定されていない場合は、プラットフォームのデフォルトのエンコーディングが使用されます。
URLEncoder
は使いません。誤った名前(URLEncoder
はURLとは無関係)であることに加えて、非効率的です(Builderの代わりにStringBuffer
を使用し、低速の他のいくつかのことを行います)。
代わりに、 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 stringに変換します。
urlStr=uri.toASCIIString();
これで、あなたのURL文字列は最初に完全にエンコードされ、次に単純なURLエンコードを行い、それからそれをASCII Stringに変換してUS-ASCIIの外側の文字が残っていないことを確認します。これはまさにブラウザの動作方法です。
Guava 15では 一連の簡単なURLエスケープ が追加されました。
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;
}
次の標準的なJavaソリューションを使用してください( Web Plattform Tests で提供されるテストケースを約100回通過します)。
0。URLがすでにエンコードされているかどうかをテストします 。 '+'エンコードスペースを '%20'エンコードスペースに置き換えます。
1。URLを構造部分に分割します。それにはJava.net.URL
を使用してください。
2。各構造部分を正しくエンコードしてください。
3.ホスト名を Punycode でエンコードするには、IDN.toASCII(putDomainNameHere)
を使用します。
4。パーセントエンコード、NFCエンコードされたUnicodeへのJava.net.URI.toASCIIString()
の使用 - (より良いのはNFKCでしょう!)詳細については、 この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$
これはまた正しく働くいくつかの例です。
{
"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$"
}
私の場合は、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.StringUtilsを使います
Androidでは、このコードを使用します。
Uri myUI = Uri.parse ("http://example.com/query").buildUpon().appendQueryParameter("q","random Word A3500 bank 24").build();
Uri
はAndroid.net.Uri
です。