ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

自己动手写一个tomcat之2拆分httpserver职责

2026/8/13 9:57:15 拓冰建站 浏览量
自己动手写一个tomcat之2拆分httpserver职责

写在前面

源码 。
本文目标,使用标准的servlet,以及拆分httpserver职责。

1:使用标准的servlet

引入标准servlet的pom:

<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency>

让HttpServlet实现javax.servlet.Servlet接口,使其成为标准的servlet:

publicclassHelloServletimplementsServlet{}

同样的request和response成为规范内的请求和响应对象:

importjavax.servlet.ServletRequest;publicclassRequestimplementsServletRequest{}
importjavax.servlet.ServletResponse;publicclassResponseimplementsServletResponse{}

2:拆分httpserver职责

当前,连接,处理请求职责都在http server,这显然不符合单一职责的原则,来拆分下,对于连接,引入Connector组件,对于处理请求引入processor组件。Connector组件定义类HttpConnector:

packagemonitomcat.server;// ...publicclassHttpConnectorimplementsRunnable{publicvoidrun(){ServerSocketserverSocket=null;intport=8080;try{serverSocket=newServerSocket(port,1,InetAddress.getByName("127.0.0.1"));}catch(IOExceptione){e.printStackTrace();System.exit(1);}while(true){Socketsocket=null;try{socket=serverSocket.accept();HttpProcessorprocessor=newHttpProcessor();processor.process(socket);// Close the socketsocket.close();}catch(Exceptione){e.printStackTrace();}}}publicvoidstart(){Threadthread=newThread(this);thread.start();}}

processor组件定义类HttpProcessor:

packagemonitomcat.server;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.Socket;publicclassHttpProcessor{publicHttpProcessor(){}publicvoidprocess(Socketsocket){InputStreaminput=null;OutputStreamoutput=null;try{input=socket.getInputStream();output=socket.getOutputStream();// create Request object and parseRequestrequest=newRequest(input);request.parse();// create Response objectResponseresponse=newResponse(output);response.setRequest(request);if(request.getUri().startsWith("/servlet/")){ServletProcessorprocessor=newServletProcessor();processor.process(request,response);}else{StaticResourceProcessorprocessor=newStaticResourceProcessor();processor.process(request,response);}}catch(Exceptione){e.printStackTrace();}}}

此时整个处理请求过程如下:

这样我们的启动类就很简单了:

packagemonitomcat.server;// ...publicclassHttpServer{publicstaticfinalStringWEB_ROOT=System.getProperty("user.dir")+File.separator+"target"+File.separator+"classes"+File.separator+"webroot";publicstaticfinalStringWEB_ROOT_SERVLET=System.getProperty("user.dir")+File.separator+"target"+File.separator+"classes"+File.separator+"monitomcat"+File.separator+"server";publicstaticvoidmain(String[]args){// HttpServer server = new HttpServer();// server.await();// 启动连接器HttpConnectorconnector=newHttpConnector();connector.start();}}

相比原来的代码是不是倍感清新舒爽~~~~~~~~!!!!!!!!
测试下:

C:\Users\dell9020>curl http://localhost:8080/hello.txt say hello from minitomcat v2...! C:\Users\dell9020>curl http://localhost:8080/servlet/monitomcat.server.HelloServlet <!DOCTYPE html> <html> <head><meta charset="utf-8"><title>Test</title></head> <body bgcolor="#f0f0f0"> <h1 align="center">Hello World from standard servlet!!!</h1>

写在后面

参考文章列表

手把手带你写一个 MiniTomcat 。