2010-11-08 2 views
17

Кто-нибудь имеет или знает класс java, который я могу использовать для манипулирования строками запроса?Манипуляция строкой запроса в Java

По сути, мне нужен класс, который я могу просто предоставить строку запроса, а затем удалить, добавить и изменить строку запроса KVP.

Заранее спасибо.

EDIT

В ответ на замечание на этот вопрос, строка запроса будет выглядеть следующим образом;

N=123+456+112&Ntt=koala&D=abc 

Поэтому я хотел бы передать этому классу строку запроса и сказать что-то вроде;

String[] N = queryStringClass.getParameter("N"); 

, а затем, возможно,

queryStringClass.setParameter("N", N); 

и, возможно, queryStringClass.removeParameter("N");

Или что-то в этом роде.

+3

Вы не предоставили достаточно контекста, чтобы кто-либо мог дать ответ. Какие строки запросов? Пожалуйста, перефразируйте вопрос. –

+1

http://stackoverflow.com/questions/1667278/parsing-query-strings-in-java –

ответ

16

Нечто подобное

public static Map<String, String> getQueryMap(String query) 
{ 
    String[] params = query.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); 
    } 
    return map; 
} 

Повторить карту просто:

String query = url.getQuery(); 
Map<String, String> map = getQueryMap(query); 
Set<String> keys = map.keySet(); 
for (String key : keys) 
{ 
    System.out.println("Name=" + key); 
    System.out.println("Value=" + map.get(key)); 
} 
+0

Хотелось бы, чтобы у вас было что-то готовое, но это здорово. :) спасибо – griegs

+1

Было бы более эффективно хранить 'param.split (" = ")' в переменной и повторно использовать результат, а не разделять один и тот же параметр дважды. – LeastOne

+7

Это решение не учитывает экранированные символы. – raulk

0

Вы можете создать метод Util и использовать регулярное выражение для синтаксического анализа. Достаточно шаблона типа "[; &]".

5

Если вы используете J2EE, вы можете использовать ServletRequest.getParameterValues().

В противном случае, я не думаю, что у Java есть общие классы для обработки строки запроса. Написание собственного не должно быть слишком сложным, хотя есть определенные сложные случаи, например, понимание того, что технически один и тот же ключ может появляться более одного раза в строке запроса.

Одна реализация может выглядеть следующим образом:

import java.util.*; 
import java.net.URLEncoder; 
import java.net.URLDecoder; 

public class QueryParams { 
private static class KVP { 
    final String key; 
    final String value; 
    KVP (String key, String value) { 
     this.key = key; 
     this.value = value; 
    } 
} 

List<KVP> query = new ArrayList<KVP>(); 

public QueryParams(String queryString) { 
    parse(queryString); 
} 

public QueryParams() { 
} 

public void addParam(String key, String value) { 
    if (key == null || value == null) 
     throw new NullPointerException("null parameter key or value"); 
    query.add(new KVP(key, value)); 
} 

private void parse(String queryString) { 
    for (String pair : queryString.split("&")) { 
     int eq = pair.indexOf("="); 
     if (eq < 0) { 
      // key with no value 
      addParam(URLDecoder.decode(pair), ""); 
     } else { 
      // key=value 
      String key = URLDecoder.decode(pair.substring(0, eq)); 
      String value = URLDecoder.decode(pair.substring(eq + 1)); 
      query.add(new KVP(key, value)); 
     } 
    } 
} 

public String toQueryString() { 
    StringBuilder sb = new StringBuilder(); 
    for (KVP kvp : query) { 
     if (sb.length() > 0) { 
      sb.append('&'); 
     } 
     sb.append(URLEncoder.encode(kvp.key)); 
     if (!kvp.value.equals("")) { 
      sb.append('='); 
      sb.append(URLEncoder.encode(kvp.value)); 
     } 
    } 
    return sb.toString(); 
} 

public String getParameter(String key) { 
    for (KVP kvp : query) { 
     if (kvp.key.equals(key)) { 
      return kvp.value; 
     } 
    } 
    return null; 
} 

public List<String> getParameterValues(String key) { 
    List<String> list = new LinkedList<String>(); 
    for (KVP kvp : query) { 
     if (kvp.key.equals(key)) { 
      list.add(kvp.value); 
     } 
    } 
    return list; 
} 

public static void main(String[] args) { 
    QueryParams qp = new QueryParams("k1=v1&k2&k3=v3&k1=v4&k1&k5=hello+%22world"); 
    System.out.println("getParameter:"); 
    String[] keys = new String[] { "k1", "k2", "k3", "k5" }; 
    for (String key : keys) { 
     System.out.println(key + ": " + qp.getParameter(key)); 
    } 
    System.out.println("getParameters(k1): " + qp.getParameterValues("k1")); 
} 
} 
+0

+1, спасибо за это. Уже реализовано что-то вроде этого. – griegs

+0

Как работать с "&" в середине строк запроса? – Achimnol

+0

@Achimnol: В чем проблема? & - это XML-кодирование, оно должно проходить через параметр URL как% 26amp ;. Если вы хотите продолжить XML-декодирование строки, вы можете использовать для этого другие методы. – Avi

12

Вы также можете использовать Splitter Google гуавы в.

String queryString = "variableA=89&variableB=100"; 
Map<String,String> queryParameters = Splitter 
    .on("&") 
    .withKeyValueSeparator("=") 
    .split(queryString); 
System.out.println(queryParameters.get("variableA")); 

печатает

89 

Это я думаю, что это очень читаемая альтернатива разбора его самостоятельно.

Редактировать: Как отметил @raulk, это решение не учитывает экранированные символы. Однако это может и не быть проблемой, поскольку перед вами URL-декодирование гарантируется, что строка запроса не имеет никаких экранированных символов, которые конфликтуют с '=' и '&'. Вы можете использовать это в своих интересах следующим образом.

Говорят, что вы должны декодировать следующую строку запроса:

a=%26%23%25!)%23(%40!&b=%23%24(%40)%24%40%40))%24%23%5E*%26 

который URL-закодирован, то вам гарантируется, что «&» и «=» специально используется для разделения пар и ключ от значения, соответственно, в какой момент вы можете использовать разветвитель Guava получить:

a = %26%23%25!)%23(%40! 
b = %23%24(%40)%24%40%40))%24%23%5E*%26 

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

a = &#%!)#(@! 
b = #$(@)[email protected]@))$#^*& 

Это должно охватывать все случаи.

+6

Это решение не учитывает экранированные символы. – raulk

+0

Вы были бы правы. –

+0

@raulk Я добавил несколько шагов, которые можно использовать даже с экранированными символами. Благодаря! –

1

Другим способом является использование http-компонентов apache. Это немного Hacky, но по крайней мере использовать все разбор дела углового:

List<NameValuePair> params = 
    URLEncodedUtils.parse("http://example.com/?" + queryString, Charset.forName("UTF-8")); 

Это даст вам список объектов, которые должны парам имени легко работать.

+0

Мне показалось странным, что это еще не было предложено ... это хакерство, но хорошее использование существующей библиотеки ... – AxelH

Смежные вопросы