Bagaimana cara melakukan decoding URL di Java?


323

Di Jawa, saya ingin mengonversi ini:

https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest_type

Untuk ini:

https://mywebsite/docs/english/site/mybook.do&request_type

Inilah yang saya miliki sejauh ini:

class StringUTF 
{
    public static void main(String[] args) 
    {
        try{
            String url = 
               "https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do" +
               "%3Frequest_type%3D%26type%3Dprivate";

            System.out.println(url+"Hello World!------->" +
                new String(url.getBytes("UTF-8"),"ASCII"));
        }
        catch(Exception E){
        }
    }
}

Tapi itu tidak berhasil. Apa ini %3Adan %2Fformat yang disebut dan bagaimana cara mengubahnya?


@Stephen .. Mengapa url tidak bisa menjadi UTF-8 String yang dikodekan ..?
crackerplace

Masalahnya adalah hanya karena URL dapat berupa UTF-8, pertanyaannya benar-benar tidak ada hubungannya dengan UTF-8. Saya telah mengedit pertanyaan dengan tepat.
Chris Jester-Young

Bisa jadi (secara teori) tetapi string dalam contoh Anda bukan String yang dikodekan UTF-8. Ini adalah string ASCII yang disandikan URL. Karena itu judulnya menyesatkan.
Stephen C

Perlu juga dicatat bahwa semua karakter dalam urlstring adalah ASCII, dan ini juga berlaku setelah string telah diterjemahkan URL. '%'adalah char ASCII dan %xxmewakili char ASCII jika xxkurang dari (heksadesimal) 80.
Stephen C

Jawaban:


634

Ini tidak ada hubungannya dengan pengkodean karakter seperti UTF-8 atau ASCII. String yang Anda miliki di sana adalah URL yang disandikan . Pengkodean semacam ini adalah sesuatu yang sama sekali berbeda dari pengkodean karakter.

Coba sesuatu seperti ini:

