Come eseguire la decodifica URL in Java?


323

In Java, voglio convertire questo:

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

A questa:

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

Questo è quello che ho finora:

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){
        }
    }
}

Ma non funziona bene. Come si chiamano questi %3Ae %2Fformati e come li converto?


@Stephen .. Perché un URL non può essere codificato in UTF-8 String ..?
crackerplace,

Il problema è che solo perché l'URL può essere UTF-8, la domanda non ha nulla a che fare con UTF-8. Ho modificato la domanda in modo adeguato.
Chris Jester-Young,

Potrebbe essere (in teoria) ma la stringa nel tuo esempio non è una stringa codificata UTF-8. È una stringa ASCII con codifica URL. Quindi il titolo è fuorviante.
Stephen C,

Vale anche la pena notare che tutti i caratteri nella urlstringa sono ASCII, e questo vale anche dopo la decodifica della stringa URL. '%'è un carattere ASCII e %xxrappresenta un carattere ASCII se xxè minore di (esadecimale) 80.
Stephen C,

Risposte:


634

Questo non ha nulla a che fare con la codifica dei caratteri come UTF-8 o ASCII. La stringa che hai lì è codificata URL . Questo tipo di codifica è qualcosa di completamente diverso dalla codifica dei caratteri.

Prova qualcosa del genere:

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 ha aggiunto il supporto diretto Charsetall'API, il che significa che non è necessario catturare UnsupportedEncodingException:

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

Si noti che una codifica dei caratteri (come UTF-8 o ASCII) è ciò che determina il mapping dei caratteri ai byte grezzi. Per una buona introduzione alle codifiche dei caratteri, consulta questo articolo .


1
I metodi URLDecodersono statici, quindi non è necessario crearne una nuova istanza.
Laz

2
@Trismegistos Solo la versione in cui non si specifica la codifica dei caratteri (il secondo parametro "UTF-8") è obsoleta in base alla documentazione dell'API Java 7. Utilizzare la versione con due parametri.
Jesper,

23
Se si utilizza java 1.7+ è possibile utilizzare la versione statica della stringa "UTF-8": StandardCharsets.UTF_8.name()da questo pacchetto: java.nio.charset.StandardCharsets. A questo proposito: link
Shahar

1
Per la codifica dei caratteri, anche questo rende un ottimo articolo balusc.blogspot.in/2009/05/unicode-how-to-get-characters-right.html
crackerplace

4
Stai attento con questo. Come notato qui: blog.lunatech.com/2009/02/03/… Non si tratta di URL, ma per la codifica dei moduli HTML.
Michal,

52

La stringa che hai è in application/x-www-form-urlencodedcodifica.

Utilizzare URLDecoder per convertirlo in stringa Java.

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

47

Questa è stata risposta in precedenza (sebbene questa domanda fosse la prima!):

"Dovresti usare java.net.URI per farlo, dato che la classe URLDecoder esegue la decodifica codificata x-www-form-urlated che è errata (nonostante il nome, è per i dati del modulo)."

Come afferma la documentazione della classe URL :

Il modo consigliato per gestire la codifica e la decodifica degli URL è utilizzare URI e convertire tra queste due classi usando toURI () e URI.toURL () .

È possibile utilizzare anche le classi URLEncoder e URLDecoder , ma solo per la codifica dei moduli HTML, che non è la stessa dello schema di codifica definito in RFC2396 .

Fondamentalmente:

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

ti darà:

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

6
In Java 1.7 il URLDecoder.decode(String, String)sovraccarico non è deprecato. Devi fare riferimento al URLDecoder.decode(String)sovraccarico senza la codifica. Potresti voler aggiornare il tuo post per chiarimenti.
Aaron,

2
Questa risposta è fuorviante; quella citazione di blocco non ha nulla a che fare con la deprecazione. Il Javadoc del metodo deprecato afferma, e in realtà cito@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 () per URI restituisce solo la parte del percorso dell'URI, come notato sopra.
Pelpotronic,

2
A meno che non mi sbagli, il "percorso" è noto per essere quella parte di un URI dopo la parte dell'autorità (vedi: en.wikipedia.org/wiki/Uniform_Resource_Identifier per la definizione del percorso) - mi sembra il comportamento che sto vedendo è il comportamento standard / corretto. Sto usando Java 1.8.0_101 (su Android Studio). Sarei curioso di vedere come si ottiene "getAuthority ()". Anche questo articolo / esempio sembra indicare che il percorso è solo la parte / public / manual / appliance del loro URI: quepublishing.com/articles/article.aspx?p=26566&seqNum=3
Pelpotronic

1
@Pelpotronic Il codice nel post in realtà stampa l'output che mostra (almeno per me). Penso che la ragione di ciò sia che, a causa della codifica dell'URL, il costruttore dell'URI sta effettivamente trattando l'intera stringa, ( https%3A%2F...), come solo il percorso di un URI; non esiste alcuna autorità, o query, ecc. Questo può essere verificato chiamando i rispettivi metodi get sull'oggetto URI. Se si passa il testo decodificato al costruttore URI:, new URI("https://mywebsite/do.....")quindi chiamandogetPath() e altri metodi daranno risultati corretti.
Kröw,

14

%3Ae %2Fsono caratteri codificati nell'URL. Utilizzare questo codice java per convertirli nuovamente in :e/

String decoded = java.net.URLDecoder.decode(url, "UTF-8");

2
non converte anche% 2C, è (,)
vuhung3990

questo deve essere racchiuso in un blocco try / catch .. leggi di più sulle eccezioni verificate (questa) vs stackoverflow
Bruno Wolff,

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
Potresti per favore elaborare di più la tua risposta aggiungendo un po 'più di descrizione della soluzione che offri?
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")); 

    } 

}

Puoi selezionare saggiamente il tuo metodo :)


0

Utilizzando la classe java.net.URI:

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

Si noti che la gestione delle eccezioni può essere migliore, ma non è molto rilevante per questo esempio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.