Мое автономное приложение на Java получает от пользователя URL-адрес (который указывает на файл), и мне нужно нажать его и загрузить. Проблема в том, что я не могу правильно закодировать URL-адрес HTTP ...
Пример:
URL: http://search.barnesandnoble.com/booksearch/first book.pdf
java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");
возвращает меня:
http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf
Но то, что я хочу, это
http://search.barnesandnoble.com/booksearch/first%20book.pdf
(пробел заменен на% 20)
Я предполагаю, URLEncoder
что не предназначен для кодирования URL-адресов HTTP ... JavaDoc говорит "Класс служебных программ для кодирования форм HTML" ... Есть ли другой способ сделать это?
Ответы:
Класс java.net.URI может помочь; в документации по URL вы найдете
Используйте один из конструкторов с более чем одним аргументом, например:
(конструктор URI с одним аргументом НЕ экранирует недопустимые символы)
Только недопустимые символы экранируются вышеуказанным кодом - он НЕ экранирует символы, не входящие в ASCII (см. Комментарий Фатиха). Метод может быть использован , чтобы получить строку только с US-ASCII символов:
toASCIIString
Для URL с таким запросом
http://www.google.com/ig/api?weather=São Paulo
используйте 5-параметрическую версию конструктора:источник
java.net.URI
: он работал отлично (Java 1.6). Я бы упомянул полное имя класса, если бы оно не было стандартным Java, и ссылка указывает на документациюjava.net.URI
. И, судя по комментарию Судхакара, он решил проблему, не включив никаких «общих библиотек»!Пожалуйста, имейте в виду, что большинство ответов выше НЕПРАВИЛЬНЫ.
URLEncoder
Класс, несмотря на это название, не то , что должно быть здесь. К сожалению, Sun назвал этот класс так досадно.URLEncoder
предназначен для передачи данных в качестве параметров, а не для кодирования самого URL.Другими словами,
"http://search.barnesandnoble.com/booksearch/first book.pdf"
это URL. Параметры будут, например"http://search.barnesandnoble.com/booksearch/first book.pdf?parameter1=this¶m2=that"
,. Параметры - это то, что вы бы использовалиURLEncoder
.Следующие два примера подчеркивают различия между ними.
Следующее дает неправильные параметры, в соответствии со стандартом HTTP. Обратите внимание, что амперсанд (&) и плюс (+) кодируются неправильно.
Далее будут получены правильные параметры с правильно закодированным запросом. Обратите внимание на пробелы, амперсанды и знаки плюс.
источник
query = URLEncoder.encode(key) + "=" + URLEncoder.encode(value)
. В документах просто говорится, что «любой символ, который не является допустимым символом URI, указан в кавычках».Я собираюсь добавить одно предложение, предназначенное для пользователей Android. Вы можете сделать это, чтобы избежать необходимости получать какие-либо внешние библиотеки. Кроме того, все решения поиска / замены символов, предложенные в некоторых из приведенных выше ответов, опасны и их следует избегать.
Попробуйте это:
Вы можете видеть, что в этом конкретном URL мне нужно закодировать эти пробелы, чтобы я мог использовать его для запроса.
Это использует преимущества нескольких функций, доступных вам в классах Android. Во-первых, класс URL может разбить URL-адрес на соответствующие компоненты, поэтому вам не нужно выполнять поиск / замену строк. Во-вторых, этот подход использует преимущества класса URI для правильного экранирования компонентов, когда вы создаете URI через компоненты, а не из одной строки.
Прелесть этого подхода в том, что вы можете взять любую действительную строку URL-адреса и заставить ее работать, не требуя каких-либо специальных знаний о ней самостоятельно.
источник
#
.решение, которое я разработал, и гораздо более стабильное, чем любое другое:
источник
String utf8Input = new String(Charset.forName("UTF-8").encode(input).array());
(взято отсюда )Если у вас есть URL, вы можете передать в этот метод url.toString (). Сначала декодируйте, чтобы избежать двойного кодирования (например, кодирование пробела приводит к% 20, а кодирование знака процента приводит к% 25, поэтому двойное кодирование превратит пробел в% 2520). Затем используйте URI, как описано выше, добавляя все части URL-адреса (чтобы не сбрасывать параметры запроса).
источник
Да, URL-кодирование будет кодировать эту строку, чтобы она правильно передавалась по URL-адресу в конечный пункт назначения. Например, у вас не может быть http://stackoverflow.com?url=http://yyy.com . UrlEncoding параметра будет фиксировать значение этого параметра.
Итак, у меня есть два варианта для вас:
У вас есть доступ к пути отдельно от домена? Если это так, вы можете просто UrlEncode пути. Однако, если это не так, то вариант 2 может быть для вас.
Получите commons-httpclient-3.1. Это имеет класс URIUtil:
System.out.println (URIUtil.encodePath (" http://example.com/x y", "ISO-8859-1"));
Это выведет именно то, что вы ищете, поскольку закодирует только часть пути URI.
К вашему сведению, для работы этого метода во время выполнения вам понадобятся кодексы и регистрация.
источник
URIUtil
решениеПометка: строка, содержащая символ пробела по определению, не является URI. Итак, вы ищете код, который реализует экранирование URI, определенное в Разделе 2.1 RFC 3986 .
источник
К сожалению,
org.apache.commons.httpclient.util.URIUtil
это устарело, иreplacement org.apache.commons.codec.net.URLCodec
делает кодирование подходящим для сообщений в форме, а не в реальных URL. Поэтому мне пришлось написать свою собственную функцию, которая выполняет один компонент (не подходит для целых строк запроса, которые имеют? S и & s)источник
URLEncoding может прекрасно кодировать HTTP-URL, как вы, к сожалению, обнаружили. Переданная вами строка « http://search.barnesandnoble.com/booksearch/first book.pdf» была правильно и полностью закодирована в виде URL-кода. Вы можете передать всю длинную строку gobbledigook, которую вы вернули, в качестве параметра в URL, и она может быть декодирована обратно в ту строку, в которой вы были переданы.
Похоже, вы хотите сделать что-то немного отличное от передачи всего URL-адреса в качестве параметра. Из того, что я понял, вы пытаетесь создать поисковый URL, который выглядит как " http://search.barnesandnoble.com/booksearch/whwhatTheUserPassesIn ". Единственное, что вам нужно кодировать, это бит "whatTheUserPassesIn", так что, возможно, все, что вам нужно сделать, это что-то вроде этого:
Это должно произвести что-то более правильное для вас.
источник
Если кто-то не хочет добавлять зависимость в свой проект, эти функции могут быть полезны.
Мы передаем часть пути нашего URL сюда. Вы, вероятно, не хотите передавать полный URL-адрес как параметр (для строк запроса требуются разные экранированные символы и т. Д.).
И тесты:
источник
Проблема все еще существует, если в вашем URL есть закодированный символ "/" (% 2F).
RFC 3986 - раздел 2.2 гласит: «Если данные для компонента URI будут конфликтовать с целью использования зарезервированного символа в качестве разделителя, то конфликтующие данные должны быть закодированы в процентах до формирования URI». (RFC 3986 - раздел 2.2)
Но есть проблема с Tomcat:
Поэтому, если у вас есть URL с символом% 2F, Tomcat возвращает: «400 Invalid URI: noSlash»
Вы можете переключить исправление в скрипте запуска Tomcat:
источник
Я прочитал предыдущие ответы, чтобы написать свой собственный метод, потому что я не мог заставить что-то правильно работать, используя решение предыдущих ответов, это выглядит хорошо для меня, но если вы можете найти URL, который не работает с этим, пожалуйста, дайте мне знать.
источник
Я согласен с Мэттом. На самом деле, я никогда не видел, чтобы это было хорошо объяснено в руководствах, но один вопрос заключается в том, как кодировать путь URL, а совсем другой вопрос - в том, как кодировать параметры, которые добавляются к URL (часть запроса, за "?" " символ). Они используют похожую кодировку, но не одинаковую.
Специально для кодирования символа пробела. Путь URL должен быть закодирован как% 20, тогда как часть запроса допускает% 20, а также знак «+». Лучшая идея - протестировать ее самостоятельно на нашем веб-сервере с помощью веб-браузера.
В обоих случаях я ВСЕГДА закодировал бы КОМПОНЕНТ ПО КОМПОНЕНТУ , а не всю строку. Действительно, URLEncoder допускает это для части запроса. Для части пути вы можете использовать класс URI, хотя в этом случае он запрашивает всю строку, а не один компонент.
В любом случае, я считаю, что лучший способ избежать этих проблем - использовать личный неконфликтный дизайн. Как? Например, я никогда не назову каталоги или параметры, используя символы, отличные от aZ, AZ, 0-9 и _. Таким образом, единственной необходимостью является кодирование значения каждого параметра, поскольку оно может быть получено из пользовательского ввода, а используемые символы неизвестны.
источник
Может быть, можете попробовать UriUtils в org.springframework.web.util
источник
Вы также можете использовать
GUAVA
и путь escape:UrlEscapers.urlFragmentEscaper().escape(relativePath)
источник
В дополнение к ответу Карлоса Хойбергера: если требуется значение, отличное от значения по умолчанию (80), следует использовать конструктор 7 параметров:
источник
Я взял содержимое выше и немного изменил его. Сначала мне нравится позитивная логика, и я подумал, что HashSet может дать лучшую производительность, чем некоторые другие опции, такие как поиск по строке. Хотя я не уверен, стоит ли штраф за автобокс, но если компилятор оптимизирует ASCII-символы, тогда стоимость бокса будет низкой.
источник
Используйте следующее стандартное решение Java (проходит около 100 тестовых случаев, предоставляемых Web Plattform Tests ):
0. Проверьте, если URL уже закодирован .
1. Разделить URL на структурные части. Используйте
java.net.URL
для этого.2. Правильно закодируйте каждую деталь конструкции!
3. Используйте
IDN.toASCII(putDomainNameHere)
для Punycode кодирования имени хоста!4. Используйте
java.net.URI.toASCIIString()
для кодирования в процентах, кодированный в NFC Unicode - (лучше было бы NFKC!).Узнайте больше здесь: https://stackoverflow.com/a/49796882/1485527
источник
Я создал новый проект, чтобы помочь создать URL-адреса HTTP. Библиотека автоматически URL-кодирует сегменты пути и параметры запроса.
Вы можете просмотреть исходный код и загрузить двоичный файл по адресу https://github.com/Widen/urlbuilder.
Пример URL в этом вопросе:
производит
http://search.barnesandnoble.com/booksearch/first%20book.pdf
источник
У меня такая же проблема. Решил это с помощью unsing:
Кодирует строку, но пропускает ":" и "/".
источник
я использую это
добавить эту зависимость
источник
Я разрабатываю библиотеку, которая служит этой цели: galimatias . Он анализирует URL так же, как веб-браузеры. То есть, если URL работает в браузере, он будет правильно проанализирован galimatias .
В этом случае:
Дадим вам:
http://search.barnesandnoble.com/booksearch/first%20book.pdf
. Конечно, это самый простой случай, но он будет работать с чем угодно, далеко за пределамиjava.net.URI
.Вы можете проверить это по адресу: https://github.com/smola/galimatias
источник
Вы можете использовать такую функцию. Заполните и измените его в соответствии с вашими потребностями:
Пример использования:
Результат: http://www.growup.com/folder/int%C3%A9rieur-%C3%A0_vendre?o=4
источник
String url = "" http://search.barnesandnoble.com/booksearch/ ;
Я думаю, это будет константа, и только имя файла будет изменено динамически, поэтому получите имя файла
Строка имени файла; // получить имя файла
String urlEnc = url + fileName.replace ("", "% 20");
источник
Как насчет:
public String UrlEncode (String in_) {
}
источник