Строка, экранирующая символы Java ASCII [дубликат]

Для меня это произошло потому, что я изменил тип аргумента в функции, от Object a, до String a. Я мог бы решить это с чистой и построить снова

567
задан Abdull 23 November 2016 в 17:39
поделиться

9 ответов

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

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

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

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

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

См. Также:

944
ответ дан bplpu 16 August 2018 в 03:51
поделиться
  • 1
    вы должны использовать StandardCharsets.UTF_8 вместо жестко запрограммированной константы. – TmTron merge me 3 July 2017 в 14:14
  • 2
    В URL-адресе могут быть два типа параметров. Строка запроса (за которой следует?) И параметр пути (как правило, часть самого URL). Итак, как насчет параметров пути. URLEncoder производит + для пространства даже для параметров пути. На самом деле он просто не обрабатывает ничего, кроме строки запроса. Кроме того, это поведение не синхронизируется с узлами js-серверов. Поэтому для меня этот класс является отходами и не может использоваться иначе, чем для особых / специальных сценариев. – sharadendu sinha 30 July 2017 в 07:15
  • 3
    @sharadendusinha: как описано и подтверждено, URLEncoder для URL-кодированных параметров запроса соответствует правилам application/x-www-form-urlencoded. Параметры пути не соответствуют этой категории. Вместо этого вам нужен кодер URI. – BalusC 30 July 2017 в 13:18
  • 4
    Добавляя к комментарию @TmTron комментарий, точнее следует использовать строчную константу StandardCharsets.UTF_8.name() – Jose Duarte 28 February 2018 в 18:48
  • 5
    @WijaySharma: поскольку URL-специфичные символы также будут закодированы. Это нужно делать только тогда, когда вы хотите передать весь URL как параметр запроса другого URL-адреса. – BalusC 15 March 2018 в 10:59

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

Вместо этого я использовал бы URIBuilder или Spring org.springframework.web.util.UriUtils.encodeQuery или Commons Apache HttpClient . Причина заключается в том, что вам нужно избегать имени параметров запроса (то есть ответ BalusC q) иначе, чем значение параметра.

Единственный недостаток вышеизложенного (что я обнаружил болезненно) заключается в том, что URL не является истинным подмножеством URI .

Пример кода:

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

Поскольку я просто ссылаюсь на другие ответы, я отметил это как вики сообщества. Не стесняйтесь редактировать.

135
ответ дан 9 revs, 5 users 62% 16 August 2018 в 03:51
поделиться
  • 1
    Почему это не имеет ничего общего с URL-адресами? – Luis Sep 26 January 2015 в 15:55
  • 2
    @Luis: URLEncoder, так как его javadoc говорит, что он намерен кодировать параметры строки запроса application/x-www-form-urlencoded, как описано в спецификации HTML: w3.org/TR/html4/interact/… . Некоторые пользователи действительно путают / злоупотребляют им для кодирования всех URI, как, по-видимому, нынешний ответчик. – BalusC 3 February 2015 в 19:15
  • 3
    @LuisSep коротким URLEncoder предназначен для кодирования для отправки формы. Это не для побега. Его не точный точный , который вы использовали бы для создания URL-адресов, которые будут помещены на вашу веб-страницу, но, похоже, достаточно похожи, чтобы люди злоупотребляли им. Единственный раз, когда вы должны использовать URLEncoder, является то, что вы пишете HTTP-клиент (и даже тогда есть намного лучшие варианты кодирования). – Adam Gent 3 February 2015 в 20:48
  • 4
    @BalusC " Некоторые пользователи действительно путают / злоупотребляют им для кодирования целых URI, как это делал текущий ответчик. & quot ;. Вы ошибались. Я никогда не говорил, что я это испортил. Я только что видел других, которые это сделали, у кого есть ошибки, которые я должен исправить. Часть, которую я испортил, заключается в том, что класс URL-адреса Java принимает неэкранированные скобки, но не URI-класс. Есть много способов испортить создание URL-адресов, и не все такие блестящие, как вы. Я бы сказал, что большинство пользователей, которые смотрят на SO для URLEncoding, вероятно, являются пользователями , действительно путают / злоупотребляют & quot; Сбой URI. – Adam Gent 3 February 2015 в 21:12
  • 5
    Вопрос не в том, что ваш ответ подразумевает это. – BalusC 3 February 2015 в 21:14

Я бы использовал этот код:

Uri myUI = Uri.parse ("http://example.com/query").buildUpon().appendQueryParameter("q","random word A3500 bank 24").build();
1
ответ дан DomTomCat 16 August 2018 в 03:51
поделиться
  • 1
    Это не использует стандартный Java API. Поэтому, пожалуйста, укажите используемую библиотеку. – rmuller 10 July 2016 в 08:35

Теперь Guava 15 добавила набор простых URL-адресов escapers .

28
ответ дан Emmanuel Touzery 16 August 2018 в 03:51
поделиться
  • 1
    Они страдают от тех же самых правил, что и в случае URLEncoder. – 2rs2ts 28 August 2014 в 23:53
  • 2
    не уверен, что у них есть проблема. они различают, например, "+" или "% 20" чтобы избежать " & Quot; (форма param или path param), которые URLEncoder нет. – Emmanuel Touzery 16 April 2015 в 11:01
  • 3
    Это сработало для меня. Я просто заменил вызов на URLEncoder (), чтобы позвонить в UrlEscapers.urlFragmentEscaper (), и это сработало, но не ясно, следует ли вместо этого использовать UrlEscapers.urlPathSegmentEscaper (). – Paul Taylor 2 November 2015 в 13:18
  • 4
    На самом деле это не работало для меня, потому что в отличие от URLEncoder он не кодирует «+», он оставляет его в покое, сервер декодирует «+» как пространство, тогда как если я использую URLEncoder '+', они преобразуются в% 2B и правильно декодируются обратно до + – Paul Taylor 2 November 2015 в 18:52
  • 5
    Обновление ссылок: UrlEscapers – mgaert 15 June 2017 в 09:50
