Java Servlet 是 java web 开发的一套解决方案,一套接口定义。Servlet 程序在服务器端运行,动态地生成 Web 页面。运行 Servlet 程序的服务器叫做 Servlet 容器。
常见的容器有
- Tomcat:由Apache开发的开源免费服务器;
- Jetty:由Eclipse开发的开源免费服务器;
- GlassFish:一个开源的全功能JavaEE服务器。
- 还有其他的商业服务器。Oracle的WebLogic,IBM的WebSphere。
项目结构
maven 项目结构,打包生成 war 包进行部署。web.xml
是 web 应用的配置文件。

容器
web容器在启动时,为每个微博应用程序创建一个对应的
ServletContext
,代表当前的 web 应用一个web应用中的所有
Servlet
共享同一个ServletContext
对象,因此Servlet
对象之间可以通过ServletContext
对象来实现通信应用:
- 获取 web 应用的全局初始化参数
- 通过
ServletContext
实现数据共享 - 利用
ServletContext
读取资源文件

加载顺序
web 容器的加载顺序 ServletContext –> context-param –> listener –> filter –> servlet
这些元素可以配置在 web.xml
文件中的任意位置,不会因为 filter 在 web.xml
文件中写在 listener 前面就先加载 filter 。
加载过程顺序如下:
- 启动一个 web 项目,web 容器会读取它的配置文件
web.xml
,读取 listener 和 context-param 两个结点。 - 创建一个 ServletContext ( Servlet 上下文),这个 web 项目的所有部分都将共享这个上下文
- 容器将 context-param 转换为键值对,并交给 ServletContext
- 容器创建 listener 中的类实例,创建监听器
- 容器创建 filter 实例
- servlet 实例在第一次请求的时候才会创建实例,然后
init()
初始化。(在web.xml
中配置load-on-startup
标签后,会在应用启动后就初始化)
Servlet 生命周期
Servlet 生命周期的三个核心方法分别是 init()
, service()
和destroy()
。每个Servlet都会实现这些方法,并且在特定的运行时间调用它们。
init
在 Servlet 生命周期的初始化阶段,web容器通过调用 init()
方法来初始化Servlet实例,并且可以传递一个实现 javax.servlet.ServletConfig
接口的对象给它。这个配置对象使 Servlet 能够读取在 web 应用的 web.xml
文件里定义的名值(name-value)初始参数。这个方法在Servlet实例的生命周期里只调用一次。
service
web 容器调用 Servlet 的 service()
方法来处理每一个请求。service()
方法定义了能够处理的请求类型并且调用适当方法来处理这些请求。编写Servlet的开发者必须为这些方法提供实现。如果发出一个Servlet没实现的请求,那么父类的方法就会被调用并且通常会给请求方(requester)返回一个错误信息。
destroy
web 容器调用 destroy()
方法来终结 Servlet。如果你想在 Servlet 的生命周期内关闭或者销毁一些文件系统或者网络资源,你可以调用这个方法来实现。destroy()
方法和 init()
方法一样,在 Servlet 的生命周期里只能调用一次。
配置
load-on-startup
tomcat启动时就创建对象,大于0,多个Servlet的话按照数字从小到大创建
Servlet实例是在Tomcat中创建,Tomcat只创建一个实例,因此是单例的。
Filter
Filter
可认为是Servlet
的一种“加强版”,主要用于对用户请求request
进行预处理,也可以对Response
进行后处理,是个典型的处理链。
使用Filter
的完整流程是:Filter
对用户请求进行预处理,接着将请求HttpServletRequest
交给Servlet
进行处理并生成响应,最后Filter
再对服务器响应HttpServletResponse
进行后处理。Filter
与Servlet
具有完全相同的生命周期。
换种说法,Servlet
里有request
和response
两个对象,Filter
能够在一个request
到达Servlet
之前预处理request
,也可以在离开Servlet
时处理response
,Filter
其实是一个Servlet
链。

