Java EE имеет ServletRequest.getParameterValues () .
На не-EE платформах URL.getQuery () просто возвращает строку.
Какой нормальный способ правильно проанализировать строку запроса в URL, если не в Java EE?
< напыщенная речь >
В ответах популярно пытаться создать свой собственный парсер. Это очень интересный и захватывающий проект по микрокодированию, но я не могу сказать, что это хорошая идея :(
Приведенные ниже фрагменты кода, как правило, ошибочны или неработоспособны. Сломать их - интересное упражнение для читателя. И хакерам, атакующим сайты, которые их используют .
Разбор строк запроса - это хорошо определенная проблема, но чтение спецификации и понимание нюансов нетривиально. Гораздо лучше, чтобы какой-то кодировщик платформы сделал тяжелую работу и исправил это за вас!
< / rant >
getQuery()
, и что вы хотите получить в качестве результата?ServletRequest
.Ответы:
С Android M все стало сложнее. Ответ android.net.URI .getQueryParameter () содержит ошибку, которая пробивает пробелы перед JellyBean. Apache URLEncodedUtils.parse () работала, но была устаревшая в L и удалена в М .
Так что лучший ответ сейчас - UrlQuerySanitizer . Это существует с уровня API 1 и до сих пор существует. Это также заставляет вас задуматься над такими сложными вопросами, как обработка специальных символов или повторяющиеся значения.
Самый простой код
Если вы довольны поведением разбора по умолчанию, вы можете сделать:
но вы должны убедиться, что вы понимаете, что такое синтаксический анализ по умолчанию, поскольку он может не соответствовать вашему желанию.
источник
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL);
String value = sanitizer.getValue("parameter");
UrlQuerySanitizer
в sdk-23 есть только один методsanitize()
_
. Я должен был пойти с stackoverflow.com/a/35638979/1155282На Android:
источник
На Android библиотеки Apache предоставляют анализатор запросов:
http://developer.android.com/reference/org/apache/http/client/utils/URLEncodedUtils.html и http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/ HTTP / клиент / Utils / URLEncodedUtils.html
источник
URLEncodedUtils.parse()
возвращает a,List
что вам нужно будет затем выполнить цикл, чтобы найти значение для конкретного ключа. Было бы гораздо приятнее, если бы онMap
ответил как в ответе BalusC.are
действительно полезны. Просто увидеть некоторые предложения о том, что может быть не так с кодом, уже очень помогает в размышлениях для себя. И имейте в виду, я не хотел сказать, что «лучше самому кататься», а просто иметь хороший материал для обоснованного решения в моем собственном коде.Вот ответ BalusC , но он компилирует и возвращает результаты:
источник
String pair[] = param.split("=");
вString pair[] = param.split("=", 2);
разделить пару ключ = значение только при первом появлении. Я полагаю, что в значении разрешено иметь незакодированные знаки равенства.Если у вас есть библиотеки Jetty (сервер или клиент) в вашем classpath, вы можете использовать классы Jetty Util (см. Javadoc ), например:
источник
Если вы используете Spring 3.1 или выше (yikes, надеялся, что поддержка вернется дальше), вы можете использовать
UriComponents
иUriComponentsBuilder
:components.getQueryParams()
возвращаетMultiValueMap<String, String>
Вот еще немного документации .
источник
Для сервлета или страницы JSP вы можете получить пары ключ / значение строки запроса, используя request.getParameter ("paramname")
Есть и другие способы сделать это, но так я делаю это на всех создаваемых мной сервлетах и страницах jsp.
источник
В Android я попытался использовать ответ @diyism, но я столкнулся с проблемой пробела, возникшей, например, в @rpetrich: я заполняю форму, где
username = "us+us"
иpassword = "pw pw"
заставляю строку URL выглядеть следующим образом:Тем не менее, код @diyism возвращает
"us+us"
и"pw+pw"
, т. Е. Не обнаруживает пробел. Если URL был переписан с%20
пробелом, он идентифицируется:Это приводит к следующему исправлению:
источник
replace(" ", "%20")
это неправильно Но сделал трюк для меня: DРазбор строки запроса немного сложнее, чем кажется, в зависимости от того, насколько вы прощаете.
Во-первых, строка запроса - это байты ascii. Вы читаете эти байты по одному и конвертируете их в символы. Если персонаж есть? или & затем он сигнализирует о начале имени параметра. Если символ =, то это означает начало значения параметра. Если символ%, то он сигнализирует о начале закодированного байта. Вот где это становится сложным.
Когда вы читаете в% char, вы должны прочитать следующие два байта и интерпретировать их как шестнадцатеричные цифры. Это означает, что следующие два байта будут 0-9, af или AF. Склейте эти две шестнадцатеричные цифры вместе, чтобы получить значение в байтах. Но помните, байты не являются символами . Вы должны знать, какая кодировка использовалась для кодирования символов. Символ é не кодирует то же самое в UTF-8, как в ISO-8859-1. Вообще невозможно знать, какая кодировка использовалась для данного набора символов. Я всегда использую UTF-8, потому что мой веб-сайт настроен так, чтобы всегда обслуживать все, используя UTF-8, но на практике вы не можете быть уверены. Некоторые пользовательские агенты сообщат вам кодировку символов в запросе; Вы можете попытаться прочитать это, если у вас есть полный HTTP-запрос. Если у вас просто есть URL-адрес в изоляции, удачи.
В любом случае, если вы используете кодировку UTF-8 или какую-либо другую многобайтовую кодировку символов, теперь, когда вы декодировали один закодированный байт, вам нужно отложить его до тех пор, пока вы не захватите следующий байт. Вам нужны все закодированные байты, потому что вы не можете правильно декодировать url по одному байту за раз. Отложите все вместе взятые байты, а затем декодируйте их все сразу, чтобы восстановить своего персонажа.
Кроме того, вам будет веселее, если вы хотите быть снисходительным и учитывать учетные записи пользователей, которые изменяют URL-адреса. Например, некоторые клиенты веб-почты дважды кодируют вещи. Или удвойте символы? & = (Например:)
http://yoursite.com/blah??p1==v1&&p2==v2
. Если вы хотите попытаться изящно справиться с этим, вам нужно будет добавить больше логики в ваш парсер.источник
На Android все просто, как показано ниже:
Также, если вы не хотите регистрировать каждый ожидаемый ключ запроса, используйте:
Перед звонком:
источник
У меня есть методы для достижения этой цели:
1) :
2) и самый простой способ сделать это с помощью класса Uri :
и это пример того, как использовать любой из двух методов:
значение tagValue равно
800
источник
В Android вы можете использовать статический метод Uri.parse класса android.net.Uri для выполнения тяжелой работы. Если вы что-то делаете с URI и Intents, вы все равно захотите это использовать.
источник
Просто для справки, это то, что я закончил (на основе URLEncodedUtils и возвращая карту).
Особенности:
request.getQueryString()
)Map
List<String>
Код:
Помощник по совместимости (значения хранятся в массиве String так же, как в ServletRequest.getParameterMap () ):
источник
Это работает для меня .. Я не уверен, почему все были после Map, List> Все, что мне было нужно, это просто имя значения Map.
Для простоты я использовал сборку в URI.getQuery ();
источник
Multimap от Guava лучше подходит для этого. Вот короткая чистая версия:
источник
Apache AXIS2 имеет автономную реализацию QueryStringParser.java. Если вы не используете Axis2, просто загрузите исходный код и контрольный пример отсюда -
http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/transport/http/util/QueryStringParser.java
http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/test/org/apache/axis2/transport/http/util/QueryStringParserTest.java
источник
Оригинально ответили здесь
На Android есть класс Uri в пакете android.net . Обратите внимание, что Uri является частью android.net, а URI - частью java.net.
У класса Uri есть много функций для извлечения пар ключ-значение запроса.
Следующая функция возвращает пары ключ-значение в виде HashMap.
В Java:
В Котлине:
источник
Я не думаю, что есть один в JRE. Вы можете найти аналогичные функции в других пакетах, таких как Apache HttpClient. Если вы не используете другие пакеты, вам просто нужно написать свой собственный. Это не так сложно. Вот что я использую,
источник
Основываясь на ответе BalusC, я написал пример Java-кода:
источник
источник
Используйте Apache HttpComponents и соедините его с некоторым коллекционным кодом для доступа к параметрам по значению: http://www.joelgerard.com/2012/09/14/parsing-query-strings-in-java-and-accessing-values-by -key /
источник
используя гуаву:
источник
Отвечаю здесь, потому что это популярная тема. Это чистое решение в Котлине, которое использует рекомендуемые
UrlQuerySanitizer
API. Смотрите официальную документацию . Я добавил конструктор строк для объединения и отображения параметров.источник
этот метод принимает URI и возвращает карту с номиналом и номиналом
источник
Вы говорите «Java», но «не Java EE». Вы имеете в виду, что используете JSP и / или сервлеты, но не полный стек Java EE? Если это так, то вы все равно должны иметь request.getParameter () для вас.
Если вы имеете в виду вы пишете Java, но вы не пишете ни сервлет JSP-страницы, или что вы используете только Java в качестве точки отсчета, но вы на какой-либо другой платформе, которая не имеет встроенный параметр разборе ... Wow Это звучит как маловероятный вопрос, но если так, то принцип будет:
(Я мог бы написать код Java, но это было бы бессмысленно, потому что если у вас есть Java, вы можете просто использовать request.getParameters.)
источник