JavaWeb 手写Tomcat底层机制
目录
一、Tomcat底层整体架构
1.简介 :
Tomcat 有三种运行模式 (BIO[阻塞], NIO[非阻塞], APR),这里采用 BIO 线程模型来模拟实现。
2.分析图 :
如下图所示 :
浏览器请求servlet资源后,Tomcat底层会通过Socket网络编程来接收请求,每次请求,都会创建一个新的线程去调用相应的Web资源,并返回。
3.基于Socket开发服务端的流程 :
如下图所示 :
通过获取的Socket对象,来获取Socket对象对应的字节输入流和字节输出流。
可以利用对象转换流将字节流转换为字符流对象(InputStreamReader实现了Reader抽象类),然后再通过BufferedReader的包装,将节点流转换成包装流(处理流)。
4.打通服务器端和客户端的数据通道 :
PS :
Maven配置Web应用,运行出现jakarta.servlet.ServletException:
因为tomcat10之后不是javax.servlet,而是jakarta.servlet,所以Web的依赖应该换成如下所示 : (pom.xml配置文件)
MyTomcat类代码如下 : (服务端;自定义的Tomcat)
在浏览器地址栏访问本机8080端口。
login.html代码如下 :
LoginServlet类代码如下 :
运行效果 :
如果以Web工程配置好的Tomcat运行,就会按照LoginServlet类的代码逻辑来处理业务,如下图所示 : (GIF)
如果以自定义的Tomcat运行,就会以MyTomcat类中的代码逻辑来处理业务。
如下图所示 : (GIF)
二、多线程模型的实现
1.思路分析 :
当服务器端接收到浏览器端的HTTP请求后,启动一个新的线程,令该线程持有浏览器对应的Socket对象,完成线程和浏览器的对接。
可通过实现Runnable接口的方式定义线程类HttpRequestHandler,线程对象用于处理来自浏览器的HTTP请求。
2.处理HTTP请求 :
线程类HttpRequestHandler类代码如下 :
3.自定义Tomcat :
在MyTomcat_EX类中实现线程的分发。
MyTomcat_EX类代码如下 :
运行效果 : (GIF)
三、自定义Servlet规范
1. HTTP请求和响应 :
1° CyanServletRequest
CyanServletRequest类的作用等同于原始的HttpServletRequest,该类用于封装HTTP请求中的数据,eg : method, URI, 以及表单数据的参数列表等。
CyanServletRequest类代码如下 :
CyanServletRequest类测试,运行效果如下GIF :
2° CyanServletResponse
CyanServletResponse类的作用等同于原始的HttpServletResponse,用于封装HTTP响应的相关信息。
CyanServletResponse类代码如下 :
运行测试(如下GIF图):
2.Servlet规范 :
1° CyanServlet
CyanServlet仅保留原生Servlet的init, destroy, service方法,其中,service方法供将来CyanServlet的抽象实现类CyanHttpServlet去重写。注意,service方法的形参列表,要使用自定义的CyanServletRequest 和 CyanServletResponse.
CyanServlet接口,代码如下 :
2° CyanHttpServlet
CyanHttpServlet的作用,类似于原生的HttpServlet;在CyanHttpServlet中实现CyanServlet接口中的service方法,在service方法中,要对HTTP请求的method类型进行判断。
CyanHttpServlet抽象类代码如下 :
3° CyanLoginServlet
CyanLoginServlet是一个简单的servlet实例,用于继承CyanHttpServlet抽象类,并实现CyanHttpServlet类中的doGet和doPost抽象方法。之后,在HttpRequestHandler线程类中先尝试直接调用CyanLoginServlet实例。
CyanLoginServlet代码如下 :
此外,还需要更新HttpServletHandler类中的类型,将已封装好的代码注释掉,HttpServletHandler类已更新,在上文“多线程模型实现”的HTTP请求处理模块。
运行效果如下图所示 :
3.容器实现 :
1° 思路分析
Tomcat中维护有至少两个大的HashMap容器。以web.xml配置文件的方式为例,其中一个HashMap容器,key存放<url-pattern>,value存放<servlet-name>;另一个HashMap容器,key存放<servlet-name>,value存放通过<servlet-class>来反射生成的servlet实例。
2° web.xml配置文件
web.xml配置文件如下 :
3° 最终版自定义Tomcat
在MyTomcat_Pro类中定义两个CurrentHashMap对象;定义init方法完成对两个CurrentHashMap对象的初始化(使用Dom4J读取web.xml配置文件)。
首先,需要在Maven的pom.xml配置文件中,引入dom4j依赖,如下图所示 :
然后,将web.xml配置文件拷贝到/target/classes/目录下一份,如下图所示 :
MyTomcat_Pro代码如下 :
4° 最终版自定义线程类
5° 容器启动测试
如下图所示(GIF):
- 点赞
- 收藏
- 关注作者
评论(0)