轻量级的HttpServer
在JDK1.6里面,提供了一个轻量级的HttpServer实现,我们先来看官方的文档怎么说:
Provides a simple high-level Http server API, which can be used to build embedded HTTP servers.
这个HttpServer并非专门的类库,而是在com.sun.net.httpserver包中,提供了简单可控的高层次的Http 服务器端API。利用这个HttpServer,可以构建内置(Embedded)的Server,支持HTTP和HTTPS协议,提供了HTTP1.1的部分实现;对于还没有实现的内容,可以通过扩展API实现。
如果想实现自己的API,必须实现HttpHandler接口,Server会通过回调Handler来处理客户端的请求。HttpServer会将Request和Response包装称HttpExchange类,Server负责执行HttpHandler中的handle回调方法,返回给客户端响应。
上面提到的HttpHandler、HttpExchange都是Server的相关类,我们会仔细看下这几个类。
我有这么一个需求,我启动了个后台应用,在后台进行业务处理;现在我想监控下服务的状态、或者对服务进行写额外的操作,可以把HttpServer启动,作为一个简单的Server使用,至少对于并发性要求不高的监控和后台应用来说是满足要求的。
下面我们看下Server端的代码:
public class TServer { public static void main ( String[] args ) { String serv = "localhost"; InetSocketAddress address = new InetSocketAddress(serv, 9988); try { HttpServer server = HttpServer.create(address, 5); HttpHandler handler = new EchoHandler(); server.createContext("/tc", handler); server.setExecutor(null); server.start(); System.out.println("server started at " + new Date()); } catch (IOException e) { e.printStackTrace(); } } static class EchoHandler implements HttpHandler { public void handle ( HttpExchange httpExchange ) throws IOException { System.out.println(httpExchange.getRequestURI().toString()); String resp = "Hello world!"; httpExchange.sendResponseHeaders(200, resp.length()); OutputStream os = httpExchange.getResponseBody(); os.write(resp.getBytes()); os.flush(); } } }
Server已经启动,可以启动浏览器,输入
http://localhost:9988/tc
可以看到输出结果:Hello world!
下面我们看下HttpHandler的内容,
public abstract interface com.sun.net.httpserver.HttpHandler { public abstract void handle(com.sun.net.httpserver.HttpExchange arg0) throws java.io.IOException; }
这是个接口,自有的Handler实现必须实现这个方法,是Server能够根据请求回调这个Handler实现,返回结果。
下面我们再看下HttpExchange这个类,这个是包装了Request和Response的主要类,是我们接收请求、处理逻辑、返回结果的合体。
HttpExchange提供了几个方法:
getRequestMethod():获得请求的方法,支持GET和POST请求 getRequestHeaders():获得请求的Headers getRequestBody():获得请求的输入流,输入流数据消费完的话,输入流关闭 getResponseHeaders():出去content-length字段外,可以设置任何Response Header sendResponseHeaders(int,long):返回Headers getResponseBody():获得相应的输入流,如果响应完成,输出流必须关掉。
还有几个类需要注意下,如果在工作中用到的话:
Authenticator:对于HTTP的身份认证进行基本的操作。 HttpPrincipal:表明身份认证的身份。 HttpContext:对Server的执行路径进行映射 Filter:对于请求进行处理:可以先处理或者后处理,注册在HttpContext中。
Spring里面有个HttpHandler的实现,大家可以参考下:
org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter
说到Server,HttpServer确实是很简单;因为简单,所以功能有限。下面我们说下工作中可能用到的Server:
Jetty:提倡把Jetty放到应用中,作为内嵌的服务器,功能足够强大,也能够满足平常的需求;支持Servlet和war包部署,配置启动;最新的文档见这里:http://www.eclipse.org/jetty/documentation/current/
Grizzly,Netty:Grizzly没有用过,Netty曾经分析过:http://isilic.iteye.com/category/254278,准确的说,这两个不应该是Server,是Network Framework。是编写基于NIO的网络通信框架,当然兼有Server的功能,你也可以把它当做Server,不过有点大材小用了。提到Netty,就不得不提到Mina,这几个网络通信框架的功能类似,只是在实现细节上有区别。其实这些NIO框架,熟悉一个就足够了,剩下的就是实现细节和内存使用上了。
最后说下这个信息:
@SuppressWarnings("restriction")
这个是对注解字段的警告抑制,因为我们在类中使用了HttpServer。
HttpServer is not accessible due to restriction on required library rt.jar
这个类的获取是受限的,所以会有编译器警告,使用上面的注解可以去掉这些注解。
因为轻巧,所以强大。这也算是简单就是美的体现吧