Манипуляция строкой запроса в Java
Кто-нибудь имеет или знает класс java, который я могу использовать для манипулирования строками запроса?
По сути, мне нужен класс, который я могу просто предоставить строку запроса, а затем удалить, добавить и изменить строку запроса KVP.
Спасибо заранее.
ИЗМЕНИТЬ
В ответ на комментарий, сделанный по этому вопросу, строка запроса будет выглядеть примерно так:
N=123+456+112&Ntt=koala&D=abc
Итак, я хотел бы передать этому классу строку запроса и сказать что-то вроде:
String[] N = queryStringClass.getParameter("N");
а затем, возможно,
queryStringClass.setParameter("N", N);
и, возможно, queryStringClass.removeParameter("N");
Или что-то в этом роде.
Ответы
Ответ 1
Что-то вроде этого
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));
}
Ответ 2
Вы также можете использовать Google Guava Splitter.
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]@))$#^*&
Это должно охватывать все случаи.
Ответ 3
Если вы используете 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"));
}
}
Ответ 4
Другим способом является использование http-компонентов apache. Это немного взломанно, но, по крайней мере, вы используете все углы разбора:
List<NameValuePair> params =
URLEncodedUtils.parse("http://example.com/?" + queryString, Charset.forName("UTF-8"));
Это даст вам список объектов NameValuePair, с которыми должно быть легко работать.
Ответ 5
Вы можете создать метод утилиты и использовать регулярное выражение для его анализа. Достаточно шаблона типа "[&]".