以下是Filter的一些常见应用场合,
- 认证Filter
- 日志和审核Filter
- 图片转换Filter
- 数据压缩Filter
- 密码Filter
- 令牌Filter
- 触发资源访问事件的Filter
- XSLT Filter
- 媒体类型链Filter
Filter可负责拦截多个请求或响应;一个请求或响应也可被多个Filter拦截。
Filter 生命周期
init
在应用启动的时候就进行装载 Filter 类,容器创建好 Filter 对象实例后,调用 init()
方法。接着被 Web 容器保存进应用级的集合容器中去了等待着,用户访问资源。
doFilter
当用户访问的资源正好被 Filter 的url-pattern
拦截时,容器会取出 Filter 类调用 doFilter()
方法,下次或多次访问被拦截的资源时,Web 容器会直接取出指定 Filter 对象实例调用 doFilter()
方法。
destroy
当应用服务被停止或重新装载了,则会执行 Filter 的 destroy()
方法,Filter 对象销毁。
配置
当有多个过滤的url-pattern
一样时,过滤器的先后和配置的先后保持一致
FilterChain:过滤器链,当有多个过滤器配置了相同的url-pattern
时,每个过滤器就像链子一样串联起来,如MyFilter–>MyFilter2—>MyFilterN,
当执行完第一个过滤器的时候通过调用chain.doFilter(request, response)
来执行过滤器链中的下一个过滤器的 doFilter()
方法
filter-mapping
标签中 dispatcher
指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST
,INCLUDE
,FORWARD
和ERROR
之一,默认REQUEST
。用户可以设置多个子元素用来指定 Filter 对资源的多种调用方式进行拦截。
REQUEST:
当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher
的include()
或forward()
方法访问或ERROR
情况时,那么该过滤器就不会被调用。
INCLUDE:
如果目标资源是通过RequestDispatcher
的include()
方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWARD:
如果目标资源是通过RequestDispatcher
的forward()
方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:
如若在A.jsp
页面page
指令中指定了error
属性=examError.jsp
,那么A.jsp
中若出现了异常,会跳转到examError.jsp
中处理。而在跳转到examError.jsp
时,若过滤器配置了ERROR
的dispather
那么则会拦截,否则不会拦截。
Listener
Listener 是用来监听 web 工程状态改变的一种实现机制
监听整个web工程:
- ServletContextListener
- ServletContextAttributeListener
监听session范围
- HttpSessionListener
- HttpSessionAttributeListener
监听request范围:
- ServletRequestListener
- ServletRequestAttributeListener
listener
为web应用程序定义监听器,监听器用来监听各种事件,比如:Application
和Session
事件,所有的监听器按照相同的方式定义,功能取决去它们各自实现的接口,常用的Web事件接口有如下几个:
ServletContextListener
:用于监听Web Application
的启动和关闭;ServletContextAttributeListener
:用于监听ServletContext
范围(Application)内属性的改变;ServletRequestListener
:用于监听用户的请求;ServletRequestAttributeListener
:用于监听ServletRequest
范围(Request)内属性的改变;HttpSessionListener
:用于监听用户session
的开始和结束;HttpSessionAttributeListener
:用于监听HttpSession
范围(Session)内属性的改变。
<listener>
主要用于监听Web应用事件,其中有两个比较重要的Web应用事件:Application
的启动和停止(starting up or shutting down)和Session
的创建和失效(created or destroyed)。
Application
启动事件发生在应用第一次被Servlet
容器装载和启动的时候;停止事件发生在Web应用停止的时候。Session
创建事件发生在每次一个新的Session
创建的时候,类似地Session
失效事件发生在每次一个Session
失效的时候。
容器注册监听器的方式有三种:
- 利用
@WebListener
注解。 - 在
web.xml
应用部署文件里注册监听器。 - 使用 ServletContext 里定义的
addListener()
方法
其他
RequestDispatcher.forward()转发请求到另一个Servlet
浏览器地址不变
1 | RequestDispatcher rd = servletContext.getRequestDispatcher("/NextServlet"); |
HttpServletResponse.sendRedirect()重定向请求到另一个Servlet
浏览器地址变成新的servlet
1 | httpServletResponse.sendRedirect("/anotherURL"); |
serlet 3.0注解
@WebServlet
@WebInitParam
@WebFilter
@WebListener