Veiledning til Java URL-koding / dekoding

1. Introduksjon

Enkelt sagt, URL-koding oversetter spesialtegn fra URL-en til en representasjon som følger spesifikasjonen og kan forstås og tolkes riktig.

I denne artikkelen vil vi fokusere på hvordan kode / dekode URL eller skjemadata slik at den overholder spesifikasjonen og overføres riktig over nettverket.

2. Analyser URL-en

En grunnleggende URI-syntaks kan generaliseres som:

skjema: [// [bruker: [e-postbeskyttet]] vert [: port]] [/] bane [? spørring] [# fragment]

Det første trinnet i å kode en URI er å undersøke delene og deretter bare kode de relevante delene.

La oss se på et eksempel på en URI:

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

En måte å analysere URI er å laste strengrepresentasjonen til a java.net.URI klasse:

@Test offentlig ugyldighet gittURL_whenAnalyze_thenCorrect () kaster unntak {URI uri = ny URI (testUrl); assertThat (uri.getScheme (), er ("http")); assertThat (uri.getHost (), er ("www.baeldung.com")); assertThat (uri.getRawQuery (), .is ("key1 = verdi + 1 & key2 = verdi% 40% 21% 242 & key3 = verdi% 253")); }

De URI klasse analyserer URL-en for strengrepresentasjon og avslører delene via en enkel API - f.eks. getXXX.

3. Kod URL-en

Når du koder for URI, er en av de vanligste fallgruvene koding av hele URI. Vanligvis trenger vi bare å kode spørringsdelen av URI.

La oss kode dataene ved hjelp av kode (data, encodingScheme) metoden for URLEncoder klasse:

private String encodeValue (String value) {return URLEncoder.encode (value, StandardCharsets.UTF_8.toString ()); } @Test offentlig ugyldighet gittRequestParam_whenUTF8Scheme_thenEncode () kaster Unntak {Map requestParams = ny HashMap (); requestParams.put ("nøkkel1", "verdi 1"); requestParams.put ("key2", "[email protected]! $ 2"); requestParams.put ("key3", "verdi% 3"); Streng encodedURL = requestParams.keySet (). Stream () .map (key -> key + "=" + encodeValue (requestParams.get (key))) .collect (joining ("&", "//www.baeldung. com? "," ")); assertThat (testUrl, is (encodedURL)); 

De kode metoden godtar to parametere:

  1. data - streng som skal oversettes
  2. encodingScheme - navnet på tegnkodingen

Dette kode metoden konverterer strengen til application / x-www-form-urlencoded format.

Kodingsskjemaet vil konvertere spesialtegn til to sifre heksadesimal representasjon av 8 bits som vil bli representert i form av “% xy“. Når vi har å gjøre med baneparametere eller legger til parametere som er dynamiske, vil vi kode dataene og deretter sende til serveren.

Merk: De World Wide Web Consortium Anbefaling sier at UTF-8 burde bli brukt. Hvis du ikke gjør det, kan det medføre inkompatibilitet. (Henvisning: //docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html)

4. Dekoder URL-en

La oss nå dekode forrige URL ved hjelp av dekodingsmetoden til URLDecoder:

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

De to viktige bitene her er:

  • analyser URL før dekoding
  • bruk samme kodingsskjema for koding og dekoding

Hvis vi skulle dekode enn å analysere, kan det hende at URL-deler ikke blir analysert riktig. Hvis vi brukte et annet kodeskjema for å dekode dataene, ville det føre til søppeldata.

5. Kode et stisegment

URLEncoder kan ikke brukes til koding av banesegment av URL. Banekomponent refererer til den hierarkiske strukturen som representerer en katalogbane, eller den tjener til å finne ressurser atskilt med “/”.

Reserverte tegn i stisegment er forskjellige enn i spørreparameterverdier. For eksempel er et "+" -tegn et gyldig tegn i banesegmentet og bør derfor ikke kodes.

For å kode stisegmentet bruker vi UriUtils klasse av Spring Framework i stedet. UriUtils klasse gir encodePath og encodePathSegment metoder for henholdsvis koding av sti og stisegment.

La oss se på et eksempel:

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

I kodebiten ovenfor kan vi se at når vi brukte encodePathSegment metode, returnerte den den kodede verdien og + blir ikke kodet fordi det er et verditegn i banekomponenten.

La oss legge til en stavariabel i test-URL: en:

Streng testUrl = "/ sti + 1? Key1 = verdi + 1 & key2 = verdi% 40% 21% 242 & key3 = verdi% 253";

og for å sette sammen og hevde en riktig kodet URL, la oss endre testen fra avsnitt 2:

Strengsti = "sti + 1"; String encodedURL = requestParams.keySet (). Stream () .map (k -> k + "=" + encodeValue (requestParams.get (k))) .collect (sammenføyning ("&", "/" + encodePath (bane) ) + "?", "")); assertThat (testUrl, CoreMatchers.is (encodedURL)); 

6. Konklusjon

I denne opplæringen har vi sett hvordan vi kan kode og dekode dataene slik at de kan overføres og tolkes riktig. Mens artikkelen fokuserte på koding / dekoding av URI-søkeparameterverdier, gjelder tilnærmingen også HTML-skjemaparametere.

Du kan finne kildekoden på GitHub.