Разбор строк запроса на Android

271

Java EE имеет ServletRequest.getParameterValues ​​() .

На не-EE платформах URL.getQuery () просто возвращает строку.

Какой нормальный способ правильно проанализировать строку запроса в URL, если не в Java EE?


< напыщенная речь >

В ответах популярно пытаться создать свой собственный парсер. Это очень интересный и захватывающий проект по микрокодированию, но я не могу сказать, что это хорошая идея :(

Приведенные ниже фрагменты кода, как правило, ошибочны или неработоспособны. Сломать их - интересное упражнение для читателя. И хакерам, атакующим сайты, которые их используют .

Разбор строк запроса - это хорошо определенная проблема, но чтение спецификации и понимание нюансов нетривиально. Гораздо лучше, чтобы какой-то кодировщик платформы сделал тяжелую работу и исправил это за вас!

< / rant >

Будет
источник
Не могли бы вы опубликовать пример URL, что вы получаете getQuery(), и что вы хотите получить в качестве результата?
Томас Оуэнс
1
Вы хотите сделать это с помощью сервлета или страницы JSP? Мне нужно немного разъяснений, прежде чем я отвечу.
ChadNC
1
Вам также нужно проанализировать параметры POST?
Тило
2
Даже если вы используете J2EE (или SE с выбранными пакетами EE, добавленными через OSGi, как я), этот вопрос может иметь смысл. В моем случае, тела запроса / POST-тела, закодированные в виде строк запроса, обрабатываются частью системы, которая намеренно не зависит от подобных вещей ServletRequest.
Ханно Фиц
61
Проголосовал за <rant />!
Новакер

Ответы:

65

С Android M все стало сложнее. Ответ android.net.URI .getQueryParameter () содержит ошибку, которая пробивает пробелы перед JellyBean. Apache URLEncodedUtils.parse () работала, но была устаревшая в L и удалена в М .

Так что лучший ответ сейчас - UrlQuerySanitizer . Это существует с уровня API 1 и до сих пор существует. Это также заставляет вас задуматься над такими сложными вопросами, как обработка специальных символов или повторяющиеся значения.

Самый простой код

UrlQuerySanitizer.ValueSanitizer sanitizer = UrlQuerySanitizer.getAllButNullLegal();
// remember to decide if you want the first or last parameter with the same name
// If you want the first call setPreferFirstRepeatedParameter(true);
sanitizer.parseUrl(url);
String value = sanitizer.getValue("paramName"); // get your value

Если вы довольны поведением разбора по умолчанию, вы можете сделать:

new UrlQuerySanitizer(url).getValue("paramName")

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

Ник Фортескью
источник
4
URLQuerySanitizer.getAllButNullLegal () возвращает UrlQuerySanitizer.ValueSanitizer, а не UrlQuerySanitizer.
Питер Чжао
31
По какой-то причине вышесказанное не сработало для меня, мне пришлось немного его изменить - что делает его еще проще:UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL); String value = sanitizer.getValue("parameter");
SeBsZ
3
Не работает. UrlQuerySanitizer в sdk-23 есть только один методsanitize()
ниндзя
Это расшифрует специальные символы и эмодзи _. Я должен был пойти с stackoverflow.com/a/35638979/1155282
Иршу
Существует ли библиотека, эквивалентная весенним фреймворкам?
Иамешуа
202

На Android:

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");
diyism
источник
20
обратите внимание, что здесь используется класс Uri, а не класс URI (Uri является частью android.net, а URI является частью java.net)
Мариус
5
Также обратите внимание, что до Ice Cream Sandwich не удается проанализировать символы + в значениях для пробела.
rpetrich
На самом деле @rpetrich говорят, что ошибка до появления Jelly Bean, включая Ice Cream Sandwich. ссылка
Big McLargeHuge
64

На 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

