Guida alla codifica / decodifica di URL Java

1. Introduzione

In poche parole, la codifica URL traduce i caratteri speciali dall'URL in una rappresentazione che aderisce alle specifiche e può essere correttamente compresa e interpretata.

In questo articolo, ci concentreremo su come codificare / decodificare l'URL o i dati del modulo in modo che aderiscano alle specifiche e trasmettano correttamente sulla rete.

2. Analizza l'URL

Una sintassi di base dell'URI può essere generalizzata come:

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

Il primo passaggio nella codifica di un URI è l'esame delle sue parti e quindi la codifica solo delle parti pertinenti.

Vediamo un esempio di URI:

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

Un modo per analizzare l'URI è caricare la rappresentazione della stringa in una classe java.net.URI :

@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")); }

La classe URI analizza l'URL di rappresentazione della stringa ed espone le sue parti tramite una semplice API, ad esempio getXXX.

3. Codifica l'URL

Quando si codifica l'URI, uno dei problemi più comuni è la codifica dell'URI completo. In genere, è necessario codificare solo la porzione di query dell'URI.

Codifichiamo i dati usando il metodo encode (data, encodingScheme) della classe URLEncoder :

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)); 

Il metodo encode accetta due parametri:

  1. data - stringa da tradurre
  2. encodingScheme : nome della codifica dei caratteri

Questo metodo di codifica converte la stringa nel formato application / x-www-form-urlencoded .

Lo schema di codifica convertirà i caratteri speciali in una rappresentazione esadecimale a due cifre di 8 bit che verranno rappresentati sotto forma di " % xy ". Quando abbiamo a che fare con parametri di percorso o aggiungendo parametri dinamici, codificheremo i dati e quindi li invieremo al server.

Nota: la raccomandazione del World Wide Web Consortium afferma che deve essere utilizzato UTF-8 . Non farlo potrebbe introdurre incompatibilità. (Riferimento: //docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html )

4. Decodificare l'URL

Cerchiamo ora di decodificare l'URL precedente utilizzando il metodo di decodifica di URLDecoder :

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

I due bit importanti qui sono:

  • analizzare l'URL prima della decodifica
  • utilizzare lo stesso schema di codifica per la codifica e la decodifica

Se dovessimo decodificare che analizzare, le porzioni di URL potrebbero non essere analizzate correttamente. Se usassimo un altro schema di codifica per decodificare i dati, si otterrebbero dati inutili.

5. Codifica un segmento di percorso

URLEncoder non può essere utilizzato per codificare il segmento di percorso dell'URL . Il componente Path si riferisce alla struttura gerarchica che rappresenta un percorso di directory, oppure serve per individuare risorse separate da "/" .

I caratteri riservati nel segmento di percorso sono diversi dai valori dei parametri di query. Ad esempio, un segno "+" è un carattere valido nel segmento di percorso e pertanto non deve essere codificato.

Per codificare il segmento del percorso, utilizziamo invece la classe UriUtils di Spring Framework. La classe UriUtils fornisce i metodi encodePath e encodePathSegment per la codifica rispettivamente del percorso e del segmento di percorso.

Vediamo un esempio:

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

Nel frammento di codice sopra possiamo vedere che quando abbiamo utilizzato il metodo encodePathSegment , ha restituito il valore codificato e + non viene codificato perché è un carattere di valore nel componente path.

Aggiungiamo una variabile di percorso al nostro URL di prova:

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

e per assemblare e affermare un URL codificato correttamente, cambiamo il test dalla sezione 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. Conclusione

In questo tutorial abbiamo visto come codificare e decodificare i dati in modo che possano essere trasferiti e interpretati correttamente. Sebbene l'articolo si concentri sulla codifica / decodifica dei valori dei parametri di query URI, l'approccio si applica anche ai parametri del modulo HTML.

Puoi trovare il codice sorgente su GitHub.