Java处理http协议相关初步(二)——httpserver
2012-04-17 14:49
405 查看
这里的HttpServer,并不是哪里专门下载的类库了,而是在JDK1.6中自带的,在com.sun.net.httpserver包中,提供了简单的较高层次意义上的Http ServerAPI,可以构建内置的HTTP Server,支持Http和Https协议,提供了HTTP1.1的部分实现,没有被实现的那部分可以通过扩展已有的Http Server API来实现。程序员必须自己实现HttpHandler接口,HttpServer会调用HttpHandler实现类的回调方法来处理客户端请求,在这里,我们把一个Http请求和它的响应称为一个交换,包装成HttpExchange类,HttpServer负责将HttpExchange传给HttpHandler实现类的回调方法.
(摘过来的,也是官方的描述说明)
通过下面使用一个简单的例子,就可以看到怎么使用它们了,详细的功能可以查看API文档。访问localhost:8086/ 和 localhost:8086/test看看
看这些的时候有个小插曲,当时看不懂既然有了createContext ( )方法中的实现HttpHandler接口的类来处理请求,为什么又要有个setExecutor来设置管理线程的Executor,而且还要在start()方法之前;这时自己查看文档的时候看到createContext(),start()方法都是抽象方法(当然HttpServer也是抽象类),是怎么调用的呢?在网上找到其源码时,才发现,HttpServer的创建首先是通过create(InetSocketAddress addr,
int backlog)这个静态方法创建,这里面是通过 HttpServerProvider(它也是抽象类,其子类 sun.net.httpserver.DefaultHttpServerProvider中的createHttpServer)来创建的,其后在具体创建过程中则是new了一个 HttpServerImpl类的实例(这个只是一个包装,具体实现是ServerImpl类来完成最后的HttpServer对象的生成);查看ServerImpl的实现,才知道setExecutor设置的是处理TCP链接请求的线程,而createContext
里设置的是针对具体的请求进行处理的回调方法,而且可以通过设置调用多次createContext(),设置不同路径采用不同或相同的处理方法。为什么绕了这么多,采用了什么设计模式,我是还没到那个高度,期待有人能给留言解说下;或者自己以后慢慢的体会吧!
后面再把这些东西合起来,想个大概的应用场景。
参考
实现Http Server的三种方法 http://lpn520.iteye.com/blog/781273
(摘过来的,也是官方的描述说明)
通过下面使用一个简单的例子,就可以看到怎么使用它们了,详细的功能可以查看API文档。访问localhost:8086/ 和 localhost:8086/test看看
package com.test.myjava; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import java.util.Queue; import java.util.concurrent.*; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class HttpServerTest { public static void main(String[] args) { try { //允许最大连接数 int backLog = 10; InetSocketAddress inetSock = new InetSocketAddress(8086); HttpServer httpServer = HttpServer.create(inetSock, backLog); //直接返回Hello..... httpServer.createContext("/", new HandlerTestA()); //显示已经处理的请求数,采用线程池 httpServer.createContext("/test",new HandlerTestB()); httpServer.setExecutor(null); httpServer.start(); System.out.println("HttpServer Test Start!"); } catch (Exception e) { e.printStackTrace(); } } } //直接处理请求 class HandlerTestA implements HttpHandler{ public void handle(HttpExchange httpExchange) throws IOException { // TODO Auto-generated method stub //针对请求的处理部分 //返回请求响应时,遵循HTTP协议 String responseString = "<font color='#ff0000'>Hello! This a HttpServer!</font>"; //设置响应头 httpExchange.sendResponseHeaders(200, responseString.length()); OutputStream os = httpExchange.getResponseBody(); os.write(responseString.getBytes()); os.close(); } } //线程池还不会用,简略的使用了下,意思有点差距,后面在分析 class HandlerTestB implements HttpHandler{ private static int requestNum = 0; ThreadPoolExecutor threadPoolExecutor; HandlerTestB(){ //两个常在线程,最大3个 threadPoolExecutor = new ThreadPoolExecutor(2,3, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), new ThreadPoolExecutor.CallerRunsPolicy() ); } public void handle(HttpExchange he) throws IOException { // TODO Auto-generated method stub if((getQueueSize(threadPoolExecutor.getQueue()))<2){ RequestTasks rqt = new RequestTasks(he); threadPoolExecutor.execute(rqt); } else System.out.println("Please Wait!"); } private synchronized int getQueueSize(Queue queue) { return queue.size(); } } //处理请求的任务 class RequestTasks implements Runnable{ static int processedNum = 0; HttpExchange httpExchange; RequestTasks(HttpExchange he){ httpExchange = he; processedNum++; } public void run() { // TODO Auto-generated method stub System.out.println("ProcessedNum:" +processedNum); String responseString = "ProcessedNum:" + processedNum + "\n"; try{ httpExchange.sendResponseHeaders(200, responseString.length()); OutputStream os = httpExchange.getResponseBody(); os.write(responseString.getBytes()); os.close(); //去掉注释,看看只能响应两个,有些问题 //while(true); }catch (Exception e){ e.printStackTrace(); } } }
看这些的时候有个小插曲,当时看不懂既然有了createContext ( )方法中的实现HttpHandler接口的类来处理请求,为什么又要有个setExecutor来设置管理线程的Executor,而且还要在start()方法之前;这时自己查看文档的时候看到createContext(),start()方法都是抽象方法(当然HttpServer也是抽象类),是怎么调用的呢?在网上找到其源码时,才发现,HttpServer的创建首先是通过create(InetSocketAddress addr,
int backlog)这个静态方法创建,这里面是通过 HttpServerProvider(它也是抽象类,其子类 sun.net.httpserver.DefaultHttpServerProvider中的createHttpServer)来创建的,其后在具体创建过程中则是new了一个 HttpServerImpl类的实例(这个只是一个包装,具体实现是ServerImpl类来完成最后的HttpServer对象的生成);查看ServerImpl的实现,才知道setExecutor设置的是处理TCP链接请求的线程,而createContext
里设置的是针对具体的请求进行处理的回调方法,而且可以通过设置调用多次createContext(),设置不同路径采用不同或相同的处理方法。为什么绕了这么多,采用了什么设计模式,我是还没到那个高度,期待有人能给留言解说下;或者自己以后慢慢的体会吧!
后面再把这些东西合起来,想个大概的应用场景。
参考
实现Http Server的三种方法 http://lpn520.iteye.com/blog/781273
相关文章推荐
- Java处理http协议相关初步(一)——httpclient
- Java处理http协议相关初步(三)——线程池的使用分析
- Java处理http协议相关初步(一)——httpclient
- Java中的http(网络处理)相关的库:HttpClient,HttpCore(转载)
- Java Web开发中用到的Http协议相关知识
- java实现网上在线支付--09,10,11,12_分析易宝支付网关的应答协议与处理代码,完成用于处理支付响应的Servlet的初步编写和调试,完成处理支付网关响应结果的Servlet,支付实现
- 基于JAVA中Jersey处理Http协议中的Multipart的详解
- [JAVA]使用Jersey处理Http协议中的Multipart
- java在线支付---09,10,11,12_在线支付_分析易宝支付网关的应答协议与处理代码,完成用于处理支付响应的Servlet的初步编写和调试,完成处理支付网关响应结果的Servlet,支付实现
- 如何处理java相关网络协议占内存的问题啊?为何时间越长,内存占用越大?
- 对java的 cookie处理进行修正(附http的相关知识)
- [JAVA]使用Jersey处理Http协议中的Multipart
- The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml... 处理方法
- java实现HTTP协议数据压缩
- java base64 编码 解码, HTTP传送解决+号 \n\r 问题,查询处理
- java 使用与字符串相关的类来处理数据
- java处理文本中的http/https链接
- Java(五)HTTP协议详解
- Java实现http协议的解析
- Java 实现HTTP协议