Java URL codering van query string parameters

Stel ik heb een URL

http://example.com/query?q=

en ik heb een query ingevoerd door de gebruiker zoals:

random woord £500 bank $

Ik wil dat het resultaat een juist gecodeerde URL is:

http://example.com/query?q=random%20word%20%A3500%20bank%20%24

Wat's de beste manier om dit te bereiken? Ik heb URLEncoder en het maken van URI/URL objecten geprobeerd, maar geen van allen komt helemaal goed.

Oplossing

URLEncoder zou de manier moeten zijn om te gaan. Je moet er alleen aan denken om alleen de individuele query string parameter naam en/of waarde te coderen, niet de hele URL, en zeker niet het query string parameter scheidingsteken & of het parameter naam-waarde scheidingsteken =.

String q = "random word £500 bank $";
String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");

Merk op dat spaties in query parameters worden weergegeven met +, niet met %20, wat wel geldig is. De %20 wordt meestal gebruikt om spaties in de URI zelf aan te geven (het deel voor het URI-query string scheidingsteken ?), niet in de query string (het deel na ?).

Merk ook op dat er twee encode() methoden zijn. Een zonder charset argument en een met. De methode zonder charset argument is deprecated. Gebruik deze nooit en specificeer altijd het charset argument. De javadoc beveelt zelfs expliciet aan om de UTF-8 encoding te gebruiken, zoals gemandateerd door RFC3986 en W3C.

Alle andere karakters zijn onveilig en worden eerst omgezet in een of meer bytes met behulp van een of ander coderingsschema. Vervolgens wordt elke byte weergegeven door de 3-tekenreeks "%xy", waarbij xy de twee-cijferige hexadecimale weergave van de byte is. Het aanbevolen coderingsschema is UTF-8. Als echter geen codering wordt opgegeven, wordt om compatibiliteitsredenen de standaardcodering van het platform gebruikt.

Zie ook:

Commentaren (11)

Ik zou URLEncoder niet gebruiken. Behalve dat het een onjuiste naam heeft (URLEncoder heeft niets met URLs te maken), inefficiënt (het gebruikt een StringBuffer in plaats van Builder en doet nog een paar andere dingen die traag zijn), is het ook veel te makkelijk om het te verpesten.

In plaats daarvan zou ik URIBuilder of Spring's org.springframework.web.util.UriUtils.encodeQuery of Commons Apache HttpClient gebruiken. De reden hiervoor is dat je de naam van de queryparameters (d.w.z. BalusC's antwoord q) anders moet escapen dan de parameterwaarde.

Het enige nadeel van het bovenstaande (waar ik pijnlijk achter kwam) is dat URL's niet een echte subset van URI's zijn.

Voorbeeld code:

import org.apache.http.client.utils.URIBuilder;

URIBuilder ub = new URIBuilder("http://example.com/query");
ub.addParameter("q", "random word £500 bank \$");
String url = ub.toString();

// Result: http://example.com/query?q=random+word+%C2%A3500+bank+%24

Sinds ik'm alleen maar link naar andere antwoorden heb ik dit gemarkeerd als een community wiki. Voel je vrij om te bewerken.

Commentaren (9)