Guide de codage / décodage d'URL Java

1. Introduction

En termes simples, le codage d'URL traduit les caractères spéciaux de l'URL en une représentation qui adhère aux spécifications et peut être correctement comprise et interprétée.

Dans cet article, nous allons nous concentrer sur la façon d'encoder / décoder l'URL ou les données de formulaire afin qu'elles adhèrent aux spécifications et transmettent correctement sur le réseau.

2. Analysez l'URL

Une syntaxe URI de base peut être généralisée comme suit:

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

La première étape du codage d'un URI consiste à examiner ses parties, puis à ne coder que les parties pertinentes.

Regardons un exemple d'URI:

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

Une façon d'analyser l'URI consiste à charger la représentation String dans une 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 analyse l'URL de représentation sous forme de chaîne et expose ses parties via une API simple - par exemple, getXXX.

3. Encodez l'URL

Lors du codage de l'URI, l'un des pièges les plus courants est le codage de l'URI complet. En règle générale, nous devons encoder uniquement la partie requête de l'URI.

Encodons les données à l'aide de la méthode encode (data, encodingScheme) de la 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)); 

La méthode d' encode accepte deux paramètres:

  1. data - chaîne à traduire
  2. encodingScheme - nom du codage de caractères

Cette méthode d' encodage convertit la chaîne au format application / x-www-form-urlencoded .

Le schéma d'encodage convertira les caractères spéciaux en deux chiffres de représentation hexadécimale de 8 bits qui seront représentés sous la forme de « % xy ». Lorsque nous traitons des paramètres de chemin ou que nous ajoutons des paramètres dynamiques, nous encoderons les données puis les enverrons au serveur.

Note: Le World Wide Web Consortium Recommandation stipule que UTF-8 doit être utilisé. Ne pas le faire peut introduire des incompatibilités. (Référence: //docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html )

4. Décodez l'URL

Décodons maintenant l'URL précédente en utilisant la méthode de décodage de l' 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); }

Les deux éléments importants ici sont:

  • analyser l'URL avant le décodage
  • utiliser le même schéma d'encodage pour l'encodage et le décodage

Si nous devions décoder plutôt qu'analyser, les portions d'URL pourraient ne pas être analysées correctement. Si nous utilisions un autre schéma de codage pour décoder les données, cela entraînerait des données inutiles.

5. Encoder un segment de chemin

URLEncoder ne peut pas être utilisé pour coder le segment de chemin de l' URL . Le composant Path fait référence à la structure hiérarchique qui représente un chemin de répertoire, ou il sert à localiser les ressources séparées par «/» .

Les caractères réservés dans le segment de chemin sont différents des valeurs des paramètres de requête. Par exemple, un signe «+» est un caractère valide dans le segment de chemin et ne doit donc pas être codé.

Pour encoder le segment de chemin, nous utilisons la classe UriUtils de Spring Framework à la place. La classe UriUtils fournit les méthodes encodePath et encodePathSegment pour coder respectivement le chemin et le segment de chemin.

Regardons un exemple:

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

Dans l'extrait de code ci-dessus, nous pouvons voir que lorsque nous avons utilisé la méthode encodePathSegment , elle a renvoyé la valeur encodée et + n'est pas encodé car il s'agit d'un caractère de valeur dans le composant de chemin.

Ajoutons une variable de chemin à notre URL de test:

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

et pour assembler et affirmer une URL correctement codée, changeons le test de la section 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. Conclusion

Dans ce tutoriel, nous avons vu comment encoder et décoder les données afin qu'elles puissent être transférées et interprétées correctement. Bien que l'article se concentre sur le codage / décodage des valeurs des paramètres de requête URI, l'approche s'applique également aux paramètres de formulaire HTML.

Vous pouvez trouver le code source sur GitHub.