Будет
источник
9
Это доступно в клиентской библиотеке apache http, не только на Android. Кстати, ссылка на Apache была изменена. Последнее: hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…
Кристиан Враби
9
Раздражающе URLEncodedUtils.parse()возвращает a, Listчто вам нужно будет затем выполнить цикл, чтобы найти значение для конкретного ключа. Было бы гораздо приятнее, если бы он Mapответил как в ответе BalusC.
Асаф
1
@ Ханно Фиц, ты имеешь в виду, что доверяешь этим альтернативам? Я знаю, что они глючат. Я знаю, что выявление ошибок, которые я вижу, будет только побуждать людей принимать «исправленные» версии, а не самим искать ошибки, которые я пропустил.
Будет
1
@ Хорошо, я бы никогда не стал доверять фрагментам копирования и вставки, которые я получил с любого веб-сайта, и никто не должен этого делать . Но здесь эти фрагменты довольно хорошо рассмотрены и прокомментированы и, таким образом, areдействительно полезны. Просто увидеть некоторые предложения о том, что может быть не так с кодом, уже очень помогает в размышлениях для себя. И имейте в виду, я не хотел сказать, что «лучше самому кататься», а просто иметь хороший материал для обоснованного решения в моем собственном коде.
Ханно Фиц
8
Я представляю, что parse возвращает список, так что он поддерживает позиционное упорядочение и позволяет легко дублировать записи.
dhaag23
26

Вот ответ BalusC , но он компилирует и возвращает результаты:

public static Map<String, List<String>> getUrlParameters(String url)
        throws UnsupportedEncodingException {
    Map<String, List<String>> params = new HashMap<String, List<String>>();
    String[] urlParts = url.split("\\?");
    if (urlParts.length > 1) {
        String query = urlParts[1];
        for (String param : query.split("&")) {
            String pair[] = param.split("=");
            String key = URLDecoder.decode(pair[0], "UTF-8");
            String value = "";
            if (pair.length > 1) {
                value = URLDecoder.decode(pair[1], "UTF-8");
            }
            List<String> values = params.get(key);
            if (values == null) {
                values = new ArrayList<String>();
                params.put(key, values);
            }
            values.add(value);
        }
    }
    return params;
}
dfrankow
источник
1
Примечание JVM: я реализовал эквивалентную форму этого в Scala, используя Java Collections; вот суть github: gist.github.com/3504765
Джей Тейлор,
2
Я предлагаю перейти String pair[] = param.split("=");в String pair[] = param.split("=", 2);разделить пару ключ = значение только при первом появлении. Я полагаю, что в значении разрешено иметь незакодированные знаки равенства.
Денни
22

Если у вас есть библиотеки Jetty (сервер или клиент) в вашем classpath, вы можете использовать классы Jetty Util (см. Javadoc ), например:

import org.eclipse.jetty.util.*;
URL url = new URL("www.example.com/index.php?foo=bar&bla=blub");
MultiMap<String> params = new MultiMap<String>();
UrlEncoded.decodeTo(url.getQuery(), params, "UTF-8");

assert params.getString("foo").equals("bar");
assert params.getString("bla").equals("blub");
Moritz
источник
13

Если вы используете Spring 3.1 или выше (yikes, надеялся, что поддержка вернется дальше), вы можете использовать UriComponentsи UriComponentsBuilder:

UriComponents components = UriComponentsBuilder.fromUri(uri).build();
List<String> myParam = components.getQueryParams().get("myParam");

components.getQueryParams() возвращает MultiValueMap<String, String>

Вот еще немного документации .