[Д2] 1. Разделить URL-адрес на структурные части. Для этого используйте java.net.URL.

2. Кодируйте каждую структурную часть правильно!

3. Использовать IDN.toASCII(putDomainNameHere) - Punycode кодировать имя хоста!

4. Используйте java.net.URI.toASCIIString() для процентного кодирования, кодированного в кодировке NFC unicode - (лучше было бы NFKC!). Для получения дополнительной информации см.: Как правильно закодировать этот URL

URL url= new URL("http://example.com/query?q=random word £500 bank $");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String correctEncodedURL=uri.toASCIIString(); 
System.out.println(correctEncodedURL);

Печать

http://example.com/query?q=random%20word%20%C2%A3500%20bank%20$
1
ответ дан jschnasse 16 August 2018 в 03:51
поделиться

Вам нужно сначала создать URI, например:

    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());

Затем преобразовать эту строку Uri в ASCII:

    urlStr=uri.toASCIIString();

Теперь ваша строка url полностью закодирована, простое кодирование url, а затем мы преобразовали его в ASCII String, чтобы убедиться, что в строке нет символа вне US-ASCII. Это как раз то, как делают браузеры.

85
ответ дан M Abdul Sami 16 August 2018 в 03:51
поделиться
  • 1
    Благодаря! Глупо, что ваше решение работает, но встроенный URL.toURI() не работает. – user11153 25 March 2015 в 13:45
  • 2
    К сожалению, это, похоже, не работает с & quot; file: /// & quot; (например: «файл: /// some / directory / файл, содержащий spaces.html»); он бомбит MalformedURLException в «новом URL ()»; любая идея, как это исправить? – ZioByte 30 April 2015 в 10:23
  • 3
    Вам нужно сделать что-то вроде этого: String urlStr = & quot; файл some / directory / a , содержащий spaces.html & quot ;; URL url = новый URL (urlStr); URI uri = новый URI (url.getProtocol (), url.getUserInfo (), url.getHost (), url.getPort (), url.getPath (), url.getQuery (), url.getRef ()); urlStr = uri.toASCIIString (); urlStr.replace (& Quot; HTTP: // & Quot;, & Quot; Файл: /// & Quot;); Я его не тестировал, но думаю, что это сработает .... :) – M Abdul Sami 30 April 2015 в 20:14
  • 4
    Я использовал это с тех пор, как начал работать в Android, но сегодня я заметил, что строки + и = = в строках запроса не закодированы, а какое-либо решение? – Rudy_TM 11 May 2015 в 20:23
  • 5
    @tibi вы можете просто использовать метод uri.toString (), чтобы преобразовать его в строку вместо строки Ascii. – M Abdul Sami 9 September 2015 в 03:40
  • 6
    – Julian Honma 1 September 2017 в 12:44

Вот способ, который вы можете использовать в своем коде для преобразования строки url и карты параметров в действительную кодированную строку url, содержащую параметры запроса.

String addQueryStringToUrlString(String url, final Map<Object, Object> parameters) throws UnsupportedEncodingException {
    if (parameters == null) {
        return url;
    }

    for (Map.Entry<Object, Object> parameter : parameters.entrySet()) {

        final String encodedKey = URLEncoder.encode(parameter.getKey().toString(), "UTF-8");
        final String encodedValue = URLEncoder.encode(parameter.getValue().toString(), "UTF-8");

        if (!url.contains("?")) {
            url += "?" + encodedKey + "=" + encodedValue;
        } else {
            url += "&" + encodedKey + "=" + encodedValue;
        }
    }

    return url;
}
5
ответ дан Pellet 16 August 2018 в 03:51
поделиться

Библиотека Apache Http Components предоставляет опрятную опцию для создания и кодирования параметров запроса -

с использованием HttpComponents 4.x - URLEncodedUtils

Для HttpClient 3 .x use - EncodingUtil

5
ответ дан Sashi 16 August 2018 в 03:51
поделиться
  1. Используйте это: URLEncoder.encode (query, StandardCharsets.UTF_8.displayName ()); или это: URLEncoder.encode (запрос, «UTF-8»);
  2. Вы можете использовать следующий код.
    String encodedUrl1 = UriUtils.encodeQuery(query, "UTF-8");//not change 
    String encodedUrl2 = URLEncoder.encode(query, "UTF-8");//changed
    String encodedUrl3 = URLEncoder.encode(query, StandardCharsets.UTF_8.displayName());//changed
    
    System.out.println("url1 " + encodedUrl1 + "\n" + "url2=" + encodedUrl2 + "\n" + "url3=" + encodedUrl3);
    
-2
ответ дан Xuelian Han 16 August 2018 в 03:51
поделиться
  • 1
    Не верно. Вы должны кодировать имена параметров и значения отдельно. Кодирование всей строки запроса также будет кодировать разделители = и &, что неверно. – user207421 13 February 2018 в 02:40
Другие вопросы по тегам:

Похожие вопросы: