Вопрос-ответ

Java URL encoding of query string parameters

Java URL-кодирование параметров строки запроса

Допустим, у меня есть URL-адрес

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

и у меня есть запрос, введенный пользователем, такой как:


случайное слово в банке стоимостью 500 фунтов стерлингов $


Я хочу, чтобы результатом был правильно закодированный URL-адрес:

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

Какой наилучший способ добиться этого? Я пробовал URLEncoder и создавать объекты URI / URL, но ни один из них не работает должным образом.

Переведено автоматически
Ответ 1

URLEncoder вот как нужно поступить. Вам нужно помнить только о том, что нужно кодировать только имя и / или значение отдельного параметра строки запроса, а не весь URL-адрес, и уж точно не символ-разделитель параметров строки запроса & или символ-разделитель имени параметра и значения =.

String q = "random word £500 bank $";
String url = "https://example.com?q=" + URLEncoder.encode(q, StandardCharsets.UTF_8);

Если вы все еще не используете Java 10 или новее, используйте StandardCharsets.UTF_8.name() в качестве аргумента кодировки, или если вы все еще не используете Java 7 или новее, используйте "UTF-8".


Обратите внимание, что пробелы в параметрах запроса представлены через +, а не %20, что является допустимым. %20 Обычно используется для представления пробелов в самом URI (часть перед символом разделителя строки URI-запроса ?), а не в строке запроса (часть после ?).

Также обратите внимание, что существует три encode() метода. Один без Charset в качестве второго аргумента, а другой с String в качестве второго аргумента, который выдает проверяемое исключение. Кодировка без Charset аргумента устарела. Никогда не используйте его и всегда указывайте Charset аргумент. В javadoc даже явно рекомендуется использовать кодировку UTF-8, как предписано RFC3986 и W3C.


Все остальные символы небезопасны и сначала преобразуются в один или несколько байтов с использованием некоторой схемы кодирования. Тогда каждый байт представлен 3-символьной строкой "%xy", где xy - двузначное шестнадцатеричное представление байта. Рекомендуемая схема кодирования для использования - UTF-8. Однако, по соображениям совместимости, если кодировка не указана, используется кодировка платформы по умолчанию.


Смотрите также:

Ответ 2

Я бы не стал использовать URLEncoder. Помимо неправильного имени (URLEncoder не имеет ничего общего с URL-адресами), неэффективен (использует StringBuffer вместо Builder и выполняет пару других медленных действий) Также слишком легко все испортить.

Instead I would use URIBuilder or Spring's org.springframework.web.util.UriUtils.encodeQuery or Commons Apache HttpClient.
The reason being you have to escape the query parameters name (ie BalusC's answer q) differently than the parameter value.

The only downside to the above (that I found out painfully) is that URL's are not a true subset of URI's.

Sample 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
Ответ 3

You need to first create a URI like:

String urlStr = "http://www.example.com/CEREC® Materials & Accessories/IPS Empress® CAD.pdf"
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());

Then convert that URI to an ASCII string:

urlStr = uri.toASCIIString();

Now your URL string is completely encoded. First we did simple URL encoding and then we converted it to an ASCII string to make sure no character outside US-ASCII remained in the string. This is exactly how browsers do it.

Ответ 4
java