我的Java Web之路 - Servlet(3)- 漫游Servlet

本文详细介绍了ServletAPI的主要接口,包括Servlet、ServletConfig、Filter、FilterConfig、ServletRequest、ServletResponse、ServletContext等,以及它们在JavaWeb开发中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本系列文章旨在记录和总结自己在Java Web开发之路上的知识点、经验、问题和思考,希望能帮助更多码农和想成为码农的人。
本文转发自头条号【普通的码农】的文章,大家可以关注一下,直接在今日头条的移动端APP中阅读。因为平台不同,会出现有些格式、图片、链接无效方面的问题,我尽量保持一致。

介绍

上篇文章提到Servlet的核心原理就是采用线程来执行Servlet的业务逻辑,可能有些过于简单了。但事实确实如此。不过具体是如何来执行Servlet的业务逻辑的,这需要好好设计一番。当然,主要还是依赖于Java的多态和面向接口编程的原则,正如这篇文章所述。
上篇文章也提到Servlet的物理构件主要有三个:
• Servlet容器
• Servlet API
• 我们编写的基于Servlet API扩展的Java代码
其中,主要跟我们编程打交道的是Servlet API,所以,本篇文章就介绍一下Servlet API的主要接口。

Servlet API的物理构件

Servlet API的物理构件在Tomcat提供的库中主要是servlet-api.jar,我们可以将它添加到我们建立的Java Web工程中,然后关联它的源码,方便我们查看它的主要接口。
新建Java Web工程以及添加servlet-api.jar,可以参考这篇文章。
下载Tomcat源码,可以参考这篇文章。
关联Tomcat源码,可以参考这篇文章。
如下图,我们可以看到Eclipse中添加的servlet-api.jar:
在这里插入图片描述

Servlet API的主要接口

我们继续点击展开上图中servlet-api.jar这个节点,如下图:
在这里插入图片描述
可以看到,这个Servlet API包括若干个包和文件夹:
• javax.servlet:主要定义Servlet和Servlet容器之间的接口、少量抽象类和类,包括Servlet、ServletRequest、ServletResponse、ServletContext、ServletConfig、Filter等;
• javax.servlet.annotation:包括用于配置的注解;
• javax.servlet.descriptor:跟JSP有关,暂时不讨论;
• javax.servlet.http:主要定义围绕HTTP的接口,包括:HttpServlet、HttpServletRequest、HttpServletResponse、HttpFilter、HttpSession等;
• javax.servlet.resources:各种XML的定义文件,有XML Schema规范的(xsd后缀,我们前面文章已经介绍过)、DTD规范的(dtd后缀),可以看到包含了我们的部署描述符的元素定义(web-app开头的);
• META-INF:暂时不用理会。
其实,我们主要用到的就是下面的几个接口。

Servlet和ServletConfig

在这里插入图片描述
Servlet主要有init()、service()、destroy()等方法,init()只有在第一次请求到来时会执行;service()是提供服务的方法,当然就是每个请求都会执行;destroy()方法只有在卸载Web应用或关闭Servlet容器时执行。
每个Servlet都会有一定的初始化参数,它们都是Servlet容器从部署描述符中读取后,封装成ServletConfig,通过init()方法传递给Servlet使用。所以,ServletConfig最主要的方法就是获取初始化参数的getInitParameter()。
GenericServlet是一个抽象类,它实现了Servlet和ServletConfig这两个接口。
HttpServlet也是一个抽象类,它继承/扩展了GenericServlet,最主要的方法就是doGet()、doPost()等供我们覆盖的方法。我们通常都会扩展HttpServlet。

Filter和FilterConfig

在这里插入图片描述
Filter(过滤器)和Servlet类似,主要有init()、doFilter()、destroy()等方法。
Filter主要是为了拦截用户请求,在用户请求访问资源之前处理ServletRequest和ServletResponse,可以用于日志记录、加解密、Session检查、图像文件保护等。
Filter与Servlet的不同之处在于,一个请求可以由多个Filter(组成Filter链条)按顺序处理;但最终只能匹配一个Servlet处理。部署描述符中需要把先被触发执行的Filter写在前面。
Filter也有自己的配置参数,被封装成FilterConfig,与ServletConfig类似。
FilterChain接口就是Filter链条的抽象,包含了多个按顺序执行的Filter。
GenericFilter和HttpFilter比较简单。

