I am trying to create a simple HttpServer in Java to handle GET requests, but when I try to get the GET parameters for a request I noticed the HttpExchange class does not have a method for that.
Does anybody know an easy way to read the GET parameters (query string)?
This is how my handler looks like:
public class TestHandler{
@Override
public void handle(HttpExchange exc) throws IOxception {
String response = "This is the reponse";
exc.sendResponseHeaders(200, response.length());
// need GET params here
OutputStream os = exc.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
.. and the main method:
public static void main(String[] args) throws Exception{
// create server on port 8000
InetSocketAddress address = new InetSocketAddress(8000);
HttpServer server = new HttpServer.create(address, 0);
// bind handler
server.createContext("/highscore", new TestHandler());
server.setExecutor(null);
server.start();
}
The following: httpExchange.getRequestURI().getQuery()
will return string in format similar to this: "field1=value1&field2=value2&field3=value3..."
so you could simply parse string yourself, this is how function for parsing could look like:
public Map<String, String> queryToMap(String query) { if(query == null) { return null; } Map<String, String> result = new HashMap<>(); for (String param : query.split("&")) { String[] entry = param.split("="); if (entry.length > 1) { result.put(entry[0], entry[1]); }else{ result.put(entry[0], ""); } } return result; }
And this is how you could use it:
Map<String, String> params = queryToMap(httpExchange.getRequestURI().getQuery()); System.out.println("param A=" + params.get("A"));
This answer, contrary to annon01's, properly decodes the keys and values. It does not use String.split
, but scans the string using indexOf
, which is faster.
public static Map<String, String> parseQueryString(String qs) { Map<String, String> result = new HashMap<>(); if (qs == null) return result; int last = 0, next, l = qs.length(); while (last < l) { next = qs.indexOf('&', last); if (next == -1) next = l; if (next > last) { int eqPos = qs.indexOf('=', last); try { if (eqPos < 0 || eqPos > next) result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), ""); else result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java } } last = next + 1; } return result; }
Building on the answer by @anon01, this is how to do it in Groovy:
Map<String,String> getQueryParameters( HttpExchange httpExchange )
{
def query = httpExchange.getRequestURI().getQuery()
return query.split( '&' )
.collectEntries {
String[] pair = it.split( '=' )
if (pair.length > 1)
{
return [(pair[0]): pair[1]]
}
else
{
return [(pair[0]): ""]
}
}
}
And this is how to use it:
def queryParameters = getQueryParameters( httpExchange )
def parameterA = queryParameters['A']
Stumbled across this, and figured I'd toss a Java 8 / Streams implementation out here, whilst adding a few extra bits (not in previous answers).
Extra 1: I've added a filter to avoid processing any empty params. Something that should not happen, but it allows a cleaner implementation vs. not handling the issue (and sending an empty response). An example of this would look like ?param1=value1¶m2=
Extra 2: I've leveraged String.split(String regex, int limit) for the second split operation. This allows a query parameter such as ?param1=it_has=in-it&other=something
to be passed.
public static Map<String, String> getParamMap(String query) {
// query is null if not provided (e.g. localhost/path )
// query is empty if '?' is supplied (e.g. localhost/path? )
if (query == null || query.isEmpty()) return Collections.emptyMap();
return Stream.of(query.split("&"))
.filter(s -> !s.isEmpty())
.map(kv -> kv.split("=", 2))
.collect(Collectors.toMap(x -> x[0], x-> x[1]));
}
Imports
import java.util.Map;
import java.util.Collections;
import java.util.stream.Stream;
import java.util.stream.Collectors;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With