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 生命周期的更多相关文章

  1. Servlet和Filter生命周期

    1. 生命周期 1.1. Servlet生命周期 servlet是一个基于java技术的WEB组件,运行在服务器端,我们利用 sevlet可以很轻松的扩展WEB服务器的功能,使它满足特定的应用需要.s ...

  2. Servlet生命周期 、Filter生命周期、Listering(监听器)总结

    Servlet生命周期简述 (1)加载和实例化 当Servlet容器启动或客户端发送一个请求时,Servlet容器会查找内存中是否存在该Servlet实例,若存在,则直接读取该实例响应请求:如果不存在 ...

  3. JSP Servlet WEB生命周期

    [转载] JavaWeb的生命周期是由Servlet容器来控制的总的来说分为三个阶段1.启动阶段:加载web应用相关数据,创建ServletContext对象,对Filter和servlet进行初始化 ...

  4. servlet的生命周期与运行时的线程模型

    第 14 章 生命周期 注意 讲一下servlet的生命周期与运行时的线程模型,对了解servlet的运行原理有所帮助,这样才能避免一些有冲突的设计. 如果你不满足以下任一条件,请继续阅读,否则请跳过 ...

  5. Servlet/JSP-01 Servlet及其生命周期

    一.起步 1.新建一个类继承Servlet接口 public class HelloServlet implements Servlet { @Override public void destroy ...

  6. Servlet学习(一)——Servlet的生命周期、执行过程、配置

    1.什么是Servlet Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是java代码,通过jav ...

  7. Servlet的生命周期及工作原理

    Servlet生命周期分为三个阶段: 1,初始化阶段  调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destroy()方法 Servlet初始化阶段: 在 ...

  8. Servlet的生命周期

    Servlet的生命周期 Servlet的生命周期是由tomcat服务器来控制的. 1 构造方法: 创建servlet对象的时候调用.默认情况下,第一访问servlet就会创建servlet对象只创建 ...

  9. Servlet的生命周期+实现方式

    1.Servlet的生命周期:        (1)被创建:            默认情况下,Servlet第一次被访问时,被服务器创建.会调用init()方法.                一个 ...

随机推荐

  1. mongo批量更新

    update的如果要批量更新是无能为力的,如果有多条匹配的结果,但结果是只能更新一条. 用bulk来进行处理 var bulk = db.HIS_ALARM.initializeUnorderedBu ...

  2. 粒子系统1:简介&工具使用

    直接使用工具来感受一下粒子系统的强大威力吧. 网络上有很多粒子编辑器,大多数都是收费的.magicalsoft提供了一个免费的粒子编辑器(该工具目前只有mac版本),界面如下: 我们将针对这个编辑器来 ...

  3. C++标准转换运算符const_cast

    前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述.C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor ...

  4. 描述cookie,sessionstroage,localstrage的区别

    HTML5 提供了两种在客户端存储数据的新方法(Web Storage): localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 ...

  5. spring源码分析之spring-jms模块详解

    0 概述 spring提供了一个jms集成框架,这个框架如spring 集成jdbc api一样,简化了jms api的使用. jms可以简单的分成两个功能区,消息的生产和消息的消费.JmsTempl ...

  6. Gradle Goodness: Set Java Compiler Encoding--转载

    原文地址:http://java.dzone.com/articles/gradle-goodness-set-java If we want to set an explicit encoding ...

  7. Java设计模式11:常用设计模式之代理模式(结构型模式)

    1. Java之代理模式(Proxy Pattern) (1)概述: 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象 ...

  8. Oracle创建表空间、新建用户和授权

    通过pl/sql以sys用户登录到Oracle数据库上,然后执行菜单:文件/新建/命令窗口 ,打开一个命令窗口然后在该命令窗口中执行脚本创建和删除表空间 . 1.创建表空间 格式:  create t ...

  9. PhotoShop—剪贴蒙版

    工作中发现剪贴蒙版方便好用,所以简单分享下~ 一.剪贴蒙版有什么作用 1.文字上色 2.裁剪图片 3.添加背景 等 二.剪贴蒙版怎么使用 1.新建层,打上字如图 2.文字上面再建层加上效果如渐变 3. ...

  10. C#中参数传递【转】

    转自[Learning hard] 建议参考 『第十一回:参数之惑---传递的艺术(上)』 一.引言 对于一些初学者(包括工作几年的人在内)来说,有时候对于方法之间的参数传递的问题感觉比较困惑的,因为 ...