391 Stimmen

HTTP-URL-Adresskodierung in Java

Meine Java-Standalone-Anwendung erhält vom Benutzer eine URL (die auf eine Datei verweist), und ich muss sie anklicken und herunterladen. Das Problem, das ich konfrontiert bin, ist, dass ich nicht in der Lage bin, die HTTP-URL-Adresse richtig zu kodieren...

Ejemplo:

URL:  http://search.barnesandnoble.com/booksearch/first book.pdf

java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");

gibt mich zurück:

http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf

Aber was ich will, ist

http://search.barnesandnoble.com/booksearch/first%20book.pdf

(Leerzeichen ersetzt durch %20)

Ich denke URLEncoder ist nicht dafür ausgelegt, HTTP-URLs zu kodieren... In der JavaDoc heißt es "Utility class for HTML form encoding"... Gibt es eine andere Möglichkeit, dies zu tun?

322voto

user85421 Punkte 28350

Le site java.net.URI Klasse kann helfen; in der Dokumentation von URL finden Sie

Beachten Sie, dass die URI-Klasse unter bestimmten Umständen ein Escaping ihrer Komponentenfelder durchführt. Der empfohlene Weg, um die Kodierung und Dekodierung von URLs zu verwalten, ist die Verwendung einer URI

Verwenden Sie einen der Konstruktoren mit mehr als einem Argument, z. B:

URI uri = new URI(
    "http", 
    "search.barnesandnoble.com", 
    "/booksearch/first book.pdf",
    null);
URL url = uri.toURL();
//or String request = uri.toString();

(der Ein-Argument-Konstruktor von URI lässt illegale Zeichen NICHT entkommen)


Nur unzulässige Zeichen werden von obigem Code escaped - Nicht-ASCII-Zeichen werden NICHT escaped (siehe fatihs Kommentar).
Die toASCIIString Methode kann verwendet werden, um einen String nur mit US-ASCII-Zeichen zu erhalten:

URI uri = new URI(
    "http", 
    "search.barnesandnoble.com", 
    "/booksearch/é",
    null);
String request = uri.toASCIIString();

Für eine URL mit einer Abfrage wie http://www.google.com/ig/api?weather=São Paulo verwenden Sie die 5-Parameter-Version des Konstruktors:

URI uri = new URI(
        "http", 
        "www.google.com", 
        "/ig/api",
        "weather=São Paulo",
        null);
String request = uri.toASCIIString();

97voto

Matt Punkte 1080

Bitte beachten Sie, dass die meisten der obigen Antworten FALSCH sind.

Le site URLEncoder Klasse, trotz ihres Namens, ist NICHT das, was hier sein muss. Es ist bedauerlich, dass Sun diese Klasse so ärgerlich benannt hat. URLEncoder ist für die Übergabe von Daten als Parameter gedacht, nicht für die Verschlüsselung der URL selbst.

Mit anderen Worten, "http://search.barnesandnoble.com/booksearch/first book.pdf" ist die URL. Die Parameter wären zum Beispiel, "http://search.barnesandnoble.com/booksearch/first book.pdf?parameter1=this&param2=that" . Die Parameter sind die, die Sie verwenden würden URLEncoder für.

Die folgenden zwei Beispiele verdeutlichen die Unterschiede zwischen den beiden.

Das folgende Beispiel erzeugt die falschen Parameter gemäß dem HTTP-Standard. Beachten Sie, dass das kaufmännische Und (&) und das Plus (+) falsch kodiert sind.

uri = new URI("http", null, "www.google.com", 80, 
"/help/me/book name+me/", "MY CRZY QUERY! +&+ :)", null);

// URI: http://www.google.com:80/help/me/book%20name+me/?MY%20CRZY%20QUERY!%20+&+%20:)

Das folgende Beispiel liefert die richtigen Parameter, wobei die Abfrage richtig kodiert ist. Beachten Sie die Leerzeichen, Ampersands und Pluszeichen.

uri = new URI("http", null, "www.google.com", 80, "/help/me/book name+me/", URLEncoder.encode("MY CRZY QUERY! +&+ :)", "UTF-8"), null);

// URI: http://www.google.com:80/help/me/book%20name+me/?MY+CRZY+QUERY%2521+%252B%2526%252B+%253A%2529

92voto

Craig B Punkte 4639

Ich werde hier einen Vorschlag hinzufügen, der sich an Android-Nutzer richtet. Sie können dies tun, die vermeidet, um alle externen Bibliotheken zu erhalten. Auch alle Suchen/Ersetzen Zeichen Lösungen in einigen der Antworten oben vorgeschlagen sind gefährlich und sollte vermieden werden.

Versuchen Sie dies:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

Sie können sehen, dass ich in dieser speziellen URL die Leerzeichen kodieren muss, damit ich sie für eine Anfrage verwenden kann.

Dabei werden einige Funktionen genutzt, die Ihnen in Android-Klassen zur Verfügung stehen. Erstens kann die URL-Klasse eine URL in ihre Komponenten zerlegen, so dass Sie keine Zeichenfolgen suchen/ersetzen müssen. Zweitens nutzt dieser Ansatz die Funktion der URI-Klasse, Komponenten ordnungsgemäß zu escapen, wenn Sie einen URI über Komponenten und nicht aus einem einzelnen String konstruieren.

Das Schöne an diesem Ansatz ist, dass Sie eine beliebige gültige URL-Zeichenkette verwenden können, ohne dass Sie selbst besondere Kenntnisse darüber haben müssen.

49voto

fmucar Punkte 14031

Eine von mir entwickelte Lösung, die viel stabiler ist als alle anderen:

public class URLParamEncoder {

    public static String encode(String input) {
        StringBuilder resultStr = new StringBuilder();
        for (char ch : input.toCharArray()) {
            if (isUnsafe(ch)) {
                resultStr.append('%');
                resultStr.append(toHex(ch / 16));
                resultStr.append(toHex(ch % 16));
            } else {
                resultStr.append(ch);
            }
        }
        return resultStr.toString();
    }

    private static char toHex(int ch) {
        return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
    }

    private static boolean isUnsafe(char ch) {
        if (ch > 128 || ch < 0)
            return true;
        return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
    }

}

41voto

Scott Izu Punkte 2099

Wenn Sie eine URL haben, können Sie url.toString() an diese Methode übergeben. Dekodieren Sie zunächst, um eine doppelte Kodierung zu vermeiden (die Kodierung eines Leerzeichens ergibt z. B. %20 und die Kodierung eines Prozentzeichens ergibt %25, so dass eine doppelte Kodierung ein Leerzeichen in %2520 verwandelt). Dann verwenden Sie den URI wie oben beschrieben und fügen alle Teile der URL hinzu (damit Sie die Abfrageparameter nicht weglassen).

public URL convertToURLEscapingIllegalCharacters(String string){
    try {
        String decodedURL = URLDecoder.decode(string, "UTF-8");
        URL url = new URL(decodedURL);
        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); 
        return uri.toURL(); 
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X