URL-Codierung in Android


335

Wie verschlüsselt man eine URL in Android?

Ich dachte es wäre so:

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

Wenn ich das oben genannte mache, wird das http://In urlAsStringdurch http%3A%2F%2FIn ersetzt encodedURLund ich erhalte ein, java.net.MalformedURLExceptionwenn ich die URL verwende.

Antworten:


630

Sie verschlüsseln nicht die gesamte URL, sondern nur Teile davon, die aus "unzuverlässigen Quellen" stammen.

String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;

Alternativ können Sie Strings.urlEncode (String str) von DroidParts verwenden , das keine Ausnahmen .

Oder benutze so etwas wie

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();

1
Was ist, wenn die gesamte URL unzuverlässig ist? Soll ich alles außer dem Protokoll verschlüsseln? Ich habe irgendwie eine bequeme Methode erwartet, um dies zu tun.
hpique

5
Dann ist es nur eine kaputte URL. Die Idee ist zu verhindern, dass der Abfrageteil die URL bricht.
Yanchenko

5
@hgpc - Sehen Sie sich Abschnitt 3 von RFC3986 an ( tools.ietf.org/html/rfc3986#section-3 ). Hier erfahren Sie, wie Sie die verschiedenen Teile eines URI codieren. Leider hat jeder Teil des URI (Host, Pfad, Abfrage usw.) leicht unterschiedliche Codierungsregeln.
D. Shawley

2
Dies ist in Ordnung, da Sie sich nur mit einem bestimmten Teil einer URL befassen und wissen, wie Sie die URL erstellen oder rekonstruieren. Einen allgemeineren Ansatz, der mit jeder URL-Zeichenfolge umgehen kann, finden Sie in meiner Antwort unten.
Craig B

8
Warum erhalte ich damit eine Abwertungswarnung? Wird Uri.encode(query);stattdessen verwendet.
Prasanthv

166

Ich werde hier einen Vorschlag hinzufügen. Sie können dies tun, ohne externe Bibliotheken abrufen zu müssen.

Probieren Sie es aus:

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 in dieser bestimmten URL diese Leerzeichen codiert sein müssen, damit ich sie für eine Anfrage verwenden kann.

Dies nutzt einige Funktionen, die Ihnen in Android-Klassen zur Verfügung stehen. Erstens kann die URL-Klasse eine URL in ihre richtigen Komponenten aufteilen, sodass Sie keine Arbeit zum Suchen / Ersetzen von Zeichenfolgen ausführen müssen. Zweitens nutzt dieser Ansatz die URI-Klassenfunktion, um Komponenten ordnungsgemäß zu maskieren, wenn Sie einen URI über Komponenten anstatt aus einer einzelnen Zeichenfolge erstellen.

Das Schöne an diesem Ansatz ist, dass Sie jede gültige URL-Zeichenfolge verwenden können, ohne dass Sie selbst spezielle Kenntnisse darüber benötigen.


19
Dies sollte die richtige Antwort sein. Dies ist der formelle und klare Weg, dies zu tun
Asanka Senavirathna

3
Es kann auch eine gute Idee sein, urlStr vor dem Senden an den URL-Konstruktor zu urldecodieren. URLDecoder.decode (urlStr)
Jakob Eriksson

1
Danke für den Beitrag :) Aber ich stehe vor einem Problem. Wenn die URL bereits teilweise codiert ist, codiert sie die bereits codierten Teile. Was sollte ich tun? Zum Beispiel: dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/… Die% 20 ist in% 2520 codiert
Berserker

2
@berserk Wenn es bereits codiert ist, codieren Sie es nicht. Sie sollten nicht in einen Zustand geraten, in dem es teilweise codiert ist, oder Sie sind sich nicht sicher, ob es codiert ist oder nicht.
Marquis von Lorne

3
Diese Methode codiert keine Zeichen wie ğ bis% C4% 9F. Akzeptiert verschlüsselt man!
Alexander Prokofyev

73

Für Android würde ich String android.net.Uri.encode (String s) verwenden

Codiert Zeichen in der angegebenen Zeichenfolge als '%' - maskierte Oktette mit dem UTF-8-Schema. Lässt Buchstaben ("AZ", "az"), Zahlen ("0-9") und nicht reservierte Zeichen ("_- !. ~ '() *") intakt. Codiert alle anderen Zeichen.

Ex/

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);

2
Leider Uri.encode("a=1&b=1")produziert a%3D1%26b%3D1aber erwarteta=1&b=1
Loentar

14
@loentar Das ist das erwartete Ergebnis. Wenn der Benutzer a=1&b=1als Abfrage eingibt , möchten Sie genau das abfragen.
Anubian Noob

Wie anders das mit URLEncoder.encode (StringHere, "UTF-8")
Stuckedoverflow

@stuckedoverflow Zum einen löst Uri.encode (str) im Gegensatz zu URLEncoder.encode (str, "UTF-8")
keine

50

Auch Sie können dies verwenden

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

Es ist die einfachste Methode


1
Dies ist nicht die beste Lösung, aber es ist definitiv eine schöne schnelle Lösung ... Danke
Sebastian Breit

4
Dies ist die schnellste Lösung, wenn die gesamte URL unzuverlässig ist. Vielen Dank!
user1032613

Sind Sie sicher, dass% erlaubt sein sollte? Sollte es nicht verschlüsselt werden?
MediumOne

1
So codieren Sie diese URL, damit sie geteilt werden kann, und dann kann der Benutzer den Link öffnen und die Seite anzeigen
Ahmad Ebrahimi

3
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

1

Sie können die folgenden Methoden verwenden

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

oder

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

Der zweite ist besser als der erste.


0

Suchen Sie nach arabischen Zeichen und ersetzen Sie sie durch die UTF-8-Codierung. etwas wie das:

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.