Java 中的查询字符串操作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4128436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Query String Manipulation in Java
提问by griegs
Does anyone have, or know of, a java class that I can use to manipulate query strings?
有没有人拥有或知道我可以用来操作查询字符串的 Java 类?
Essentially I'd like a class that I can simply give a query string to and then delete, add and modify query string KVP's.
本质上,我想要一个类,我可以简单地给它一个查询字符串,然后删除、添加和修改查询字符串 KVP。
Thanks in advance.
提前致谢。
EDIT
编辑
In response to a comment made to this question, the query string will look something like this;
作为对这个问题的评论的回应,查询字符串看起来像这样;
N=123+456+112&Ntt=koala&D=abc
So I'd like to pass this class the query string and say something like;
所以我想将查询字符串传递给这个类,然后说:
String[] N = queryStringClass.getParameter("N");
and then maybe
然后也许
queryStringClass.setParameter("N", N);
and maybe queryStringClass.removeParameter("N");
有可能 queryStringClass.removeParameter("N");
Or something to that effect.
或者类似的东西。
采纳答案by Maurizio Cucchiara
SOmething like this
像这样的东西
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;
}
To iterate the map simply:
简单地迭代地图:
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));
}
回答by CoolBeans
You can create a util method and use regular expression to parse it. A pattern like "[;&]" should suffice.
您可以创建一个 util 方法并使用正则表达式来解析它。像“[;&]”这样的模式就足够了。
回答by Avi
If you are using J2EE, you can use ServletRequest.getParameterValues().
如果您使用的是 J2EE,则可以使用ServletRequest.getParameterValues()。
Otherwise, I don't think Java has any common classes for query string handling. Writing your own shouldn't be too hard, though there are certain tricky edge cases, such as realizing that technically the same key may appear more than once in the query string.
否则,我认为 Java 没有任何用于查询字符串处理的通用类。编写自己的代码应该不会太难,尽管存在某些棘手的边缘情况,例如意识到技术上相同的键可能会在查询字符串中出现多次。
One implementation might look like:
一种实现可能如下所示:
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"));
}
}
回答by laughing_man
You can also use Google Guava's Splitter.
您还可以使用 Google Guava 的 Splitter。
String queryString = "variableA=89&variableB=100";
Map<String,String> queryParameters = Splitter
.on("&")
.withKeyValueSeparator("=")
.split(queryString);
System.out.println(queryParameters.get("variableA"));
prints out
打印出来
89
This I think is a very readable alternative to parsing it yourself.
我认为这是一个非常易读的替代方法来解析它。
Edit: As @raulk pointed out, this solution does not account for escaped characters. However, this may not be an issue because before you URL-Decode, the query string is guaranteed to not have any escaped characters that conflict with '=' and '&'. You can use this to your advantage in the following way.
编辑:正如@raulk 指出的,这个解决方案不考虑转义字符。但是,这可能不是问题,因为在您进行 URL 解码之前,保证查询字符串没有任何与“=”和“&”冲突的转义字符。您可以通过以下方式利用这一点。
Say that you must decode the following query string:
假设您必须解码以下查询字符串:
a=%26%23%25!)%23(%40!&b=%23%24(%40)%24%40%40))%24%23%5E*%26
which is URL encoded, then you are guaranteed that the '&' and '=' are specifically used for separating pairs and key from value, respectively, at which point you can use the Guava splitter to get:
这是 URL 编码的,那么您可以保证 '&' 和 '=' 分别专门用于将对和键与值分开,此时您可以使用 Guava 拆分器来获得:
a = %26%23%25!)%23(%40!
b = %23%24(%40)%24%40%40))%24%23%5E*%26
Once you have obtained the key-value pairs, then you can URL decode them separately.
获得键值对后,就可以分别对它们进行 URL 解码。
a = &#%!)#(@!
b = #$(@)$@@))$#^*&
That should cover all cases.
这应该涵盖所有情况。
回答by matt burns
Another way is to use apache http-components. It's a bit hacky, but at least you leverage all the parsing corner cases:
另一种方法是使用 apache http-components。这有点 hacky,但至少你利用了所有解析的极端情况:
List<NameValuePair> params =
URLEncodedUtils.parse("http://example.com/?" + queryString, Charset.forName("UTF-8"));
That'll give you a List of NameValuePair objects that should be easy to work with.
这将为您提供一个应该易于使用的 NameValuePair 对象列表。