Wie mache ich eine URL-Dekodierung in Java?

323

In Java möchte ich Folgendes konvertieren:

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

Dazu:

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

Das habe ich bisher:

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

Aber es funktioniert nicht richtig. Wie heißen diese %3Aund %2FFormate und wie konvertiere ich sie?

Crackerplace
quelle
@Stephen .. Warum kann eine URL nicht UTF-8-codiert sein String ..?
Crackerplace
Das Problem ist, dass nur weil die URL UTF-8 sein kann, die Frage wirklich nichts mit UTF-8 zu tun hat. Ich habe die Frage entsprechend bearbeitet.
Chris Jester-Young
Es könnte (theoretisch) sein, aber die Zeichenfolge in Ihrem Beispiel ist keine UTF-8-codierte Zeichenfolge. Es ist eine URL-codierte ASCII-Zeichenfolge. Daher ist der Titel irreführend.
Stephen C
Es ist auch erwähnenswert, dass alle Zeichen in der urlZeichenfolge ASCII sind, und dies gilt auch, nachdem die Zeichenfolge URL-decodiert wurde. '%'ist ein ASCII-Zeichen und %xxstellt ein ASCII-Zeichen dar, wenn xxes kleiner als (hexadezimal) ist 80.
Stephen C

Antworten:

634

Dies hat nichts mit Zeichencodierungen wie UTF-8 oder ASCII zu tun. Die Zeichenfolge, die Sie dort haben, ist URL-codiert . Diese Art der Codierung ist etwas völlig anderes als die Zeichencodierung.

Versuchen Sie so etwas:

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 hat Charsetder API direkte Unterstützung hinzugefügt , sodass UnsupportedEncodingException nicht abgefangen werden muss:

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

Beachten Sie, dass eine Zeichencodierung (wie UTF-8 oder ASCII) die Zuordnung von Zeichen zu Rohbytes bestimmt. Eine gute Einführung in die Zeichenkodierung finden Sie in diesem Artikel .

Jesper
quelle
1
Die Methoden URLDecodersind statisch, sodass Sie keine neue Instanz davon erstellen müssen.
Laz
2
@Trismegistos Nur die Version, in der Sie die Zeichenkodierung nicht angeben (der zweite Parameter "UTF-8"), ist gemäß der Java 7-API-Dokumentation veraltet. Verwenden Sie die Version mit zwei Parametern.
Jesper
23
Wenn Sie Java 1.7+ verwenden, können Sie die statische Version der Zeichenfolge "UTF-8" verwenden: StandardCharsets.UTF_8.name()aus diesem Paket : java.nio.charset.StandardCharsets. Relevant dafür: Link
Shahar
1
Für die Zeichenkodierung ist dies ein großartiger Artikel. Balusc.blogspot.in/2009/05/unicode-how-to-get-characters-right.html
crackerplace
4
Sei vorsichtig damit. Wie hier angegeben: blog.lunatech.com/2009/02/03/… Hier geht es nicht um URLs, sondern um die HTML-Formularcodierung.
Michal
52

Die Zeichenfolge, die Sie haben, ist in application/x-www-form-urlencodedCodierung.

Verwenden Sie URLDecoder , um es in Java String zu konvertieren.

URLDecoder.decode( url, "UTF-8" );
Alexander Pogrebnyak
quelle
47

Dies beantwortet wurde vor (obwohl diese Frage zuerst war!):

"Sie sollten dazu java.net.URI verwenden, da die URLDecoder-Klasse eine falsche x-www-form-urlencodierte Decodierung durchführt (trotz des Namens handelt es sich um Formulardaten)."

In der Dokumentation zur URL- Klasse heißt es:

Die empfohlene Methode zum Verwalten der Codierung und Decodierung von URLs besteht darin, URI zu verwenden und mit toURI () und URI.toURL () zwischen diesen beiden Klassen zu konvertieren .

Die Klassen URLEncoder und URLDecoder können ebenfalls verwendet werden, jedoch nur für die HTML-Formularcodierung, die nicht mit dem in RFC2396 definierten Codierungsschema identisch ist .

Grundsätzlich:

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

werde dir geben:

https://mywebsite/docs/english/site/mybook.do?request_type
Nick Grealy
quelle
6
In Java 1.7 ist die URLDecoder.decode(String, String)Überlastung nicht veraltet. Sie müssen sich auf die URLDecoder.decode(String)Überlastung ohne die Codierung beziehen . Möglicherweise möchten Sie Ihren Beitrag zur Verdeutlichung aktualisieren.
Aaron
2
Diese Antwort ist irreführend; Dieses Blockzitat hat nichts mit der Wertminderung zu tun. Der Javadoc der veralteten Methode besagt, und ich zitiere tatsächlich@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 () für URIs gibt nur den Pfadteil des URI zurück, wie oben angegeben.
Pelpotronic
2
Wenn ich mich nicht irre, ist der "Pfad" bekanntermaßen der Teil einer URI nach dem Autoritätsteil (siehe: en.wikipedia.org/wiki/Uniform_Resource_Identifier für die Definition des Pfads) - es scheint mir das Verhalten zu sein, das ich sehe ist das Standard- / korrekte Verhalten. Ich verwende Java 1.8.0_101 (unter Android Studio). Ich wäre gespannt, was Sie als "getAuthority ()" erhalten. Sogar dieser Artikel / dieses Beispiel scheint darauf hinzudeuten, dass der Pfad nur der / public / manual / appliances-Teil ihrer URI ist: quepublishing.com/articles/article.aspx?p=26566&seqNum=3
Pelpotronic
1
@Pelpotronic Der Code im Beitrag druckt tatsächlich die angezeigte Ausgabe (zumindest für mich). Ich denke, der Grund dafür ist, dass der URI-Konstruktor aufgrund der URL-Codierung tatsächlich die gesamte Zeichenfolge ( https%3A%2F...) als nur den Pfad eines URI behandelt. Es gibt keine Berechtigung oder Abfrage usw. Dies kann getestet werden, indem die entsprechenden get-Methoden für das URI-Objekt aufgerufen werden. Wenn Sie den dekodierten Text an den URI-Konstruktor: übergeben new URI("https://mywebsite/do....."), führen Aufruf getPath()und andere Methoden zu korrekten Ergebnissen.
Kröw
14

%3Aund %2Fsind URL-codierte Zeichen. Verwenden Sie diesen Java-Code, um sie wieder in :und zu konvertieren/

String decoded = java.net.URLDecoder.decode(url, "UTF-8");
laz
quelle
2
es konvertiert nicht% 2C auch, es ist (,)
vuhung3990
Dies muss in einen Try / Catch-Block eingeschlossen werden. Lesen Sie mehr über geprüfte Ausnahmen (diese) gegen ungeprüfte stackoverflow.com/questions/6115896/…
Bruno Wolff
5
 try {
        String result = URLDecoder.decode(urlString, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
Hsm
quelle
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
quelle
4
Könnten Sie bitte Ihre Antwort näher erläutern und etwas mehr Beschreibung der von Ihnen bereitgestellten Lösung hinzufügen?
Abarisone
3

Ich benutze Apache Commons

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

Der Standardzeichensatz ist UTF-8

Sorter
quelle
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")); 

    } 

}

Sie können Ihre Methode mit Bedacht auswählen :)

Rinuthomaz
quelle
0

Verwenden der Klasse java.net.URI:

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

Bitte beachten Sie, dass die Ausnahmebehandlung besser sein kann, für dieses Beispiel jedoch nicht sehr relevant ist.

x7BiT
quelle