19

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 then delete, add and modify query string KVP's.

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");

Or something to that effect.

2
  • 3
    You haven't provided enough context for anybody to give an answer. What kind of query strings? Please rephrase the question. Commented Nov 8, 2010 at 21:55
  • 1
    stackoverflow.com/questions/1667278/… Commented Nov 8, 2010 at 22:53

5 Answers 5

17

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));  
 }  
Sign up to request clarification or add additional context in comments.

4 Comments

Would love to have had something pre-built but this is great. :) thank you
It'd be more efficient to store param.split("=") in a variable and reusing the result as opposed to splitting the same param twice.
This solution does not take into account escaped characters.
This solution also does not take into account arrays.
12

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.

2 Comments

This solution does not take into account escaped characters.
@raulk I've added some steps that could be used even with escaped characters. Thanks!
5

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"));
}
}

3 Comments

+1, thanks for this. Already implemented something like this.
@Achimnol: What's the problem? &amp; is XML-encoding, it should pass through a URL parameter as %26amp;. If you want to further XML-decode the string, you can use other methods for that.
Note that ServletRequest.getParameterValues() can badly handle encoding: stackoverflow.com/questions/469874/…
2

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.

1 Comment

I found strange that this was not already proposed ... this is hacky but a good usage of an existing library...
0

You can create a util method and use regular expression to parse it. A pattern like "[;&]" should suffice.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.