Apr 12, 2011

Get POST parameters from Java HTTP Server

It turns out that it is not very simple to do so.

First, Create a class name ParameterFilter


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package friendposter;

import com.sun.net.httpserver.Filter;
import com.sun.net.httpserver.Filter.Chain;
import com.sun.net.httpserver.HttpExchange;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
*
* @author Tanin
*/
public class ParameterFilter extends Filter {

@Override
public String description() {
return "Parses the requested URI for parameters";
}

@Override
public void doFilter(HttpExchange exchange, Chain chain)
throws IOException {
parseGetParameters(exchange);
parsePostParameters(exchange);
chain.doFilter(exchange);
}

private void parseGetParameters(HttpExchange exchange)
throws UnsupportedEncodingException {

Map parameters = new HashMap();
URI requestedUri = exchange.getRequestURI();
String query = requestedUri.getRawQuery();
parseQuery(query, parameters);
exchange.setAttribute("parameters", parameters);
}

private void parsePostParameters(HttpExchange exchange)
throws IOException {

if ("post".equalsIgnoreCase(exchange.getRequestMethod())) {
@SuppressWarnings("unchecked")
Map parameters =
(Map)exchange.getAttribute("parameters");
InputStreamReader isr =
new InputStreamReader(exchange.getRequestBody(),"utf-8");
BufferedReader br = new BufferedReader(isr);
String query = br.readLine();
parseQuery(query, parameters);
}
}

@SuppressWarnings("unchecked")
private void parseQuery(String query, Map parameters)
throws UnsupportedEncodingException {

if (query != null) {
String pairs[] = query.split("[&]");

for (String pair : pairs) {
String param[] = pair.split("[=]");

String key = null;
String value = null;
if (param.length > 0) {
key = URLDecoder.decode(param[0],
System.getProperty("file.encoding"));
}

if (param.length > 1) {
value = URLDecoder.decode(param[1],
System.getProperty("file.encoding"));
}

if (parameters.containsKey(key)) {
Object obj = parameters.get(key);
if(obj instanceof List) {
List values = (List)obj;
values.add(value);
} else if(obj instanceof String) {
List values = new ArrayList();
values.add((String)obj);
values.add(value);
parameters.put(key, values);
}
} else {
parameters.put(key, value);
}
}
}
}
}



Then, when start a server, please add ParameterFilter as a filter:


HttpServer server = HttpServer.create(new InetSocketAddress(PORT),100);

HttpContext context = server.createContext("/", new FriendPosterServer());
context.getFilters().add(new ParameterFilter());

server.setExecutor(null); // creates a default executor

server.start();


Then, in the handler, you may obtain parameters like this:


public void handle(HttpExchange t) throws IOException
{
...
Map params = (Map)t.getAttribute("parameters");
...
}