views:

294

answers:

3

I have a Map with my data and want to build a query string with it, just like I would with http_build_query on PHP. I'm not sure if this code is the best implementation of it or if I'm forgetting something?

public String toQueryString(Map<?, ?> data) throws UnsupportedEncodingException {
    StringBuffer queryString = new StringBuffer();

    for (Entry<?, ?> pair : data.entrySet()) {
        queryString.append ( URLEncoder.encode ( (String) pair.getKey (), "UTF-8" ) + "=" );
        queryString.append ( URLEncoder.encode ( (String) pair.getValue (), "UTF-8" ) + "&" );
    }

    if (queryString.length () > 0) {
        queryString.deleteCharAt ( queryString.length () - 1 );
    }

 return queryString.toString ();
}
+1  A: 

Looks OK, with these caveats:

  • make the parameter a Map<String, String> rather than casting key and value to String.
  • the hardcoded encoding looks suspicious. UTF-8 is not a given, it has to match the encoding defined in the header of the HTTP request. So the code should ensure that they do - at least define it as a constant somewhere and refer to that both here and wherever the request encoding is set.

Edit: It seems that I was wrong about the encoding; HTTP GET parameters are not subject to an encoding header, and did not traditionally have a well-defined encoding at all. RFC 3988 does seem to mandate UTF-8, but that sounds rather brittle to me, so unless you have tight control over the server and can ensure that it does indeed use UTF-8 as well, I'd use POST requests for any data that's not in the 7bit ASCII range.

Michael Borgwardt
a) Fixed it, thanks.b) Seems you're right, but I'm using restlet.org packages to do a REST request and it doesn't let you define the encoding of the request. Let's say it doesn't specify one, what would the default be? Depends on the server configuration?
falmp
+2  A: 

look at the QueryStringBuilder class and its test class :

QueryStringBuilder builder = new QueryStringBuilder()
for (Entry<?, ?> pair : data.entrySet()) {
    builder.addQueryParameter(data.getKey(), data.getValue());
}
return builder.encode("UTF-8");
Vladimir
I'm accepting this answer because that's exactly what I asked. I'm keeping my own version though since I was pretty close to it. :)
falmp
Looks nice, you should considering packaging it or submitting it to as a library. One small quibble, the name is misleading - it's not just building a query string, it includes a path as well.
pimlottc
+1  A: 

You'd probably want to check the "Accept" request header for the encodings supported by the client before forcing UTF-8 (even though it's probably the best choice).

magnus.wissler