Pengkodean URL Java: URLEncoder vs. URI

Melihat halaman web pengkodean URL Sekolah W3, dikatakan bahwa @ harus dikodekan sebagai %40, dan space seharusnya dikodekan sebagai %20.

Saya sudah mencoba URLEncoder dan URI, tetapi cara di atas juga tidak berhasil:

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("[email protected]", "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%[email protected]
        // (WRONG: it has not encoded the @ in the email address)
        URI uri = new URI("http", "www.home.com", "/test", "Email [email protected]", null);
        System.out.println(uri.toString());
    }
}

Untuk beberapa alasan, URLEncoder memberi spasi pada alamat email dengan benar tetapi tidak menggunakan spasi, dan URI memberi spasi pada mata uang tetapi tidak memberi spasi pada alamat email.

Bagaimana saya harus mengkodekan 2 parameter ini agar konsisten dengan apa yang dikatakan w3schools benar (atau apakah w3schools salah?)


person John Farrelly    schedule 14.01.2013    source sumber
comment
Jika Anda melihat w3schools.com, maka Anda salah melakukannya. Lihat ini   -  person Srinivas    schedule 14.01.2013
comment
@Srinivas layanan web yang saya gunakan secara eksplisit mengabaikan permintaan kecuali parameter dikodekan seperti yang dijelaskan di halaman web w3schools :(   -  person John Farrelly    schedule 14.01.2013
comment
URLEncoder tidak mengkodekan sesuai spesifikasi URL tetapi sesuai dengan format application/x-www-form-urlencoded MIME (yang diharapkan sebagian besar server aplikasi untuk kunci/nilai parameter.) Tipe URI mengkodekan sesuai dokumentasinya - yaitu, ini bukan yang lengkap Pembuat URL. Perhatikan bahwa bagian URI yang berbeda memiliki aturan yang berbeda. Lihat postingan ini untuk mengetahui analisis lebih lanjut.   -  person McDowell    schedule 14.01.2013
comment
@McDowell Ya, saya rasa saya seharusnya bertanya bagaimana cara membuat Java melakukan apa yang dilakukan encodeURIComponent() JavaScript. Saya akan memeriksa lib Anda.   -  person John Farrelly    schedule 14.01.2013


Jawaban (2)


Meskipun menurut saya jawaban dari @fge adalah yang benar, karena saya menggunakan layanan web pihak ketiga yang mengandalkan pengkodean yang diuraikan dalam artikel W3Schools, saya mengikuti jawaban dari Java setara dengan encodeURIComponent JavaScript yang menghasilkan output identik?

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;
}
person John Farrelly    schedule 20.01.2013
comment
Anda lupa simbol & yang penting untuk mendekode url (baik untuk metode GET atau POST), karena itu adalah simbol yang memisahkan kunci dalam permintaan - person Giorgos Fandomas; 10.08.2015
comment
Saya terdorong untuk menunjukkan bahwa w3schools bukanlah W3C. Mereka sangat berbeda. - person Mike B; 06.11.2018

Sintaks URI ditentukan oleh RFC 3986 (konten yang diizinkan untuk string kueri ditentukan di bagian 3.4). URI Java mematuhi RFC ini, dengan beberapa peringatan disebutkan dalam Javadoc.

Anda akan melihat bahwa aturan tata bahasa pchar ditentukan oleh:

pchar = tidak dicadangkan / dikodekan pct / sub-delims / ":" / "@"

Artinya, @ adalah sah dalam string kueri.

Percayai URI. Ini akan melakukan hal yang benar dan "legal".

Terakhir, jika Anda melihat Javadoc dari URLEncoder, Anda melihatnya menyatakan:

Kelas ini berisi metode statis untuk mengonversi String ke format MIME application/x-www-form-urlencoded.

Yang tidak sama dengan string kueri seperti yang ditentukan oleh spesifikasi URI.

person fge    schedule 14.01.2013
comment
Saya pikir pertanyaan yang seharusnya saya tanyakan adalah bagaimana cara membuat Java menyandikan URL dengan cara yang sama seperti JavaScript encodeURIComponent, karena inilah yang diharapkan oleh layanan web penerima: stackoverflow.com/questions/607176/ - person John Farrelly; 14.01.2013
comment
Sejak itu, saya telah mengembangkan perpustakaan yang menyediakan templat URI (RFC 6570), yang bahkan lebih canggih;) - person fge; 05.07.2013
comment
ini aneh... Javadocs untuk URI menyatakan mengikuti RFC 2396, bahkan di Java 8, dengan RFC 2396 berasal dari tahun 1998, dan telah usang oleh RFC 3986 sejak tahun 2005 - person arcuri82; 28.03.2017