Парсинг строк запроса на Android

Это просто, это коротко и если Вы захотите создать реальную реализацию в теле свойства где-нибудь по линии, это не повредит внешний интерфейс Вашего типа.

Настолько простой.

268
задан rds 8 July 2014 в 05:05
поделиться

8 ответов

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

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

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.

-3
ответ дан 23 November 2019 в 02:22
поделиться

Я не Не думаю, что в 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;
 } 
}
0
ответ дан 23 November 2019 в 02:22
поделиться

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

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

4
ответ дан 23 November 2019 в 02:22
поделиться

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

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

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

5
ответ дан 23 November 2019 в 02:22
поделиться

Основываясь на ответе 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
            }
        }
    }
0
ответ дан 23 November 2019 в 02:22
поделиться

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

3
ответ дан 23 November 2019 в 02:22
поделиться

Вот ответ 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;
}
26
ответ дан 23 November 2019 в 02:22
поделиться
Другие вопросы по тегам:

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