ServletRequest和HttpServletRequest

在这里插入图片描述
ServletRequest和HttpServletRequest代表了用户的请求,HttpServletRequest扩展了ServletRequest。当然,实际运行过程中是由Servlet容器将用户请求解析并封装成ServletRequest和HttpServletRequest。它们主要包括操作请求报文中各种数据的方法。
ServletRequestWrapper和HttpServletRequestWrapper这两个类分别实现了ServletRequest和HttpServletRequest接口,它们主要使用了装饰器(Decorator)设计模式,可以对请求和响应的行为进行修改。
可以从ServletRequest中获取到直接访问报文原始数据的IO流ServletInputStream。
从ServletRequest中也可以获取到用于转发请求到其他Servlet或Web组件进行处理的RequestDispatcher。
ReadListener暂时不理会。

ServletResponse和HttpServletResponse

在这里插入图片描述
ServletResponse和HttpServletResponse代表了将要返回给用户的响应,HttpServletResponse扩展了ServletResponse。当然,实际运行过程中是由Servlet容器预先生成封装了发送报文细节的ServletResponse和HttpServletResponse,用户只需要通过getOutputStream()和getWriter()获取IO流来填充响应内容即可。
HttpServletResponse中的sendRedirect()方法用于HTTP请求的重定向。
ServletResponseWrapper和HttpServletResponseWrapper类似于请求的包装器。
ServletOutputStream用于直接访问响应报文。
WriteListener暂时不理会。

ServletContext

在这里插入图片描述
ServletContext代表的是Web应用本身,它管理着Servlet、Filter、Listener的创建、添加、注册等,同时也可以获取Web应用的一些配置信息和其他属性。

监听器

监听器用于监听某些事件,通常是一些生命周期事件:
• 初始化事件
• 销毁事件
和属性的变化事件:
• 属性添加事件
• 属性移除事件
• 属性修改事件
监听器包括以下:
• ServletContextListener和ServletContextEvent
• ServletContextAttributeListener和ServletContextAttributeEvent
• ServletRequestListener和ServletRequestEvent
• ServletRequestAttributeListener和ServletRequestAttributeEvent
• HttpSessionListener和HttpSessionEvent
• HttpSessionIdListener
• HttpSessionBindingListener和HttpSessionBindingEvent
• HttpSessionAttributeListener
• HttpSessionActivationListener
监听器也可以在部署描述符中配置,前面的文章介绍过Spring MVC整合Spring IoC中就使用了Spring MVC为我们提供的org.springframework.web.context.ContextLoaderListener。它就是实现了javax.servlet.ServletContextListener接口,从而可以能够监听ServletContext对象的生命周期。

总结

上面我们粗略的过了一遍Servlet API,其中大部分是接口,小部分是抽象类和类。还有一部分尚未介绍,比如关于会话、异步操作等方面的接口。
其实Servlet技术的各个接口设计也是很自然而合理的,可以通过它们的概念层次关系图看出来:
在这里插入图片描述
首先,Servlet容器处于最外层,它拦截并解析用户请求,并封装成ServletRequest;同时将响应的传输协议和发送细节封装在ServletResponse,用户只需通过它的Writer填充响应的内容即可。
其次,Servlet容器可以部署多个Web应用,每个Web应用对应一个ServletContext,用于与Servlet容器之间的交互。它们都有自己的部署描述符,即有自己的配置。
然后,每个Web应用可以配置多个Servlet、Filter。当然,每个Servlet和Filter也都有自己的配置。
最后,Servlet容器中还可以配置多个监听器,监听各个对象的各种事件。
用户通过继承/扩展Servlet和Filter来实现自己需要的业务功能,然后配置好与用户请求的对应关系。
Servlet容器根据配置找到用户请求对应的Servlet和Filter之后,将该请求分派给线程池中的某个线程,执行Servlet和Filter的服务方法。
Servlet和Filter的服务方法的参数中包含有ServletRequest和ServletResponse,用户可以获取请求中的任何数据,也可以向响应中填充任何数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值