Servlet、Filter 生命周期
Servlet作为JavaEE必须掌握的内容,Struts2通过使用Filter的功能实现了一个MVC的框架。因此掌握这Servlet以及Filter的生命周期显得非常重要。
1. Servlet的生命周期
虽然通过使用IDE工具快速创建了Servlet,但是很多人没有弄明白这个东西到底是怎么什么时候实例化或者销毁的,丢开一阵子后很快就忘记服务器在后台到底做了什么。因此了解Servlet的生命周期非常必要。
Servlet是JavaEE标准下的一个接口,该接口抽象出了以下几个方法:
返回值 | 方法名称 | 作用 |
void |
init(ServletConfig config) |
初始化Servlet类实例 |
ServletConfig |
getServletConfig() |
获取含有初始化参数的Servlet配置文件 |
void |
service(ServletRequest req, ServletResponse res) |
调用Servlet的实例方法 |
void |
getServletInfo() |
获取Servlet的信息,包含版本、作者、版权等 |
void |
destroy() |
销毁Servlet类型内容 |
HttpServlet类基本实现了大部分Servlet接口的内容,目前使用IDE创建一个Servlet基本都是集成HttpServlet进行实现的。
回到Servlet生命周期。当用户发出了一个请求,tomcat这类服务器中间件是如何实例化用户编写的Servlet呢?这要从配置文件说起。
① 当用户在浏览器内输入请求,服务器中间件会根据web.xml去查找需要实例化的Servlet。如下:
<servlet>
<!-- ②根据servletName找到对应的Servlet,这个名称必须和mapping里面的名称一样 -->
<servlet-name>RequestServlet</servlet-name>
<!-- ③找到代码中需要实例化的具体对象位置,实例化对象 -->
<servlet-class>com.scl.controler.RequestServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>RequestServlet</servlet-name>
<!--①中间件匹配url内的链接 -->
<url-pattern>/requestmap</url-pattern>
</servlet-mapping>
Servlet 配置
中间件通过反射查找到对应的类,进行实例化。
② 调用对应servlet类内的init方法。只运行一次init方法
③ 分析请求,servlet实例调用service方法。HttpServlet类把这个方法分成get和post两种请求方式处理相关逻辑。
④ 当服务器中间件被关闭或者web.xml被修改时,服务器中间件会调用servlet实例的destroy方法,对Servlet进行销毁。
package com.scl.controler; import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class RequestServlet extends HttpServlet
{
private static final long serialVersionUID = 1L; @Override
public void init() throws ServletException
{
System.out.println("servlet init!");
} @Override
public void destroy()
{
System.out.println("servlet destory!");
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
System.out.println("do servlet method");
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
} }
RequestServlet 示例代码
在浏览器访问http://localhost:8081/FilterProject/requestmap会得到如下结果
servlet init!
do servlet method
实例代码结果
当关闭服务器中间件时会调用destroy方法,init方法只会调用一次。
2. Filter的生命周期
掌握Servlet以后,再接触基础的Filter类,会发现。这两块内容在web.xml里面的配置基本是一样的!先来看下Filter接口抽象了哪几个方法。
返回值 | 方法名称 | 作用 |
void |
init(FilterConfig filterConfig) |
初始化Filter实例 |
void |
doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
调用Filter过滤内容 |
void |
destroy() |
销毁Filter实例 |
Filter 实例在启动web容器的时候就开始进行初始化,而Servlet实例则是在用户通过浏览器访问程序的时候调用。
① 当web容器(服务器中间件)启动的时候,建立Filter实例,初始化Filter接口。
② 当用户通过浏览器访问站点,Filter过滤用户请求
③ 进行Servlet服务处理
④ 当web容器退出时,servlet实例先销毁,再销毁filter实例
Filter配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <filter>
<!-- ② -->
<filter-name>MyFilter</filter-name>
<!-- ③ -->
<filter-class>com.scl.filter.MyFilter</filter-class>
</filter> <filter>
<filter-name>MyFilter2</filter-name>
<filter-class>com.scl.filter.MyFilter2</filter-class>
</filter>
<!-- 多个Filter,按照mapping里面的配置顺序进行过滤操作 -->
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>MyFilter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <servlet>
<!-- ②根据servletName找到对应的Servlet,这个名称必须和mapping里面的名称一样 -->
<servlet-name>RequestServlet</servlet-name>
<!-- ③找到代码中需要实例化的具体对象位置,实例化对象 -->
<servlet-class>com.scl.controler.RequestServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>RequestServlet</servlet-name>
<!--①中间件匹配url内的链接 -->
<url-pattern>/requestmap</url-pattern>
</servlet-mapping> <welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Filter 配置
Filter 的使用必须通过类去实现Filter接口
package com.scl.filter; import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class MyFilter implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
System.out.println("myFilter init!");
} @Override
public void destroy()
{
System.out.println("myFilter destroy!");
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
System.out.println("filter start");
chain.doFilter(request, response);
System.out.println("filter end");
} }
MyFilter 代码
package com.scl.filter; import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class MyFilter2 implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
System.out.println("myFilter2 init!");
} @Override
public void destroy()
{
System.out.println("myFilter2 destroy!");
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
System.out.println("filter2 start");
chain.doFilter(request, response);
System.out.println("filter2 end");
} }
MyFilter2 代码
访问http://localhost:8080/FilterProject/requestmap 会有以下结果
servlet init!
filter start
filter2 start
do servlet method
filter2 end
filter end
含Filter的servlet运行结果
其中,在web容器运行的时候Filter就已经初始化了,并在控制台输出:
myFilter2 init!
myFilter init!
两个不同的Filter在运行的时候,按照filter-mapping中的顺序先后进行过滤。
关于url-mapping节点内容,有以下解析:
假设当前工程目录为:testmapping。
1 、url的精确匹配。
无论使用什么路径访问站点查找Servlet都是先以精确匹配开始。有 MapServlet 的url-pattern 设置为:/map,同时也有ServletB的url-pattern 设置为/* ; 假设用户输入http://localhost:8081/testmapping/map; 容器会找到MapServlet,并且只匹配MapServlet ,ServletB被放弃。(Filter 不一样,Filter是一个链式过滤,按照filter-mapping的顺序,都匹配上)。servlet会一层一层地查找,
2 、后缀名匹配。
url最后一段包含扩展,容器将会根据扩展选择合适的servlet。如 MapServlet 的url-pattern 设置为:"*.action";则访问http://localhost:8081/testmapping/a/a.action时,会匹配上。注意尽量不要直接使用".action"来指定,这样会报错。
3 、默认servlet。
当前两种方式没法匹配上的时候,如果是静态资源或者JSP文件,则走容器内部的default-servlet匹配。
以上为Servlet及Filter的生命周期总结,如有问题烦请指出纠正。
Servlet、Filter 生命周期的更多相关文章
- Servlet和Filter生命周期
1. 生命周期 1.1. Servlet生命周期 servlet是一个基于java技术的WEB组件,运行在服务器端,我们利用 sevlet可以很轻松的扩展WEB服务器的功能,使它满足特定的应用需要.s ...
- Servlet生命周期 、Filter生命周期、Listering(监听器)总结
Servlet生命周期简述 (1)加载和实例化 当Servlet容器启动或客户端发送一个请求时,Servlet容器会查找内存中是否存在该Servlet实例,若存在,则直接读取该实例响应请求:如果不存在 ...
- JSP Servlet WEB生命周期
[转载] JavaWeb的生命周期是由Servlet容器来控制的总的来说分为三个阶段1.启动阶段:加载web应用相关数据,创建ServletContext对象,对Filter和servlet进行初始化 ...
- servlet的生命周期与运行时的线程模型
第 14 章 生命周期 注意 讲一下servlet的生命周期与运行时的线程模型,对了解servlet的运行原理有所帮助,这样才能避免一些有冲突的设计. 如果你不满足以下任一条件,请继续阅读,否则请跳过 ...
- Servlet/JSP-01 Servlet及其生命周期
一.起步 1.新建一个类继承Servlet接口 public class HelloServlet implements Servlet { @Override public void destroy ...
- Servlet学习(一)——Servlet的生命周期、执行过程、配置
1.什么是Servlet Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是java代码,通过jav ...
- Servlet的生命周期及工作原理
Servlet生命周期分为三个阶段: 1,初始化阶段 调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destroy()方法 Servlet初始化阶段: 在 ...
- Servlet的生命周期
Servlet的生命周期 Servlet的生命周期是由tomcat服务器来控制的. 1 构造方法: 创建servlet对象的时候调用.默认情况下,第一访问servlet就会创建servlet对象只创建 ...
- Servlet的生命周期+实现方式
1.Servlet的生命周期: (1)被创建: 默认情况下,Servlet第一次被访问时,被服务器创建.会调用init()方法. 一个 ...
随机推荐
- Programming Assignment 3: Collinear Points
The problem. Given a set of N distinct points in the plane, draw every (maximal) line segment that c ...
- js new date详解
创建一个日期对象: var objDate=new Date([arguments list]); var ini_date=new Date(2014,7,0); //是代表7月最后一天 ,也就是2 ...
- 解决iphone横屏时字体变大问题或者内容大小不一样等
在样式表中增加: @media screen and (max-device-width: 320px){body{-webkit-text-size-adjust:none}} @media scr ...
- 第三方框架FMDB
摘要:关键点:创建.插入.查询.数据格式化 第三方框架FMDB -------------------------------------------------------------------- ...
- 获取json对象的id或者根据name获取id
--用json的时候,知道id获取对应的name或者相反根据name获取id --内核代码 <script> var products=[{ID:1,Name:"a", ...
- yii2.0的gii生成代码bug
自动生成代码真的很好用,能减少很多基础代码的编写,如果这些基础代码一个个手动去敲,即枯燥乏味,还容易出错(话说人类真的不适合做单调重复的工作),yii框架的gii自动生成代码工具就能减少很多工作量.前 ...
- linux安装gcc的一些问题。
输入命令:yum install gcc 提示: Loaded plugins: fastestmirror, langpacksExisting lock /var/run/yum.pid: ano ...
- controller,link,compile不同
测试案例 .directive('testDirective', function() { return { restrict: 'E', template: '<p>Hello {{nu ...
- [改善Java代码]集合运算时使用更优雅的方式
在初中代数中,我们经常会求两个集合的并集.交集.差集等,在Java中也存在着此 类运算,那如何实现呢? 一提到此类集合操作,大部分的实现者都会说:对两个集合进行遍历,即可求出结果.是的,遍历可以实现并 ...
- 关于在Eclipse中构建patch开发环境
git仓库中不能添加空文件夹. 至于为什么git 仓库中不能添加空文件夹,我没有找到具体的原因. 在V2EX上有人说: 我猜是因为git的内部实现,即只对文件做快照决定的吧,另一方面空文件夹确实对源代 ...