Does anyone have, or know of, a java class that I can use to manipulate query strings?
Essentially I\'d like a class that I can simply give a query string to and the
You can also use Google Guava's 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.
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:
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.
a = &#%!)#(@!
b = #$(@)$@@))$#^*&
That should cover all cases.
If you are using J2EE, you can use 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.
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"));
}
}
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));
}
You can create a util method and use regular expression to parse it. A pattern like "[;&]" should suffice.
Another way is to use apache http-components. It's a bit hacky, but at least you leverage all the parsing corner cases:
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.