23

W3 SchoolsのURLエンコードWebページを見ると、それはとして@エンコードする必要があり、それは%40としてエンコードする必要があると書かspaceれてい%20ます。

私はとの両方を試しましURLEncoderURIが、どちらも上記を正しく行いません:

import java.net.URI;
import java.net.URLEncoder;

public class Test {
    public static void main(String[] args) throws Exception {

        // Prints me%40home.com (CORRECT)
        System.out.println(URLEncoder.encode("me@home.com", "UTF-8"));

        // Prints Email+Address (WRONG: Should be Email%20Address)
        System.out.println(URLEncoder.encode("Email Address", "UTF-8"));

        // http://www.home.com/test?Email%20Address=me@home.com
        // (WRONG: it has not encoded the @ in the email address)
        URI uri = new URI("http", "www.home.com", "/test", "Email Address=me@home.com", null);
        System.out.println(uri.toString());
    }
}

何らかの理由でURLEncoder、電子メールアドレスは正しく実行されますが、スペースは実行されURIません。また、スペース通貨は実行されますが、電子メールアドレスは実行されません。

w3schoolsが正しいと言っていること(またはw3schoolsが間違っていること)と一致するように、これら2つのパラメーターをどのようにエンコードする必要がありますか?

4

2 に答える 2

43

@fgeからの答えは正しいと思いますが、W3Schoolsの記事で概説されているエンコーディングに依存するサードパーティのWebサービスを使用していたので、同じ出力を生成するJavaScriptのencodeURIComponentに相当するJavaからの答えに従いましたか?

public static String encodeURIComponent(String s) {
    String result;

    try {
        result = URLEncoder.encode(s, "UTF-8")
                .replaceAll("\\+", "%20")
                .replaceAll("\\%21", "!")
                .replaceAll("\\%27", "'")
                .replaceAll("\\%28", "(")
                .replaceAll("\\%29", ")")
                .replaceAll("\\%7E", "~");
    } catch (UnsupportedEncodingException e) {
        result = s;
    }

    return result;
}
于 2013-01-20T12:59:10.217 に答える
16

URI構文はRFC3986で定義されています(クエリ文字列の許可される内容はセクション3.4で定義されています)。JavaURIはこのRFCに準拠していますが、Javadocにいくつかの注意点があります。

pchar文法規則が次のように定義されていることに気付くでしょう。

pchar = unreserved / pct-encoded / sub-delims / ":" / "@"

これは、クエリ文字列でa@有効であることを意味します。

URIを信頼します。それ正しい「合法的な」ことをします。

最後に、URLEncoderのJavadocを見ると、次のように記述されていることがわかります。

このクラスには、文字列をapplication /x-www-form-urlencodedMIME形式に変換するための静的メソッドが含まれています。

これは、URI仕様で定義されているクエリ文字列と同じではありません。

于 2013-01-14T16:03:04.940 に答える