Powiedz, ż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 na osiągnięcie tego? Próbowałem URLEncoder
utworzyć obiekty URI / URL, ale żaden z nich nie wyszedł całkiem dobrze.
Odpowiedzi:
URLEncoder
jest droga. Trzeba tylko pamiętać, aby zakodować tylko nazwę i / lub wartość parametru pojedynczego ciągu zapytania, a nie cały adres URL, na pewno nie znak separatora parametru ciągu zapytania&
ani znak separatora nazwa-wartość parametru=
.Zauważ, że spacje w parametrach zapytania są reprezentowane przez
+
, a nie%20
, co jest zgodne z prawem.%20
Zwykle być używany do reprezentowania w samej przestrzeni (część przed URI-separatora ciąg znaków zapytania URI?
), a nie w ciągu zapytania (po części?
).Pamiętaj również, że istnieją trzy
encode()
metody. Jeden bezCharset
drugiego argumentu i drugi zString
drugim argumentem, który zgłasza sprawdzony wyjątek. Ten bezCharset
argumentu jest przestarzały. Nigdy go nie używaj i zawsze określajCharset
argument. Javadoc nawet wyraźnie zaleca stosowanie kodowania UTF-8, przewidzianym w RFC3986 i W3C .Zobacz też:
źródło
URLEncoder
parametry zapytań zakodowane w adresie URL są zgodne zapplication/x-www-form-urlencoded
regułami. Parametry ścieżki nie pasują do tej kategorii. Zamiast tego potrzebujesz kodera URI.Nie użyłbym
URLEncoder
. Poza tym, że ma niepoprawną nazwę (URLEncoder
nie ma nic wspólnego z adresami URL), jest nieefektywny (używaStringBuffer
zamiast Buildera i robi kilka innych rzeczy, które są powolne) Jest to również zbyt łatwe do zepsucia.Zamiast tego chciałbym użyć
URIBuilder
lub sprężynyorg.springframework.web.util.UriUtils.encodeQuery
lub Commons ApacheHttpClient
. Powodem jest to, że musisz zmienić nazwę parametru zapytania (tj. Odpowiedź BalusCq
) inaczej niż wartość parametru.Jedynym minusem powyższego (który dowiedziałem się boleśnie) jest to, że adresy URL nie są prawdziwym podzbiorem identyfikatorów URI .
Przykładowy kod:
Ponieważ odsyłam do innych odpowiedzi, oznaczyłem to jako wiki społeczności. Nie krępuj się edytować.
źródło
URLEncoder
jest, jak mówi javadoc, przeznaczone do kodowania parametrów ciągu zapytania zgodnych zapplication/x-www-form-urlencoded
opisem w specyfikacji HTML: w3.org/TR/html4/interact/… . Niektórzy użytkownicy rzeczywiście mylą / nadużywają go do kodowania całych identyfikatorów URI, jak najwyraźniej obecny użytkownik odpowiadający.Musisz najpierw utworzyć identyfikator URI, taki jak:
Następnie przekonwertuj ten Uri na ciąg ASCII:
Teraz twój ciąg adresu URL jest całkowicie zakodowany, najpierw wykonaliśmy proste kodowanie adresu URL, a następnie przekonwertowaliśmy go na ciąg ASCII, aby upewnić się, że żaden ciąg poza US-ASCII nie pozostanie w ciągu. Właśnie tak robią przeglądarki.
źródło
URL.toURI()
nie.+
zastąpienia spacji, ale zaakceptował% 20, więc to rozwiązanie działało lepiej niż BalusC, dzięki!Guava 15 dodał teraz zestaw prostych kodów ucieczki adresów URL .
źródło
URLEncoder
.URLEncoder
nie.Biblioteka komponentów Apache Http zapewnia ciekawą opcję budowania i kodowania parametrów zapytań -
Z HttpComponents 4.x użyj - URLEncodedUtils
Do użytku w HttpClient 3.x - EncodingUtil
źródło
Oto metoda, której możesz użyć w kodzie, aby przekonwertować ciąg adresu URL i mapę parametrów na prawidłowy zakodowany ciąg adresu URL zawierający parametry zapytania.
źródło
Wydruki
Co tu się dzieje?
1. Podziel adres URL na części strukturalne. Użyj
java.net.URL
do tego.2. Zakoduj poprawnie każdą część konstrukcyjną!
3. Użyj
IDN.toASCII(putDomainNameHere)
aby Punycode zakodować nazwę hosta!4. Użyj
java.net.URI.toASCIIString()
do kodowania procentowego, kodowania NFC unicode - (lepiej byłoby NFKC!). Aby uzyskać więcej informacji, zobacz: Jak poprawnie zakodować ten adres URLW niektórych przypadkach wskazane jest sprawdzenie, czy adres URL jest już zakodowany . Zastąp także spacje zakodowane „+” spacjami zakodowanymi „% 20”.
Oto kilka przykładów, które również będą działać poprawnie
Rozwiązanie przechodzi około 100 przypadków testowych dostarczonych przez Web Plattform Tests .
źródło
W Androidzie użyłbym tego kodu:
Gdzie
Uri
jestandroid.net.Uri
źródło
W moim przypadku musiałem tylko przekazać cały adres URL i zakodować tylko wartość każdego parametru. Nie znalazłem wspólnego kodu, aby to zrobić (!!), więc stworzyłem tę małą metodę wykonania zadania:
Wykorzystuje org.apache.commons.lang3.StringUtils
źródło
Możesz użyć następującego kodu.
źródło
=
i&
, co jest niepoprawne.