try {
    String result = java.net.URLDecoder.decode(url, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
    // not going to happen - value came from JDK's own StandardCharsets
}

Java 10 menambahkan dukungan langsung Charsetke API, artinya tidak perlu untuk menangkap UnsupportedEncodingException:

String result = java.net.URLDecoder.decode(url, StandardCharsets.UTF_8);

Perhatikan bahwa pengkodean karakter (seperti UTF-8 atau ASCII) adalah yang menentukan pemetaan karakter menjadi byte mentah. Untuk pengenalan pengodean karakter yang baik, lihat artikel ini .


1
Metode aktif URLDecoderbersifat statis sehingga Anda tidak perlu membuat instance baru.
laz

2
@ Trismegistos Hanya versi di mana Anda tidak menentukan pengkodean karakter (parameter kedua, "UTF-8") dihentikan menurut dokumentasi Java 7 API. Gunakan versi dengan dua parameter.
Jesper

23
Jika menggunakan java 1.7+ Anda dapat menggunakan versi statis "UTF-8" string: StandardCharsets.UTF_8.name()dari paket ini: java.nio.charset.StandardCharsets. Relevan dengan ini: tautan
Shahar

1
Untuk pengkodean karakter, ini membuat sebuah artikel besar juga balusc.blogspot.in/2009/05/unicode-how-to-get-characters-right.html
crackerplace

4
Hati-hati dengan ini. Seperti disebutkan di sini: blog.lunatech.com/2009/02/03/... Ini bukan tentang URL, tetapi untuk pengkodean formulir HTML.
Michal

52

String yang Anda punya ada dalam application/x-www-form-urlencodedencoding.

Gunakan URLDecoder untuk mengubahnya menjadi Java String.

URLDecoder.decode( url, "UTF-8" );

47

Ini telah dijawab sebelumnya (meskipun pertanyaan ini yang pertama!):

"Anda harus menggunakan java.net.URI untuk melakukan ini, karena kelas URLDecoder melakukan decoding x-www-form-urlencoded yang salah (terlepas dari namanya, ini untuk data formulir)."

Seperti yang dinyatakan oleh dokumentasi kelas URL :

Cara yang disarankan untuk mengelola encoding dan decoding URL adalah menggunakan URI , dan mengkonversi antara dua kelas ini menggunakan toURI () dan URI.toURL () .

Kelas URLEncoder dan URLDecoder juga dapat digunakan, tetapi hanya untuk pengkodean formulir HTML, yang tidak sama dengan skema pengkodean yang ditentukan dalam RFC2396 .

Pada dasarnya:

String url = "https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest_type";
System.out.println(new java.net.URI(url).getPath());

akan memberimu:

https://mywebsite/docs/english/site/mybook.do?request_type

6
Di Jawa 1.7 URLDecoder.decode(String, String)kelebihannya tidak ditinggalkan. Anda harus merujuk ke URLDecoder.decode(String)kelebihan tanpa pengkodean. Anda mungkin ingin memperbarui posting Anda untuk klarifikasi.
Aaron

2
Jawaban ini menyesatkan; bahwa kutipan blok tidak ada hubungannya dengan penghinaan. Javadoc dari metode yang ditinggalkan menyatakan, dan saya benar-benar mengutip@deprecated The resulting string may vary depending on the platform's default encoding. Instead, use the decode(String,String) method to specify the encoding.
Emerson Farrugia

1
getPath () untuk URI hanya mengembalikan bagian jalur URI, seperti yang disebutkan di atas.
Pelpotronic

2
Kecuali saya salah, "path" diketahui sebagai bagian dari URI setelah bagian otoritas (lihat: en.wikipedia.org/wiki/Uniform_Resource_Identifier untuk definisi path) - menurut saya perilaku yang saya lihat adalah standar / perilaku yang benar. Saya menggunakan java 1.8.0_101 (di Android Studio). Saya ingin tahu apa yang Anda dapatkan sebagai "getAuthority ()" disebut. Bahkan artikel / contoh ini tampaknya menunjukkan bahwa path hanya bagian / publik / manual / peralatan dari URI mereka: quepublishing.com/articles/article.aspx?p=26566&seqNum=3
Pelpotronic

1
@Pelpotronic Kode dalam postingan sebenarnya mencetak output yang ditampilkan (setidaknya untuk saya). Saya pikir alasan untuk ini adalah bahwa, karena pengkodean URL, konstruktor URI sebenarnya memperlakukan seluruh string, ( https%3A%2F...), hanya sebagai jalur URI; tidak ada otoritas, atau permintaan, dll. Ini dapat diuji dengan memanggil masing-masing metode get pada objek URI. Jika Anda meneruskan teks yang diterjemahkan ke konstruktor URI:, new URI("https://mywebsite/do.....")maka memanggil getPath()dan metode lain akan memberikan hasil yang benar.
Kröw


5
 try {
        String result = URLDecoder.decode(urlString, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

5
public String decodeString(String URL)
    {

    String urlString="";
    try {
        urlString = URLDecoder.decode(URL,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block

        }

        return urlString;

    }

4
Bisakah Anda menjelaskan lebih lanjut jawaban Anda dengan menambahkan sedikit deskripsi tentang solusi yang Anda berikan?
abarisone


2
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;

public class URLDecoding { 

    String decoded = "";

    public String decodeMethod(String url) throws UnsupportedEncodingException
    {
        decoded = java.net.URLDecoder.decode(url, "UTF-8"); 
        return  decoded;
//"You should use java.net.URI to do this, as the URLDecoder class does x-www-form-urlencoded decoding which is wrong (despite the name, it's for form data)."
    }

    public String getPathMethod(String url) throws URISyntaxException 
    {
        decoded = new java.net.URI(url).getPath();  
        return  decoded; 
    }

    public static void main(String[] args) throws UnsupportedEncodingException, URISyntaxException 
    {
        System.out.println(" Here is your Decoded url with decode method : "+ new URLDecoding().decodeMethod("https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest_type")); 
        System.out.println("Here is your Decoded url with getPath method : "+ new URLDecoding().getPathMethod("https%3A%2F%2Fmywebsite%2Fdocs%2Fenglish%2Fsite%2Fmybook.do%3Frequest")); 

    } 

}

Anda dapat memilih metode Anda dengan bijak :)


0

Menggunakan kelas java.net.URI:

public String getDecodedURL(String encodedUrl) {
    try {
        URI uri = new URI(encodedUrl);
        return uri.getScheme() + ":" + uri.getSchemeSpecificPart();
    } catch (Exception e) {
        return "";
    }
}

Harap perhatikan bahwa penanganan pengecualian bisa lebih baik, tetapi tidak terlalu relevan untuk contoh ini.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.