Ник Спейсек
источник
Это то, что я ищу. Мой вопрос, как я могу получить URI? Я застрял с обслуживанием кода, который я не могу изменить, и мы не используем HttpServlet. Вместо этого просто используйте аннотации и Spring (@Get, @Produces (mediaType) и @Path ("/ dataAsJSON / datafield / {datafield}))) Просто нужно знать, как получить строку запроса, чтобы я мог ее проанализировать, как показано в этот пример.
Nelda.techspiress
5

Для сервлета или страницы JSP вы можете получить пары ключ / значение строки запроса, используя request.getParameter ("paramname")

String name = request.getParameter("name");

Есть и другие способы сделать это, но так я делаю это на всех создаваемых мной сервлетах и ​​страницах jsp.

ChadNC
источник
3
HttpServletRequest является частью J2EE, которой у него нет. Также использование getParamter () на самом деле не является разбором.
Мистер Блестящий и Новый 宇 宇
3
Пожалуйста, найдите время, чтобы прочитать комментарий, в котором я попросил разъяснить его вопрос. Этот ответ является ответом на его комментарий к этому комментарию, в котором он заявил: «Я пытаюсь сделать это на Android, но все ответы на всех платформах были бы полезными ответами, которые могли бы дать указатели (также другим, кто может столкнуться с этим вопрос) так что не сдерживайтесь! Я ответил на его вопрос, основываясь на этом комментарии. Если вам нечего добавить, ничего не добавляйте
ChadNC
1
Не расстраивайся. «Это не отвечает на вопрос» полезно добавить, ИМО.
Мистер Блестящий и Новый 宇 宇
1
Не имеет значения, Android это или нет, вопрос в том, как разобрать строку, содержащую URL, и получить из нее параметры URL. То, что вы портируете здесь, является частью Servlet API, где контейнер Servlet анализирует входящие параметры из HTTP-запроса для вас. Это не имеет значения, потому что вопрос касается разбора String, содержащего URL, а не HTTP-запрос и не внутри контейнера сервлета.
mvmn
5

В Android я попытался использовать ответ @diyism, но я столкнулся с проблемой пробела, возникшей, например, в @rpetrich: я заполняю форму, где username = "us+us"и password = "pw pw"заставляю строку URL выглядеть следующим образом:

http://somewhere?username=us%2Bus&password=pw+pw

Тем не менее, код @diyism возвращает "us+us"и "pw+pw", т. Е. Не обнаруживает пробел. Если URL был переписан с %20пробелом, он идентифицируется:

http://somewhere?username=us%2Bus&password=pw%20pw

Это приводит к следующему исправлению:

Uri uri = Uri.parse(url_string.replace("+", "%20"));
uri.getQueryParameter("para1");
Стивен Куан
источник
replace(" ", "%20")это неправильно Но сделал трюк для меня: D
Mārtiņš Briedis
Правильный синтаксис должен быть "некоторая строка" .replaceAll ("[+]", "% 20");
RRTW
4

Разбор строки запроса немного сложнее, чем кажется, в зависимости от того, насколько вы прощаете.

Во-первых, строка запроса - это байты 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. Если вы хотите попытаться изящно справиться с этим, вам нужно будет добавить больше логики в ваш парсер.

Мистер Блестящий и Новый 安 宇
источник
Это не объясняет, как анализировать или получать значения параметров
строки
Хорошо, но немного громоздко. Для этого у нас уже есть URLDecoder.
BalusC
2
@ChadNC: третье предложение говорит вам, как анализировать: читать по одному байту за раз и преобразовывать в символы. Четвертое предложение предупреждает вас об особых символах. И т.д. Может быть, вы не читали ответ?
Мистер Блестящий и Новый 宇 宇
@BalusC: URLDecoder работает, но у него есть несколько режимов сбоя, если вы пытаетесь быть более снисходительными в отношении того, какой тип URL вы принимаете.
Мистер Блестящий и Новый 宇 宇
1
Согласиться с @ Mr.ShinyAndNew парам запроса разбора не просто. Я поддерживаю FIQL, и это стало НАСТОЯЩЕЙ болью в заднице. Например: yoursite.com/blah??p1==v1&&p2==v2,p2==v3;p2==v4
rafa.ferreira
4

На Android все просто, как показано ниже:

UrlQuerySanitizer sanitzer = new UrlQuerySanitizer(url);
String value = sanitzer.getValue("your_get_parameter");

Также, если вы не хотите регистрировать каждый ожидаемый ключ запроса, используйте:

sanitzer.setAllowUnregisteredParamaters(true)

Перед звонком:

sanitzer.parseUrl(yourUrl)
Кевин Крейн
источник
4

У меня есть методы для достижения этой цели:

1) :

public static String getQueryString(String url, String tag) {
    String[] params = url.split("&");
    Map<String, String> map = new HashMap<String, String>();
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }

    Set<String> keys = map.keySet();
    for (String key : keys) {
        if(key.equals(tag)){
         return map.get(key);
        }
        System.out.println("Name=" + key);
        System.out.println("Value=" + map.get(key));
    }
    return "";
}

2) и самый простой способ сделать это с помощью класса Uri :

