私は期待している
System.out.println(Java.net.URLEncoder.encode("Hello World", "UTF-8"));
出力するには:
Hello%20World
(20はASCIIスペースの16進コードです)
しかし、私が得るのは:
Hello+World
間違った方法を使用していますか?使用すべき正しい方法は何ですか?
これは期待どおりに動作します。 URLEncoder
は、HTMLフォームでURLをエンコードする方法に関するHTML仕様を実装します。
javadocs から:
このクラスには、文字列をapplication/x-www-form-urlencoded MIME形式に変換する静的メソッドが含まれています。
および HTML仕様 から:
application/x-www-form-urlencoded
このコンテンツタイプで送信されるフォームは、次のようにエンコードする必要があります。
- コントロールの名前と値はエスケープされます。スペース文字は「+」に置き換えられます
あなたはそれを交換する必要があります、例えば:
System.out.println(Java.net.URLEncoder.encode("Hello World", "UTF-8").replace("+", "%20"));
スペースは、URLでは%20
にエンコードされ、フォーム送信データ(コンテンツタイプapplication/x-www-form-urlencoded)では+
にエンコードされます。前者が必要です。
Guava を使用:
dependencies {
compile 'com.google.guava:guava:23.0'
// or, for Android:
compile 'com.google.guava:guava:23.0-Android'
}
rlEscapers を使用できます。
String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);
String.replaceを使用しないでください。これはスペースのみをエンコードします。代わりにライブラリを使用してください。
このクラスは、パーセントエンコーディングではなくapplication/x-www-form-urlencoded
- typeエンコーディングを実行するため、+
に置き換えるのが正しい動作です。
Javadocから:
文字列をエンコードする場合、次の規則が適用されます。
- 英数字「a」から「z」、「A」から「Z」、および「0」から「9」は同じままです。
- 特殊文字「。」、「-」、「*」、および「_」は同じままです。
- スペース文字「」はプラス記号「+」に変換されます。
- 他のすべての文字は安全ではなく、最初に何らかのエンコーディングスキームを使用して1つ以上のバイトに変換されます。次に、各バイトは3文字の文字列「%xy」で表されます。ここで、xyはバイトの2桁の16進表現です。使用する推奨エンコードスキームはUTF-8です。ただし、互換性の理由から、エンコーディングが指定されていない場合、プラットフォームのデフォルトのエンコーディングが使用されます。
クエリパラメータのエンコード
org.Apache.commons.httpclient.util.URIUtil
URIUtil.encodeQuery(input);
または、URI内の文字をエスケープする場合
public static String escapeURIPathParam(String input) {
StringBuilder resultStr = new StringBuilder();
for (char ch : input.toCharArray()) {
if (isUnsafe(ch)) {
resultStr.append('%');
resultStr.append(toHex(ch / 16));
resultStr.append(toHex(ch % 16));
} else{
resultStr.append(ch);
}
}
return resultStr.toString();
}
private static char toHex(int ch) {
return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
}
private static boolean isUnsafe(char ch) {
if (ch > 128 || ch < 0)
return true;
return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
}
Hello+World
は、ブラウザがGET
要求に対してフォームデータ(application/x-www-form-urlencoded
)をエンコードする方法であり、これはURIのクエリ部分で一般的に受け入れられているフォームです。
http://Host/path/?message=Hello+World
このリクエストをJavaサーブレットに送信した場合、サーブレットはパラメーター値を正しくデコードします。通常、ここで問題になるのは、エンコードが一致しない場合のみです。
厳密に言えば、HTTP仕様またはURI仕様では、クエリパーツをapplication/x-www-form-urlencoded
キーと値のペアを使用してエンコードする必要はありません。クエリ部分は、Webサーバーが受け入れる形式である必要があります。実際には、これが問題になることはほとんどありません。
一般に、URIの他の部分(パスなど)にこのエンコードを使用することは正しくありません。その場合、 RFC 3986 で説明されているエンコードスキームを使用する必要があります。
http://Host/Hello%20World
もっと こちら 。
「+」が正しい。本当に%20が必要な場合は、後で自分でPlussesを交換してください。
他の回答は、手動の文字列置換、 RLEncoder を提示します。これは実際にHTML形式にエンコードされ、Apacheの abandonedRIUtil 、またはGuavaの rlEscapers 。最後のものは、デコーダーを提供しないことを除いて、問題ありません。
Apache Commons Langは、URL形式 rfc3986 に従ってandデコードをエンコードする RLCodec を提供します。
String encoded = new URLCodec().encode(str);
String decoded = new URLCodec().decode(str);
既にSpringを使用している場合は、itsriUtils クラスも使用することもできます。
Androidでもこれに苦労しており、Uri.encode(String、String)につまずくことができましたが、特定のAndroid(Android.net.Uri)に役立つことがあります。
static String encode(String s、String allow)
これは私のために働いた
org.Apache.catalina.util.URLEncoder ul = new org.Apache.catalina.util.URLEncoder().encode("MY URL");
かなり古いものの、それにもかかわらず迅速な応答:
SpringはUriUtilsを提供します-これにより、エンコード方法と、URIからどの部分を関連付けるかを指定できます。
encodePathSegment
encodePort
encodeFragment
encodeUriVariables
....
私はすでにSpringを使用しているため、それらを使用します、つまり追加のライブラリは必要ありません!
間違った方法を使用していますか?使用すべき正しい方法は何ですか?
はい、このメソッドJava.net.URLEncoder.encodeは、仕様( source )に従って ""を "20%"に変換するために作成されたものではありません。
スペース文字「」はプラス記号「+」に変換されます。
これは正しい方法ではありませんが、System.out.println(Java.net.URLEncoder.encode("Hello World", "UTF-8").replaceAll("\\+", "%20"));
have a Nice day =)に変更できます。
Java.net.URIクラスを調べてください。