前面说到HttpServer是JDK6提供的一个轻量的http server,位于
- com.sun.net.httpserver
- com.sun.net.httpserver.spi
主要的接口或类如下
Class/interface | What does it do? |
---|---|
HttpServer | Listens on a particular port number and address for incoming Http requests |
HttpsServer | Same as for HttpServer except for Https requests |
HttpHandler | Programmer implements this. Handler is called to handle each incoming Http request |
HttpExchange | Encapsulates all of the information about a Http request and the corresponding response |
HttpContext | Represents one Http application on a HttpServer instance. It is identified by the URI path to the application, and has a HttpHandler associated |
更多的详情见这里。下面来见一个简单的例子
1、创建一个HttpServer实例
InetSocketAddress addr = new InetSocketAddress(8080);
//创建一个httpserver实例,0表示开启服务
HttpServer server = HttpServer.create(addr, 0);
//HttpContext与servlet中的ServletContext类似
//这里指定了ContextPath(/get/user),以及相应的Handler(Servlet)
HttpContext context = server.createContext("/get/user", new ParameterHandler());
//这里指定了Filter
context.getFilters().add(new ParameterFilter());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
这样就创建了一个端口8080的http server当前对其中注册的Handler和Filter接下来需要说明
2、这里的ParameterHandler需要实现HttpHandler用来处理请求。这里实现一个简单用例:打印headers和将请求中的参数作为string返回
public class ParameterHandler implements HttpHandler {
public void handle(HttpExchange exchange) throws IOException {
String requestMethod = exchange.getRequestMethod();
if (requestMethod.equalsIgnoreCase("GET")) {
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type", "text/plain");
exchange.sendResponseHeaders(200, 0);
OutputStream responseBody = exchange.getResponseBody();
Headers requestHeaders = exchange.getRequestHeaders();
Set<String> keySet = requestHeaders.keySet();
Iterator<String> iter = keySet.iterator();
//print headers info
responseBody.write("headers: \n".getBytes());
while (iter.hasNext()) {
String key = iter.next();
List<?> values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\n";
responseBody.write(s.getBytes());
}
//print parameters
responseBody.write("parameters: \n".getBytes());
@SuppressWarnings("unchecked")
Map<String, String> params = (Map<String, String>) exchange.getAttribute("parameters");
for (Map.Entry<String, String> entry : params.entrySet()) {
responseBody.write((entry.getKey() + " = " + entry.getValue() + "\n").getBytes());
}
responseBody.close();
}
}
}
3、在上面的ParameterHandler中我们用到了
exchange.getAttribute("parameters");
但是parameters并没有处理,这就需要在Filter中来实现。也是在HttpContext 中加入的Filter,需要继承Filter。这和Servlet规范中很类似吧
public class ParameterFilter extends Filter {
@Override
public String description() {
return "description...";
}
@Override
public void doFilter(HttpExchange exchange, Chain chain) throws IOException {
URI uri = exchange.getRequestURI();
String rawQuery = uri.getRawQuery();
if (null != rawQuery) {
Map<String, String> map = new HashMap<String, String>();
String[] params = rawQuery.split("&");
for (String param : params) {
String[] paras = param.split("\\=");
map.put(paras[0], paras[1]);
}
exchange.setAttribute("parameters", map);
}
chain.doFilter(exchange);
}
}
这里只是把请求(GET)中的参数做简单的处理并设置到HttpContext中。
4、到这一步这个例子也已差不多了,运行1中的代码即可在浏览器中访问,比如我们的访问及结果如下:
//RequestUrl
http://localhost:8080/get/user?name=robin&gender=male
headers:
Host = [localhost:8080]
Accept-charset = [GBK,utf-8;q=0.7,*;q=0.3]
Accept-encoding = [gzip,deflate,sdch]
Connection = [keep-alive]
Accept-language = [zh-CN,zh;q=0.8]
User-agent = [Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.96 Safari/537.4]
Accept = [text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8]
parameters:
name = robin
gender = male
DONE!