public static String getQueryString(String url, String tag) {
    try {
        Uri uri=Uri.parse(url);
        return uri.getQueryParameter(tag);
    }catch(Exception e){
        Log.e(TAG,"getQueryString() " + e.getMessage());
    }
    return "";
}

и это пример того, как использовать любой из двух методов:

String url = "http://www.jorgesys.com/advertisements/publicidadmobile.htm?position=x46&site=reform&awidth=800&aheight=120";      
String tagValue = getQueryString(url,"awidth");

значение tagValue равно 800

Jorgesys
источник
3

В Android вы можете использовать статический метод Uri.parse класса android.net.Uri для выполнения тяжелой работы. Если вы что-то делаете с URI и Intents, вы все равно захотите это использовать.

Патрик О'Лири
источник
3

Просто для справки, это то, что я закончил (на основе URLEncodedUtils и возвращая карту).

Особенности:

  • он принимает часть строки запроса URL (вы можете использовать request.getQueryString())
  • пустая строка запроса создаст пустую Map
  • параметр без значения (? test) будет сопоставлен с пустым List<String>

Код:

public static Map<String, List<String>> getParameterMapOfLists(String queryString) {
    Map<String, List<String>> mapOfLists = new HashMap<String, List<String>>();
    if (queryString == null || queryString.length() == 0) {
        return mapOfLists;
    }
    List<NameValuePair> list = URLEncodedUtils.parse(URI.create("http://localhost/?" + queryString), "UTF-8");
    for (NameValuePair pair : list) {
        List<String> values = mapOfLists.get(pair.getName());
        if (values == null) {
            values = new ArrayList<String>();
            mapOfLists.put(pair.getName(), values);
        }
        if (pair.getValue() != null) {
            values.add(pair.getValue());
        }
    }

    return mapOfLists;
}

Помощник по совместимости (значения хранятся в массиве String так же, как в ServletRequest.getParameterMap () ):

public static Map<String, String[]> getParameterMap(String queryString) {
    Map<String, List<String>> mapOfLists = getParameterMapOfLists(queryString);

    Map<String, String[]> mapOfArrays = new HashMap<String, String[]>();
    for (String key : mapOfLists.keySet()) {
        mapOfArrays.put(key, mapOfLists.get(key).toArray(new String[] {}));
    }

    return mapOfArrays;
}
Дэн
источник
3

Это работает для меня .. Я не уверен, почему все были после Map, List> Все, что мне было нужно, это просто имя значения Map.

Для простоты я использовал сборку в URI.getQuery ();

public static Map<String, String> getUrlParameters(URI uri)
    throws UnsupportedEncodingException {
    Map<String, String> params = new HashMap<String, String>();
    for (String param : uri.getQuery().split("&")) {
        String pair[] = param.split("=");
        String key = URLDecoder.decode(pair[0], "UTF-8");
        String value = "";
        if (pair.length > 1) {
            value = URLDecoder.decode(pair[1], "UTF-8");
        }
        params.put(new String(key), new String(value));
    }
    return params;
}
Дейв
источник
1
как насчет форм с множественным выбором? Совершенно нормально, когда ключи повторяются в допустимых строках запроса (и в формах POST). Существуют и другие дефекты и неучтенные случаи; многие из них были упомянуты в комментариях к другим подходам. Я воздержусь от формы, указывающей на них из страха, что вы исправите это вместо использования качественной библиотеки, как указано в моей статье в вопросе;)
Будет
2

Multimap от Guava лучше подходит для этого. Вот короткая чистая версия:

