Gids voor Java URL-codering / decodering

1. Inleiding

Simpel gezegd, URL-codering vertaalt speciale tekens van de URL naar een weergave die voldoet aan de specificatie en correct kan worden begrepen en geïnterpreteerd.

In dit artikel zullen we ons concentreren op hoe u de URL of formuliergegevens codeert / decodeert zodat het zich aan de specificaties houdt en correct over het netwerk verzendt.

2. Analyseer de URL

Een standaard URI-syntaxis kan worden gegeneraliseerd als:

schema: [// [gebruiker: [e-mail beschermd]] host [: poort]] [/] pad [? query] [# fragment]

De eerste stap bij het coderen van een URI is het onderzoeken van de onderdelen ervan en vervolgens het coderen van alleen de relevante delen.

Laten we eens kijken naar een voorbeeld van een URI:

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

Een manier om de URI te analyseren is het laden van de String-weergave naar een java.net.URI klasse:

@ Test openbare ongeldige gegevenURL_whenAnalyze_thenCorrect () gooit uitzondering {URI uri = nieuwe URI (testUrl); assertThat (uri.getScheme (), is ("http")); assertThat (uri.getHost (), is ("www.baeldung.com")); assertThat (uri.getRawQuery (), .is ("key1 = waarde + 1 & key2 = waarde% 40% 21% 242 & key3 = waarde% 253")); }

De URI class parseert de tekenreeksweergave-URL en stelt de onderdelen ervan bloot via een eenvoudige API - bijv. getXXX.

3. Codeer de URL

Bij het coderen van URI's is een van de meest voorkomende valkuilen het coderen van de volledige URI. Meestal hoeven we alleen het querygedeelte van de URI te coderen.

Laten we de gegevens coderen met de coderen (data, encodingScheme) methode van de URLEncoder klasse:

private String encodeValue (String waarde) {return URLEncoder.encode (waarde, StandardCharsets.UTF_8.toString ()); } @Test openbare ongeldig gegevenRequestParam_whenUTF8Scheme_thenEncode () gooit uitzondering {Map requestParams = nieuwe 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 (join ("&", "//www.baeldung. com? "," ")); assertThat (testUrl, is (encodedURL)); 

De coderen methode accepteert twee parameters:

  1. gegevens - tekenreeks die moet worden vertaald
  2. encodingScheme - naam van de tekencodering

Dit coderen methode zet de string om in application / x-www-form-urlencoded formaat.

Het coderingsschema zet speciale tekens om in een hexadecimale weergave van twee cijfers van 8 bits die wordt weergegeven in de vorm van "% xy“. Als we te maken hebben met padparameters of het toevoegen van parameters die dynamisch zijn, zullen we de gegevens coderen en vervolgens naar de server sturen.

Opmerking: De Wereldwijde web consortium Aanbeveling stelt dat UTF-8 zou gebruikt moeten worden. Als u dit niet doet, kunnen er onverenigbaarheden ontstaan. (Referentie: //docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html)

4. Decodeer de URL

Laten we nu de vorige URL decoderen met behulp van de decoderingsmethode van de URLDecoder:

private String decode (String waarde) {return URLDecoder.decode (waarde, StandardCharsets.UTF_8.toString ()); } @Test openbare ongeldig gegevenRequestParam_whenUTF8Scheme_thenDecodeRequestParams () {URI uri = nieuwe URI (testUrl); Tekenreeksschema = uri.getScheme (); String host = uri.getHost (); Tekenreeksquery = 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); }

De twee belangrijke stukjes hier zijn:

  • analyseer URL alvorens te decoderen
  • gebruik hetzelfde coderingsschema voor codering en decodering

Als we zouden decoderen dan analyseren, worden URL-delen mogelijk niet correct geparseerd. Als we een ander coderingsschema zouden gebruiken om de gegevens te decoderen, zou dit resulteren in afvalgegevens.

5. Codeer een padsegment

URLEncoder kan niet worden gebruikt voor het coderen van padsegment van het URL. Padcomponent verwijst naar de hiërarchische structuur die een mappad vertegenwoordigt, of het dient om bronnen te lokaliseren die zijn gescheiden door “/”.

Gereserveerde tekens in padsegment zijn anders dan in queryparameterwaarden. Een "+" -teken is bijvoorbeeld een geldig teken in het padsegment en mag daarom niet worden gecodeerd.

Om het padsegment te coderen, gebruiken we de UriUtils class door Spring Framework. UriUtils klasse biedt encodePath en encodePathSegment methoden voor het coderen van respectievelijk pad en padsegment.

Laten we naar een voorbeeld kijken:

private String encodePath (String path) {probeer {path = UriUtils.encodePath (pad, "UTF-8"); } catch (UnsupportedEncodingException e) {LOGGER.error ("Fout bij het coderen van parameter {}", e.getMessage (), e); } terugweg; }
@Test openbare leegte gegevenPathSegment_thenEncodeDecode () gooit UnsupportedEncodingException {String pathSegment = "/ Pad 1 / Pad + 2"; String encodedPathSegment = encodePath (pathSegment); String decodedPathSegment = UriUtils.decode (encodedPathSegment, "UTF-8"); assertEquals ("/ Path% 201 / Path + 2", encodedPathSegment); assertEquals ("/ Path 1 / Path + 2", decodedPathSegment); }

In het bovenstaande codefragment kunnen we dat zien toen we de encodePathSegment methode, retourneerde het de gecodeerde waarde en + wordt niet gecodeerd omdat het een waardeteken is in de padcomponent.

Laten we een padvariabele toevoegen aan onze test-URL:

String testUrl = "/ pad + 1? Key1 = waarde + 1 & key2 = waarde% 40% 21% 242 & key3 = waarde% 253";

en om een ​​correct gecodeerde URL samen te stellen en te bevestigen, laten we de test wijzigen van sectie 2:

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

6. Conclusie

In deze zelfstudie hebben we gezien hoe de gegevens moeten worden gecodeerd en gedecodeerd, zodat ze correct kunnen worden overgedragen en geïnterpreteerd. Hoewel het artikel zich richtte op het coderen / decoderen van URI-queryparameterwaarden, is de benadering ook van toepassing op HTML-formulierparameters.

Je kunt de broncode vinden op GitHub.