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?

crackerplace
sumber
@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 .

Jesper
sumber
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" );
Alexander Pogrebnyak
sumber
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
Nick Grealy
sumber
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
14

%3Adan %2Fmerupakan karakter yang disandikan URL. Gunakan kode java ini untuk mengubahnya kembali menjadi :dan/

String decoded = java.net.URLDecoder.decode(url, "UTF-8");
laz
sumber
2
itu tidak mengonversi% 2C juga, ini (,)
vuhung3990
ini perlu dibungkus dalam blok coba / tangkap .. baca lebih lanjut tentang pengecualian yang diperiksa (yang satu ini) vs stackoverflow.com/questions/question/6115896/… yang
Bruno Wolff
5
 try {
        String result = URLDecoder.decode(urlString, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
Hsm
sumber
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;

    }
Ronak Poriya
sumber
4
Bisakah Anda menjelaskan lebih lanjut jawaban Anda dengan menambahkan sedikit deskripsi tentang solusi yang Anda berikan?
abarisone
3

Saya menggunakan apache commons

String decodedUrl = new URLCodec().decode(url);

Charset default adalah UTF-8

Tukang sortir
sumber
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 :)

rinuthomaz
sumber
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.

x7BiT
sumber