Powiedzmy, że mam adres URL
http://example.com/query?q=
i mam zapytanie wprowadzone przez użytkownika, takie jak:
losowe słowo £500 bank $
Chcę, aby wynik był poprawnie zakodowanym adresem URL:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
Jaki jest najlepszy sposób, aby to osiągnąć? Próbowałem URLEncoder
i tworzenie obiektów URI/URL, ale żaden z nich nie wyszedł całkiem dobrze.
URLEncoder
powinien być drogą do zrobienia. Musisz tylko pamiętać, aby kodować tylko poszczególne nazwy i/lub wartości parametrów łańcucha zapytania, nie cały URL, na pewno nie znak separatora parametrów łańcucha zapytania &
ani znak separatora nazwa-wartość =
.
String q = "random word £500 bank $";
String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");
Zauważ, że spacje w parametrach zapytania są reprezentowane przez +
, a nie %20
, co jest prawnie poprawne. %20
jest zwykle używane do reprezentowania spacji w samym URI (część przed znakiem separatora łańcuchów zapytań URI ?
), nie w łańcuchach zapytań (część po ?
).
Zauważ również, że istnieją dwie metody encode()
. Jedna bez argumentu charset i druga z. Ta bez argumentu charset jest zdeprecjonowana. Nigdy jej nie używaj i zawsze podawaj argument charset. The javadoc nawet wyraźnie zaleca używanie kodowania UTF-8, jak nakazuje RFC3986 i W3C.
Wszystkie inne znaki nie są bezpieczne i są najpierw konwertowane na jeden lub więcej bajtów przy użyciu jakiegoś schematu kodowania. Następnie każdy bajt jest reprezentowany przez trzyznakowy łańcuch "%xy", gdzie xy jest dwucyfrową szesnastkową reprezentacją bajtu. Zalecanym schematem kodowania jest UTF-8. Jednakże, ze względu na kompatybilność, jeśli kodowanie nie jest określone, to używane jest domyślne kodowanie platformy.
Nie używałbym URLEncoder
. Poza tym, że jest niepoprawnie nazwany (URLEncoder
nie ma nic wspólnego z URLami), nieefektywny (używa StringBuffer
zamiast Buildera i robi kilka innych rzeczy, które są powolne) to jeszcze zbyt łatwo go spieprzyć.
Zamiast tego użyłbym URIBuilder
lub Spring's org.springframework.web.util.UriUtils.encodeQuery
lub Commons Apache HttpClient
.
Powodem jest to, że musisz uciec nazwę parametrów zapytania (tj. BalusC's odpowiedź q
) inaczej niż wartość parametru.
Jedynym minusem powyższego (który odkryłem boleśnie) jest to, że URL's nie są prawdziwym podzbiorem URI's.
Przykładowy kod:
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
Ponieważ łączę się z innymi odpowiedziami, oznaczyłem to jako wiki społeczności. Czuj się swobodnie do edycji.