views:

260

answers:

4

Is there a widely-used Java library that does something like what dojo.objectToQuery() does? E.g. (assuming the use of HttpCore's HttpParams object, but any key-value mapping will do):

HttpParams params = new BasicHttpParams()
    .setParameter("foo", "bar")
    .setParameter("thud", "grunt");
UnknownLibrary.toQueryString(params);

should yield "foo=bar&thud=grunt".

I know it's not hard to write but it seems like it should have already been written. I just can't find it.

+3  A: 

You don't really need a library for that. I didn't find one in HttpCore either so I wrote something like this,

public String toString() {

 StringBuilder sb = new StringBuilder(baseUrl);

 char separator;

 if (baseUrl.indexOf('?') > 0)
  separator = '&';
 else
  separator = '?';

 for (Parameter p : parameters) {
  sb.append(separator);
    try {
   sb.append(URLEncoder.encode(p.name, "UTF-8"));
   if (p.value != null) {
       sb.append('=');
       sb.append(URLEncoder.encode(p.value, "UTF-8"));
   }
 } catch (UnsupportedEncodingException e) {
  // Not really possible, throw unchecked exception
  throw new IllegalStateException("No UTF-8");
 }  
 separator = '&';
 }

 return sb.toString();
}
ZZ Coder
+1  A: 

If you have JAX-RS there is javax.ws.rs.core.UriBuilder; other than that you should primarily be aware of URLEncoder and URLDecoder which will at least encode the pieces of the parameter list.

Kathy Van Stone
+1  A: 

I ended up writing my own. It can be called like

URIUtils.withQuery(uri, "param1", "value1", "param2", "value2");

which isn't so bad.

/**
 * Concatenates <code>uri</code> with a query string generated from
 * <code>params</code>.
 *
 * @param uri the base URI
 * @param params a <code>Map</code> of key/value pairs
 * @return a new <code>URI</code>
 */

public static URI withQuery(URI uri, Map<String, String> params) {
    StringBuilder query = new StringBuilder();
    char separator = '?';
    for (Entry<String, String> param : params.entrySet()) {
        query.append(separator);
        separator = '&';
        try {
            query.append(URLEncoder.encode(param.getKey(), "UTF-8"));
            if (!StringUtils.isEmpty(param.getValue())) {
                query.append('=');
                query.append(URLEncoder.encode(param.getValue(), "UTF-8"));
            }
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
    return URI.create(uri.toString() + query.toString());
}

/**
 * Concatenates <code>uri</code> with a query string generated from
 * <code>params</code>.  The members of <code>params</code> will be
 * interpreted as {key1, val1, key2, val2}.  Empty values can be given
 * as <code>""</code> or <code>null</code>.
 *
 * @param uri the base URI
 * @param params the key/value pairs in sequence
 * @return a new <code>URI</code>
 */
public static URI withQuery(URI uri, String... params) {
    Map<String, String> map = new LinkedHashMap<String, String>();
    for (int i = 0; i < params.length; i += 2) {
        String key = params[i];
        String val = i + 1 < params.length ? params[i + 1] : "";
        map.put(key, val);
    }
    return withQuery(uri, map);
}
Steven Huwig
+3  A: 

Why reinvent the wheel? Apache HttpClient has URLEncodedUtils:

   List<BasicNameValuePair> params = Arrays.asList(new BasicNameValuePair("\\%^ &=@#:", "\\%^ &=@#:"));
   String query = URLEncodedUtils.format(params, "UTF-8");
Stephen Siard