Anleitung zur Java-URL-Codierung / -Decodierung

1. Einleitung

Einfach ausgedrückt übersetzt die URL-Codierung Sonderzeichen von der URL in eine Darstellung, die der Spezifikation entspricht und korrekt verstanden und interpretiert werden kann.

In diesem Artikel konzentrieren wir uns darauf, wie die URL oder Formulardaten so codiert / decodiert werden , dass sie der Spezifikation entsprechen und korrekt über das Netzwerk übertragen werden.

2. Analysieren Sie die URL

Eine grundlegende URI-Syntax kann wie folgt verallgemeinert werden:

scheme:[//[user:[email protected]]host[:port]][/]path[?query][#fragment]

Der erste Schritt zum Codieren eines URI besteht darin, seine Teile zu untersuchen und dann nur die relevanten Teile zu codieren.

Schauen wir uns ein Beispiel für eine URI an:

String testUrl = "//www.baeldung.com?key1=value+1&key2=value%40%21%242&key3=value%253";

Eine Möglichkeit zur Analyse des URI besteht darin, die String-Darstellung in eine java.net.URI- Klasse zu laden :

@Test public void givenURL_whenAnalyze_thenCorrect() throws Exception { URI uri = new URI(testUrl); assertThat(uri.getScheme(), is("http")); assertThat(uri.getHost(), is("www.baeldung.com")); assertThat(uri.getRawQuery(), .is("key1=value+1&key2=value%40%21%242&key3=value%253")); }

Die URI- Klasse analysiert die URL der Zeichenfolgendarstellung und macht ihre Teile über eine einfache API verfügbar - z . B. getXXX.

3. Codieren Sie die URL

Bei der Codierung des URI besteht eine der häufigsten Gefahren darin, den vollständigen URI zu codieren. Normalerweise müssen wir nur den Abfrageteil des URI codieren.

Codieren wir die Daten mit der Methode encode (data, encodingScheme) der URLEncoder- Klasse:

private String encodeValue(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } @Test public void givenRequestParam_whenUTF8Scheme_thenEncode() throws Exception { Map requestParams = new HashMap(); requestParams.put("key1", "value 1"); requestParams.put("key2", "[email protected]!$2"); requestParams.put("key3", "value%3"); String encodedURL = requestParams.keySet().stream() .map(key -> key + "=" + encodeValue(requestParams.get(key))) .collect(joining("&", "//www.baeldung.com?", "")); assertThat(testUrl, is(encodedURL)); 

Die Codierungsmethode akzeptiert zwei Parameter:

  1. Daten - String übersetzt werden
  2. encodingScheme - Name der Zeichenkodierung

Diese Codierungsmethode konvertiert die Zeichenfolge in das Format application / x-www-form-urlencoded .

Das Codierungsschema konvertiert Sonderzeichen in eine zweistellige hexadezimale Darstellung von 8 Bits, die in Form von „ % xy “ dargestellt werden. Wenn wir uns mit Pfadparametern befassen oder dynamische Parameter hinzufügen, werden wir die Daten codieren und dann an den Server senden.

Hinweis: Die Empfehlung des World Wide Web Consortium besagt, dass UTF-8 verwendet werden sollte. Andernfalls kann es zu Inkompatibilitäten kommen. (Referenz: //docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html )

4. Dekodieren Sie die URL

Lassen Sie uns nun die vorherige URL mit der Dekodierungsmethode des URLDecoders dekodieren :

private String decode(String value) { return URLDecoder.decode(value, StandardCharsets.UTF_8.toString()); } @Test public void givenRequestParam_whenUTF8Scheme_thenDecodeRequestParams() { URI uri = new URI(testUrl); String scheme = uri.getScheme(); String host = uri.getHost(); String query = uri.getRawQuery(); String decodedQuery = Arrays.stream(query.split("&")) .map(param -> param.split("=")[0] + "=" + decode(param.split("=")[1])) .collect(Collectors.joining("&")); assertEquals( "//www.baeldung.com?key1=value 1&[email protected]!$2&key3=value%3", scheme + "://" + host + "?" + decodedQuery); }

Die zwei wichtigen Punkte hier sind:

  • Analysieren Sie die URL vor dem Dekodieren
  • Verwenden Sie zum Codieren und Decodieren dasselbe Codierungsschema

Wenn wir dekodieren als analysieren, werden URL-Teile möglicherweise nicht richtig analysiert. Wenn wir ein anderes Codierungsschema zum Decodieren der Daten verwenden würden, würde dies zu Mülldaten führen.

5. Codieren Sie ein Pfadsegment

URLEncoder kann nicht zum Codieren des Pfadsegments der URL verwendet werden . Die Pfadkomponente bezieht sich auf die hierarchische Struktur, die einen Verzeichnispfad darstellt, oder dient zum Auffinden von Ressourcen, die durch "/" getrennt sind .

Reservierte Zeichen im Pfadsegment unterscheiden sich von den Abfrageparameterwerten. Beispielsweise ist ein "+" - Zeichen ein gültiges Zeichen im Pfadsegment und sollte daher nicht codiert werden.

Um das Pfadsegment zu codieren, verwenden wir stattdessen die UriUtils- Klasse von Spring Framework. Die UriUtils- Klasse bietet die Methoden encodePath und encodePathSegment zum Codieren des Pfads bzw. des Pfadsegments .

Schauen wir uns ein Beispiel an:

private String encodePath(String path) { try { path = UriUtils.encodePath(path, "UTF-8"); } catch (UnsupportedEncodingException e) { LOGGER.error("Error encoding parameter {}", e.getMessage(), e); } return path; }
@Test public void givenPathSegment_thenEncodeDecode() throws UnsupportedEncodingException { String pathSegment = "/Path 1/Path+2"; String encodedPathSegment = encodePath(pathSegment); String decodedPathSegment = UriUtils.decode(encodedPathSegment, "UTF-8"); assertEquals("/Path%201/Path+2", encodedPathSegment); assertEquals("/Path 1/Path+2", decodedPathSegment); }

Im obigen Codeausschnitt sehen wir, dass bei Verwendung der Methode encodePathSegment der codierte Wert zurückgegeben wurde und + nicht codiert wird, da es sich um ein Wertzeichen in der Pfadkomponente handelt.

Fügen wir unserer Test-URL eine Pfadvariable hinzu:

String testUrl = "/path+1?key1=value+1&key2=value%40%21%242&key3=value%253";

und um eine ordnungsgemäß codierte URL zusammenzustellen und zu bestätigen, ändern wir den Test aus Abschnitt 2:

String path = "path+1"; String encodedURL = requestParams.keySet().stream() .map(k -> k + "=" + encodeValue(requestParams.get(k))) .collect(joining("&", "/" + encodePath(path) + "?", "")); assertThat(testUrl, CoreMatchers.is(encodedURL)); 

6. Fazit

In diesem Tutorial haben wir gesehen, wie die Daten codiert und decodiert werden, damit sie korrekt übertragen und interpretiert werden können. Während sich der Artikel auf das Codieren / Decodieren von URI-Abfrageparameterwerten konzentrierte, gilt der Ansatz auch für HTML-Formularparameter.

Sie finden den Quellcode auf GitHub.