Tarkime, kad turiu URL adresą
http://example.com/query?q=
ir turiu naudotojo įvestą užklausą, pvz:
atsitiktinis žodis £500 bank $
Noriu, kad rezultatas būtų tinkamai užkoduotas URL adresas:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
Koks'yra geriausias būdas tai pasiekti? Bandžiau URLEncoder
ir kurti URI/URL objektus, bet nė vienas iš jų neišėjo visiškai tinkamas.
URLEncoder
turėtų būti tinkamas būdas. Tik reikia nepamiršti, kad reikia koduoti tik atskirų užklausos eilutės parametrų pavadinimus ir (arba) reikšmes, o ne visą URL adresą, ir tikrai ne užklausos eilutės parametrų skiriamąjį simbolį &
bei parametro pavadinimo ir reikšmės skiriamąjį simbolį =
.
String q = "random word £500 bank $";
String url = "http://example.com/query?q=" + URLEncoder.encode(q, "UTF-8");
Atkreipkite dėmesį, kad tarpai užklausos parametruose žymimi +
, o ne %20
, kuris yra teisėtas. %20
paprastai naudojamas tarpams pačiame URI (dalyje prieš URI ir užklausos eilutės skiriamąjį simbolį ?
), o ne užklausos eilutėje (dalyje po ?
) žymėti.
Taip pat atkreipkite dėmesį, kad yra du encode()
metodai. Vienas be charset argumento, kitas - su charset argumentu. Metodas be charset argumento yra nebenaudojamas. Niekada jo nenaudokite ir visada nurodykite charset argumentą. javadoc netgi aiškiai rekomenduojama naudoti UTF-8 koduotę, kaip nurodyta RFC3986 ir W3C.
Visi kiti simboliai yra nesaugūs ir pirmiausia konvertuojami į vieną ar daugiau baitų naudojant tam tikrą kodavimo schemą. Tada kiekvienas baitas vaizduojamas trijų simbolių eilute "%xy", kur xy yra dviženklis šešioliktainis baito atvaizdas. Rekomenduojama naudoti UTF-8 kodavimo schemą. Tačiau suderinamumo sumetimais, jei koduotė nenurodyta, naudojama numatytoji platformos koduotė.
Nenaudočiau URLEncoder
. Be to, kad jis neteisingai pavadintas (URLEncoder
neturi nieko bendro su URL), neefektyvus (vietoj Builder jis naudoja StringBuffer
ir atlieka keletą kitų lėtų veiksmų), jį taip pat pernelyg lengva sugadinti.
Vietoj to aš naudočiau URIBuilder
arba Spring's org.springframework.web.util.UriUtils.encodeQuery
arba Commons Apache HttpClient
.
Priežastis yra ta, kad užklausos parametro vardą (t. y. BalusC'o atsakymą q
) reikia užrašyti kitaip nei parametro reikšmę.
Vienintelis aukščiau pateikto būdo trūkumas (kurį skaudžiai sužinojau) yra tas, kad URL'ai nėra tikras URI'ų poaibis.
Kodo pavyzdys:
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
Kadangi aš tiesiog pateikiu nuorodas į kitus atsakymus, pažymėjau tai kaip bendruomenės wiki. Jauskitės laisvi redaguoti.