Multimap<String, String> getUrlParameters(String url) {
        try {
            Multimap<String, String> ret = ArrayListMultimap.create();
            for (NameValuePair param : URLEncodedUtils.parse(new URI(url), "UTF-8")) {
                ret.put(param.getName(), param.getValue());
            }
            return ret;
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
pathikrit
источник
1

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

Срипати Кришнан
источник
1

Оригинально ответили здесь

На Android есть класс Uri в пакете android.net . Обратите внимание, что Uri является частью android.net, а URI - частью java.net.

У класса Uri есть много функций для извлечения пар ключ-значение запроса. введите описание изображения здесь

Следующая функция возвращает пары ключ-значение в виде HashMap.

В Java:

Map<String, String> getQueryKeyValueMap(Uri uri){
    HashMap<String, String> keyValueMap = new HashMap();
    String key;
    String value;

    Set<String> keyNamesList = uri.getQueryParameterNames();
    Iterator iterator = keyNamesList.iterator();

    while (iterator.hasNext()){
        key = (String) iterator.next();
        value = uri.getQueryParameter(key);
        keyValueMap.put(key, value);
    }
    return keyValueMap;
}

В Котлине:

fun getQueryKeyValueMap(uri: Uri): HashMap<String, String> {
        val keyValueMap = HashMap<String, String>()
        var key: String
        var value: String

        val keyNamesList = uri.queryParameterNames
        val iterator = keyNamesList.iterator()

        while (iterator.hasNext()) {
            key = iterator.next() as String
            value = uri.getQueryParameter(key) as String
            keyValueMap.put(key, value)
        }
        return keyValueMap
    }
Рамакришна Джоши
источник
0

Я не думаю, что есть один в JRE. Вы можете найти аналогичные функции в других пакетах, таких как Apache HttpClient. Если вы не используете другие пакеты, вам просто нужно написать свой собственный. Это не так сложно. Вот что я использую,

public class QueryString {

 private Map<String, List<String>> parameters;

 public QueryString(String qs) {
  parameters = new TreeMap<String, List<String>>();

  // Parse query string
     String pairs[] = qs.split("&");
     for (String pair : pairs) {
            String name;
            String value;
            int pos = pair.indexOf('=');
            // for "n=", the value is "", for "n", the value is null
         if (pos == -1) {
          name = pair;
          value = null;
         } else {
       try {
        name = URLDecoder.decode(pair.substring(0, pos), "UTF-8");
              value = URLDecoder.decode(pair.substring(pos+1, pair.length()), "UTF-8");            
       } catch (UnsupportedEncodingException e) {
        // Not really possible, throw unchecked
           throw new IllegalStateException("No UTF-8");
       }
         }
         List<String> list = parameters.get(name);
         if (list == null) {
          list = new ArrayList<String>();
          parameters.put(name, list);
         }
         list.add(value);
     }
 }

 public String getParameter(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  if (values.size() == 0)
   return "";

  return values.get(0);
 }

 public String[] getParameterValues(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  return (String[])values.toArray(new String[values.size()]);
 }

 public Enumeration<String> getParameterNames() {  
  return Collections.enumeration(parameters.keySet()); 
 }

 public Map<String, String[]> getParameterMap() {
  Map<String, String[]> map = new TreeMap<String, String[]>();
  for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
   List<String> list = entry.getValue();
   String[] values;
   if (list == null)
    values = null;
   else
    values = (String[]) list.toArray(new String[list.size()]);
   map.put(entry.getKey(), values);
  }
  return map;
 } 
}
ZZ Coder
источник
Как обстоят дела с классами Apache?
Будет
1
Вы можете использовать метод parse (): hc.apache.org/httpcomponents-client/httpclient/apidocs/org/…
ZZ Coder
3
Пожалуйста, поместите ссылку на Apache Commons в свой ответ, чтобы я мог проголосовать.
itadok
0

Основываясь на ответе BalusC, я написал пример Java-кода:

    if (queryString != null)
    {
        final String[] arrParameters = queryString.split("&");
        for (final String tempParameterString : arrParameters)
        {
            final String[] arrTempParameter = tempParameterString.split("=");
            if (arrTempParameter.length >= 2)
            {
                final String parameterKey = arrTempParameter[0];
                final String parameterValue = arrTempParameter[1];
                //do something with the parameters
            }
        }
    }
Andreas
источник
0
public static Map <String, String> parseQueryString (final URL url)
        throws UnsupportedEncodingException
{
    final Map <String, String> qps = new TreeMap <String, String> ();
    final StringTokenizer pairs = new StringTokenizer (url.getQuery (), "&");
    while (pairs.hasMoreTokens ())
    {
        final String pair = pairs.nextToken ();
        final StringTokenizer parts = new StringTokenizer (pair, "=");
        final String name = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        final String value = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        qps.put (name, value);
    }
    return qps;
}
wafna
источник
0

используя гуаву:

Multimap<String,String> parseQueryString(String queryString, String encoding) {
    LinkedListMultimap<String, String> result = LinkedListMultimap.create();

    for(String entry : Splitter.on("&").omitEmptyStrings().split(queryString)) {
        String pair [] = entry.split("=", 2);
        try {
            result.put(URLDecoder.decode(pair[0], encoding), pair.length == 2 ? URLDecoder.decode(pair[1], encoding) : null);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    return result;
}
Тайсон
источник
0

Отвечаю здесь, потому что это популярная тема. Это чистое решение в Котлине, которое использует рекомендуемые UrlQuerySanitizerAPI. Смотрите официальную документацию . Я добавил конструктор строк для объединения и отображения параметров.

    var myURL: String? = null
    // if the url is sent from a different activity where you set it to a value
    if (intent.hasExtra("my_value")) {
        myURL = intent.extras.getString("my_value")
    } else {
        myURL = intent.dataString
    }

    val sanitizer = UrlQuerySanitizer(myURL)
    // We don't want to manually define every expected query *key*, so we set this to true
    sanitizer.allowUnregisteredParamaters = true
    val parameterNamesToValues: List<UrlQuerySanitizer.ParameterValuePair> = sanitizer.parameterList
    val parameterIterator: Iterator<UrlQuerySanitizer.ParameterValuePair> = parameterNamesToValues.iterator()

    // Helper simply so we can display all values on screen
    val stringBuilder = StringBuilder()

    while (parameterIterator.hasNext()) {
        val parameterValuePair: UrlQuerySanitizer.ParameterValuePair = parameterIterator.next()
        val parameterName: String = parameterValuePair.mParameter
        val parameterValue: String = parameterValuePair.mValue

        // Append string to display all key value pairs
        stringBuilder.append("Key: $parameterName\nValue: $parameterValue\n\n")
    }

    // Set a textView's text to display the string
    val paramListString = stringBuilder.toString()
    val textView: TextView = findViewById(R.id.activity_title) as TextView
    textView.text = "Paramlist is \n\n$paramListString"

    // to check if the url has specific keys
    if (sanitizer.hasParameter("type")) {
        val type = sanitizer.getValue("type")
        println("sanitizer has type param $type")
    }
jungledev
источник
-2

этот метод принимает URI и возвращает карту с номиналом и номиналом

  public static Map<String, String> getQueryMap(String uri) {

    String queryParms[] = uri.split("\\?");

    Map<String, String> map = new HashMap<>();// 

    if (queryParms == null || queryParms.length == 0) return map;

    String[] params = queryParms[1].split("&");
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }
    return map;
}
ФАХАД ХАММАД АЛОТАИБИ
источник
1
Согласно моей напыщенной речи выше, это может быть тривиально. Не беспокойтесь об исправлении, просто используйте профессиональную служебную библиотеку.
Будет
-3

Вы говорите «Java», но «не Java EE». Вы имеете в виду, что используете JSP и / или сервлеты, но не полный стек Java EE? Если это так, то вы все равно должны иметь request.getParameter () для вас.

Если вы имеете в виду вы пишете Java, но вы не пишете ни сервлет JSP-страницы, или что вы используете только Java в качестве точки отсчета, но вы на какой-либо другой платформе, которая не имеет встроенный параметр разборе ... Wow Это звучит как маловероятный вопрос, но если так, то принцип будет:

xparm=0
word=""
loop
  get next char
  if no char
    exit loop
  if char=='='
    param_name[xparm]=word
    word=""
  else if char=='&'
    param_value[xparm]=word
    word=""
    xparm=xparm+1
  else if char=='%'
    read next two chars
    word=word+interpret the chars as hex digits to make a byte
  else
    word=word+char

(Я мог бы написать код Java, но это было бы бессмысленно, потому что если у вас есть Java, вы можете просто использовать request.getParameters.)

сойка
источник
обратите внимание на кодировку символов при url-декодировании шестнадцатеричных цифр.
Мистер Блестящий и Новый 宇 宇
Это Android, следовательно, Java, но не J2EE.
Анджей Дойл
Я забыл упомянуть: вы также должны проверить «+», который должен быть переведен в пробел. Встроенные пробелы недопустимы в строке запроса.
Джей