Vejledning til Java URL-kodning / afkodning

1. Introduktion

Kort sagt, URL-kodning oversætter specialtegn fra URL'en til en repræsentation, der overholder specifikationen og kan forstås korrekt og fortolkes.

I denne artikel vil vi fokusere på hvordan man koder / afkoder URL'en eller formulardata så den overholder specifikationen og transmitteres korrekt over netværket.

2. Analyser URL'en

En grundlæggende URI-syntaks kan generaliseres som:

skema: [// [bruger: [e-mailbeskyttet]] vært [: port]] [/] sti [? forespørgsel] [# fragment]

Det første trin i kodning af en URI er at undersøge dens dele og derefter kun kode de relevante dele.

Lad os 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åde at analysere URI er at indlæse strengrepræsentationen til en java.net.URI klasse:

@Test offentligt ugyldigt givetURL_whenAnalyze_thenCorrect () kaster undtagelse {URI uri = ny URI (testUrl); assertThat (uri.getScheme (), er ("http")); assertThat (uri.getHost (), er ("www.baeldung.com")); assertThat (uri.getRawQuery (), .is ("key1 = værdi + 1 & key2 = værdi% 40% 21% 242 & key3 = værdi% 253")); }

Det URI klasse analyserer strengrepræsentations-URL'en og udsætter dens dele via en simpel API - f.eks. getXXX.

3. Kod URL'en

Ved kodning af URI er en af ​​de almindelige faldgruber at kode for den komplette URI. Typisk skal vi kun kode forespørgselsdelen af ​​URI.

Lad os kode dataene ved hjælp af kode (data, encodingScheme) metode til URLEncoder klasse:

private String encodeValue (String value) {return URLEncoder.encode (value, StandardCharsets.UTF_8.toString ()); } @Test offentlig ugyldighed givenRequestParam_whenUTF8Scheme_thenEncode () kaster Undtagelse {Map requestParams = ny HashMap (); requestParams.put ("nøgle1", "værdi 1"); requestParams.put ("key2", "[email protected]! $ 2"); requestParams.put ("key3", "værdi% 3"); String encodedURL = requestParams.keySet (). Stream () .map (key -> key + "=" + encodeValue (requestParams.get (key))) .collect (sammenføjning ("&", "//www.baeldung. com? "," ")); assertThat (testUrl, is (encodedURL)); 

Det kode metode accepterer to parametre:

  1. data - streng, der skal oversættes
  2. kodningSkema - navnet på tegnkodningen

Det her kode metode konverterer strengen til application / x-www-form-urlencoded format.

Kodningsskemaet konverterer specialtegn til to cifre hexadecimal repræsentation af 8 bits, der vil blive repræsenteret i form af “% xy“. Når vi har at gøre med styparametre eller tilføjer parametre, som er dynamiske, koder vi dataene og sender derefter til serveren.

Bemærk: Det World Wide Web Consortium Anbefaling hedder det UTF-8 skal bruges. Hvis du ikke gør det, kan det medføre inkompatibilitet. (Reference: //docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html)

4. Afkod URL'en

Lad os nu afkode den forrige URL ved hjælp af dekodningsmetoden til URLDecoder:

privat strengafkodning (strengværdi) {return URLDecoder.decode (værdi, StandardCharsets.UTF_8.toString ()); } @Test offentlig ugyldighed givenRequestParam_whenUTF8Scheme_thenDecodeRequestParams () {URI uri = ny URI (testUrl); Strengskema = uri.getScheme (); String vært = uri.getHost (); Strengeforespørgsel = uri.getRawQuery (); String decodedQuery = Arrays.stream (query.split ("&")) .map (param -> param.split ("=") [0] + "=" + dekod (param.split ("=") [1 ])) .collect (Collectors.joining ("&")); assertEquals ("//www.baeldung.com?key1=værdi 1 & [e-mailbeskyttet]! $ 2 & key3 = værdi% 3", skema + ": //" + vært + "?" + dekodet forespørgsel); }

De to vigtige bits her er:

  • analyser URL før afkodning
  • brug den samme kodningsplan til kodning og afkodning

Hvis vi skulle afkode end analysere, blev URL-dele muligvis ikke parset korrekt. Hvis vi brugte et andet kodningsskema til at afkode dataene, ville det resultere i skraldata.

5. Kod et stiksegment

URLEncoder kan ikke bruges til kodning af stisegment af URL. Stykomponent henviser til den hierarkiske struktur, der repræsenterer en biblioteksti, eller den tjener til at lokalisere ressourcer adskilt af “/”.

Reserverede tegn i stisegment er forskellige end i forespørgselsparameterværdier. For eksempel er et “+” - tegn et gyldigt tegn i stisegmentet og bør derfor ikke kodes.

For at kode stisegmentet bruger vi UriUtils klasse i stedet for Spring Framework. UriUtils klasse giver encodePath og encodePathSegment metoder til kodning af henholdsvis sti og stisegment.

Lad os se på et eksempel:

private String encodePath (streng sti) {prøv {sti = UriUtils.encodePath (sti, "UTF-8"); } fange (UnsupportedEncodingException e) {LOGGER.error ("Fejlkodningsparameter {}", e.getMessage (), e); } returvej }
@Test offentlig ugyldighed 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 ovenstående kodestykke kan vi se, at når vi brugte encodePathSegment metode returnerede den den kodede værdi og + kodes ikke, fordi det er et værditegn i stykomponenten.

Lad os tilføje en stivariabel til vores test-URL:

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

og for at samle og hævde en korrekt kodet URL, lad os ændre testen fra afsnit 2:

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

6. Konklusion

I denne vejledning har vi set, hvordan vi koder og afkoder dataene, så de kan overføres og fortolkes korrekt. Mens artiklen fokuserede på kodning / afkodning af URI-forespørgselsparameterværdier, gælder fremgangsmåden også for HTML-formularparametre.

Du kan finde kildekoden over på GitHub.