在写这篇博客之前我查了很久发现全网都没有一篇写httpserver源码解析的
所以今天就由我来为大家解析一下httpserver的源码。(这里我会去掉其中的https部分的源码,只讲http部分,对httpserver中https的实现感兴趣的读者可以尝试自己去阅读,这部分并不复杂)
第一次在没有参考资料的情况下写这么长一篇源码解析,可能会有很多错误和讲不清楚的地方,希望大家尽量指出来。
大家最好先跟着我构建这样一个小demo,跑起来之后再一步一步去看源码
/**
* @author 肥宅快乐码
*/
public class HttpServerSample {
private static void serverStart() throws IOException {
HttpServerProvider provider = HttpServerProvider.provider();
// 监听端口8080,连接排队队列,如果队列中的连接超过这个数的话就会拒绝连接
HttpServer httpserver =provider.createHttpServer(new InetSocketAddress(8080), 100);
// 监听路径为RestSample,请求处理后回调RestGetHandler里的handle方法
httpserver.createContext("/RestSample", new RestGetHandler());
// 管理工作线程池
ExecutorService executor = new ThreadPoolExecutor(10,200,60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.AbortPolicy());
httpserver.setExecutor(executor);
httpserver.start();
System.out.println("server started");
}
public static void main(String[] args) throws IOException {
serverStart();
}
}
/**
* 回调类,里面的handle方法主要完成将包装好的请求头返回给客户端的功能
*/
class RestGetHandler implements HttpHandler {
@Override
public void handle(HttpExchange he) throws IOException {
String requestMethod = he.getRequestMethod();
// 如果是get方法
if ("GET".equalsIgnoreCase(requestMethod)) {
// 获取响应头,接下来我们来设置响应头信息
Headers responseHeaders = he.getResponseHeaders();
// 以json形式返回,其他还有text/html等等
responseHeaders.set("Content-Type", "application/json");
// 设置响应码200和响应body长度,这里我们设0,没有响应体
he.sendResponseHeaders(200, 0);
// 获取响应体
OutputStream responseBody = he.getResponseBody();
// 获取请求头并打印
Headers requestHeaders = he.getRequestHeaders();
Set<String> keySet = requestHeaders.keySet();
Iterator<String> iter = keySet.iterator();
while (iter.hasNext()) {
String key = iter.next();
List values = requestHeaders.get(key);
String s = key + " = " + values.toString() + "\r\n";
responseBody.write(s.getBytes());
}
// 关闭输出流
responseBody.close();
}
}
}
① 最开始我们通过 HttpServerProvider provider = HttpServerProvider.provider(); 创建了一个HttpServerProvider,也就是这里的DefaultHttpServerProvider
// HttpServerProvider.java
public static HttpServerProvider provider () {
// 这里我们删掉了其他部分,只留下172、173两行
// 这里创建了一个DefaultHttpServerProvider
provider = new sun.net.httpserver.DefaultHttpServerProvider();
return provider;
}
② 之后我们调用 HttpServer httpserver =provider.createHttpServer(new InetSocketAddress(8080), 100); ,
也就是调用了DefaultHttpServerProvider的createHttpServer创建一个HttpServerImpl,当然这里也可以用createHttpsServer创建一个HttpsServerImpl,但是前面说了我们这篇不分析https,所以这里忽略了createHttpsServer方法
还有这里创建ServerImpl的构造方法我们暂时不讲,留到后面再讲
// DefaultHttpServerProvider.java
public HttpServer createHttpServer (InetSocketAddress addr, int backlog) throws IOException {
return new HttpServerImpl (addr, backlog);
}
// HttpServerImpl.java
HttpServerImpl (
InetSocketAddress addr, int backlog
) throws IOException {
server = new ServerImpl (this, "http", addr, backlog);
}
③ 接下来我们创建了一个监听路径 httpserver.createContext("/RestSample", new RestGetHandler());
// HttpServer.java
public abstract HttpContext createContext (String path, HttpHandler handler) ;
// HttpContextImpl.java
public HttpContextImpl createContext (String path, HttpHandler handler) {
// 这里调用的server是ServerImpl类的对象
return server.createContext (path, handler);
}
这里成功返回了一个HttpContextImpl对象,这个我们后面会说,这
jdk下httpserver源码解析
最新推荐文章于 2023-09-14 23:51:21 发布