`
qtlkw
  • 浏览: 307160 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Servlet、Filter 和 Listener 调用顺序、生命周期的实验分析

    博客分类:
  • JAVA
 
阅读更多
通过实验来验证Servlet、Filter和Listener的调用顺序、生命周期。

1、示例项目

目录结构:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <listener>
        <listener-class>edu.shao.webapp.sample.listener.MyServletRequestListener</listener-class>
    </listener>
    <listener>
        <listener-class>edu.shao.webapp.sample.listener.MyServletContextListener</listener-class>
    </listener>
    
    <filter>
        <filter-name>ResponseFilter</filter-name>
        <filter-class>edu.shao.webapp.sample.filter.ResponseFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ResponseFilter</filter-name>
        <servlet-name>hello_world</servlet-name>
    </filter-mapping>
    
    <filter>
        <filter-name>LogFilter</filter-name>
        <filter-class>edu.shao.webapp.sample.filter.LogFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LogFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <servlet>
        <servlet-name>hello_world</servlet-name>
        <servlet-class>edu.shao.webapp.sample.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello_world</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>early_servlet</servlet-name>
        <servlet-class>edu.shao.webapp.sample.EarlyServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>early_servlet</servlet-name>
        <url-pattern>/early</url-pattern>
    </servlet-mapping>
</web-app>


MyServletContextListener类:

public class MyServletContextListener implements ServletContextListener {
    public static Logger logger=LogManager.getLogger(MyServletContextListener.class);

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        logger.info("Servlet context initialized.");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        logger.info("Servlet context destroyed.");
    }
}

MyServletRequestListener类:

public class MyServletRequestListener implements ServletRequestListener {
    public static Logger logger=LogManager.getLogger(MyServletRequestListener.class);

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        logger.info("Servlet request destroyed.");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        logger.info("Servlet request initialized.");
    }
}

ResponseFilter类:

public class ResponseFilter implements Filter {
    public static Logger logger=LogManager.getLogger(ResponseFilter.class);
    
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        logger.info("Response Filter initialized.");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        chain.doFilter(req, res);
        res.getWriter().write("--@2013 Mr.Shao");
    }

    @Override
    public void destroy() {
        logger.info("Response Filter destroyed.");
    }
}


LogFilter类:

public class LogFilter implements Filter {
    public static Logger logger=LogManager.getLogger(LogFilter.class);
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("Log Filter initialized.");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        logger.info("Intercept Url="+httpServletRequest.getRequestURI());
        
        long start=System.currentTimeMillis();
        chain.doFilter(request, response);
        long end=System.currentTimeMillis();
        logger.info(request.getRemoteAddr()+": time used :"+(end-start));
    }

    @Override
    public void destroy() {
        logger.info("Log Filter destroyed.");
    }
}


HelloServlet类:

public class HelloServlet extends HttpServlet {
    public static Logger logger=LogManager.getLogger(HelloServlet.class);

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        logger.debug("Do Get Method.");
        resp.getWriter().print("Hello World");
    }
    
    public void init() throws ServletException {
        logger.debug("Hello Servlet initialized.");
    }
    
    public void destroy() {
        logger.debug("Hello Servlet destroyed.");
    }
}


EarlyServlet类:

public class EarlyServlet extends HttpServlet {
    public static Logger logger=LogManager.getLogger(EarlyServlet.class);

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        logger.debug("Do Get Method.");
        resp.getWriter().print("This message is created in EarlyServlet");
    }
    
    public void init() throws ServletException {
        logger.debug("Early Servlet initialized.");
    }
    
    public void destroy() {
        logger.debug("Early Servlet destroyed.");
    }
}


2、测试操作
1、启动tomcat服务
2、访问http://10.130.29.198:8080/test/  (访问index.html)
3、访问http://10.130.29.198:8080/test/hello
4、访问http://10.130.29.198:8080/test/early
5、停止tomcat服务

3、Log输出

(根据输出的时间,人为的把日志分割开来,便于观察)
1、启动tomcat服务
2013-03-28 18:14:08,954 INFO  - [MyServletContextListener - contextInitialized] Servlet context initialized.
2013-03-28 18:14:08,983 INFO  - [LogFilter - init] Log Filter initialized.
2013-03-28 18:14:08,984 INFO  - [ResponseFilter - init] Response Filter initialized.
2013-03-28 18:14:08,991 DEBUG - [EarlyServlet - init] Early Servlet initialized.
2、访问http://10.130.29.198:8080/test/  (访问index.html)
2013-03-28 18:14:18,946 INFO  - [MyServletRequestListener - requestInitialized] Servlet request initialized.
2013-03-28 18:14:18,957 INFO  - [LogFilter - doFilter] Intercept Url=/test/
2013-03-28 18:14:18,962 INFO  - [LogFilter - doFilter] 10.130.29.198: time used :4
2013-03-28 18:14:18,963 INFO  - [MyServletRequestListener - requestDestroyed] Servlet request destroyed.
3、访问http://10.130.29.198:8080/test/hello
2013-03-28 18:14:34,713 INFO  - [MyServletRequestListener - requestInitialized] Servlet request initialized.
2013-03-28 18:14:34,714 DEBUG - [HelloServlet - init] Hello Servlet initialized.
2013-03-28 18:14:34,716 INFO  - [LogFilter - doFilter] Intercept Url=/test/hello
2013-03-28 18:14:34,717 DEBUG - [HelloServlet - doGet] Do Get Method.
2013-03-28 18:14:34,720 INFO  - [LogFilter - doFilter] 10.130.29.198: time used :3
2013-03-28 18:14:34,721 INFO  - [MyServletRequestListener - requestDestroyed] Servlet request destroyed.
4、访问http://10.130.29.198:8080/test/early
2013-03-28 18:14:42,124 INFO  - [MyServletRequestListener - requestInitialized] Servlet request initialized.
2013-03-28 18:14:42,127 INFO  - [LogFilter - doFilter] Intercept Url=/test/early
2013-03-28 18:14:42,128 DEBUG - [EarlyServlet - doGet] Do Get Method.
2013-03-28 18:14:42,129 INFO  - [LogFilter - doFilter] 10.130.29.198: time used :1
2013-03-28 18:14:42,130 INFO  - [MyServletRequestListener - requestDestroyed] Servlet request destroyed.
5、停止tomcat服务
2013-03-28 18:14:49,723 DEBUG - [EarlyServlet - destroy] Early Servlet destroyed.
2013-03-28 18:14:49,724 DEBUG - [HelloServlet - destroy] Hello Servlet destroyed.
2013-03-28 18:14:49,724 INFO  - [LogFilter - destroy] Log Filter destroyed.
2013-03-28 18:14:49,726 INFO  - [ResponseFilter - destroy] Response Filter destroyed.
2013-03-28 18:14:49,727 INFO  - [MyServletContextListener - contextDestroyed] Servlet context destroyed.

4、分析

1、在Tomcat(Servlet容器)启动时,Listener和 ServletContext 最先初始化。因为最先输出的日志是:
  2013-03-28 18:14:08,954 INFO - [MyServletContextListener - contextInitialized] Servlet context initialized.
2、Filter在Tomcat(Servlet容器)启动时初始化。
  2013-03-28 18:14:08,983 INFO - [LogFilter - init] Log Filter initialized.
  2013-03-28 18:14:08,984 INFO - [ResponseFilter - init] Response Filter initialized.
3、如果某个Servlet配置了 <load-on-startup >1 </load-on-startup >,该Servlet也是在Tomcat(Servlet容器)启动时初始化。例如 EarlyServlet:
  2013-03-28 18:14:08,991 DEBUG - [EarlyServlet - init] Early Servlet initialized.
4、每次请求, Request都会被初始化,响应请求后,请求被销毁:
  2013-03-28 18:14:18,946 INFO - [MyServletRequestListener - requestInitialized] Servlet request initialized.
  ......
  2013-03-28 18:14:18,963 INFO - [MyServletRequestListener - requestDestroyed] Servlet request destroyed.
5、Filter在请求执行前后,都能做一些处理。
  (1)请求执行前:2013-03-28 18:14:34,716 INFO - [LogFilter - doFilter] Intercept Url=/test/hello
  (2)执行请求:2013-03-28 18:14:34,717 DEBUG - [HelloServlet - doGet] Do Get Method.
  (3)请求执行后:2013-03-28 18:14:34,720 INFO - [LogFilter - doFilter] 10.130.29.198: time used :3
6、如果Servlet没有配置<load-on-startup >1 </load-on-startup >,该Servlet不会在Tomcat启动时初始化,而是在请求到来时初始化。例如 HelloServlet:
  2013-03-28 18:14:34,714 DEBUG - [HelloServlet - init] Hello Servlet initialized.
7、Servlet初始化后,将不会随着请求的结束而注销。HelloServlet 初始化,当请求结束了,HelloServlet 的 destroy() 没有被调用。
8、关闭Tomcat时,Servlet、Filter、Listener依次被注销。
分享到:
评论
1 楼 wst0350 2016-04-12  
点赞,有空深入讲解下原理

相关推荐

    servlet+filter+listener 详解

    Servlet 的生命周期通过 javax.servlet.Servlet 接口中的 init()、service() 和 destroy() 方法来表示。 * 加载和实例化 * 初始化,调用 init() * 请求处理,调用 service() * 结束,销毁实例,调用 destroy() ...

    web服务器三大组件servlet、Filter、Listener——浅浅笔记

    Web服务器中的三大组件,即Servlet、Filter和Listener,是构建动态Web应用程序的关键元素。这些组件都是基于Java的,主要用于增强和扩展Web服务器的功能。 Servlet是Java中用于处理HTTP请求的核心组件,它是动态...

    Filter和Listener

    在Java Web开发中,Filter(过滤器)和Listener(监听器)是两个重要的概念,它们在Web应用程序的生命周期管理和请求处理流程中扮演着关键角色。理解它们的区别和应用场景对于构建高效、灵活的Web应用至关重要。 ##...

    servlet基础与servlet容器模型

    Servlet的主要生命周期方法包括:`init()`(初始化)、`service()`(处理请求)和`destroy()`(销毁)。`init()`方法在Servlet实例化后首次调用,用于初始化Servlet;`service()`方法处理每个到来的请求;而`destroy...

    Servlet 的生命周期

    在实际开发中,我们还会接触到`Filter`和`Listener`等概念,它们是Servlet容器中的重要组件,可以拦截请求、监听事件,进一步增强和管理Servlet的行为。理解Servlet生命周期以及相关API的使用,是成为一名熟练的Java...

    servlet+filter+lisenter 例子

    在Java Web开发中,Servlet、Filter和Listener是三个核心组件,它们构成了Web应用程序的基础架构,用于处理HTTP请求、实现业务逻辑以及管理应用的生命周期。现在,让我们深入探讨这些概念及其在实际开发中的应用。 ...

    day19_Filter&Listener教案1

    【Filter 概述】 ...了解并掌握Filter的配置、生命周期和执行流程对于提升Web应用程序的可扩展性和安全性至关重要。同时,监听器(Listener)作为补充,可以帮助开发者更好地管理和监控应用状态。

    过滤器filter和监听器listener的应用总结

    2. **生命周期**:Filter有初始化(init)、执行(doFilter)和销毁(destroy)三个关键方法。在Web应用启动时,每个Filter的`init()`方法被调用一次;每次请求匹配到Filter时,`doFilter()`方法会被调用;Web应用...

    实验2Servlet基础实验

    在本实验中,我们将深入探讨JavaWeb开发中的核心组件——Servlet。...这个实验不仅涵盖了Servlet的基本操作,还可能涉及到JSP、Filter和Listener等相关的JavaWeb技术,这些都是构建高效、可维护的Web应用的关键组件。

    web.xml中servlet, bean, filter, listenr 加载顺序_动力节点Java学院整理

    通过对web.xml文件的分析,我们可以得出结论:Listener的加载顺序在最前面,接着是Filter,然后是Servlet,最后是Bean。这意味着,如果过滤器中要使用到Bean,可以将Spring的加载改成Listener的方式,以确保Bean的...

    servlet3.0 规范pdf 包含javadoc

    6. **Filter链的改进**:现在,Filter可以通过`doFilter(ServletRequest, ServletResponse, FilterChain)`方法中的`FilterChain`对象按顺序调用下一个Filter,允许更灵活的过滤器配置。 7. **WebSocket支持**:尽管...

    servlet api说明文档

    10. **动态注册和注解**:从Servlet 3.0版本开始,可以通过注解(如`@WebServlet`、`@WebFilter`、`@WebListener`)在类级别直接声明Servlet、Filter和Listener,无需在web.xml中配置。 11. **异步处理**:Servlet ...

    Tomcat(二) Tomcat实现:Servlet与web.xml介绍 以及 源码分析Tomcat实现细节1

    - **Servlet容器的实现**:Tomcat的Servlet容器负责管理Servlet的生命周期,包括加载、初始化、服务和销毁。 深入理解这些概念和原理对于开发和优化基于Tomcat的Web应用至关重要。通过阅读《Servlet3.1规范(最终...

    servlet3.0

    提供了`init()`、`destroy()`之外的新的生命周期回调方法,如`@PostConstruct`和`@PreDestroy`,这些注解的方法会在对象创建后和销毁前被调用,便于进行资源的初始化和清理。 10. **动态注册**: 开发者可以在...

    实验2 Servlet和会话实验源代码.rar

    学习Servlet和会话管理是Java Web开发的基础,进一步可以深入学习MVC框架(如Spring MVC)、过滤器(Filter)和监听器(Listener),以及更高级的会话管理策略,如分布式会话、会话超时和安全性控制。 总之,"实验...

    jakarta-servletapi-4-src.zip servlet源码

    在Servlet的生命周期中,`init()`方法在Servlet实例化后首次被调用,用于初始化Servlet;`service()`方法处理客户端请求;而`destroy()`方法在Servlet销毁前执行,用于释放资源。源码中,我们可以看到这些方法的具体...

    servlet-api 源码

    它实现了`service()`方法,并提供了生命周期方法如`init()`和`destroy()`,用于初始化和销毁Servlet实例。 三、HttpServlet `HttpServlet`是`GenericServlet`的子类,专门针对HTTP协议进行了优化。它扩展了`...

    Servlet中文API文档 servlet

    4. **Servlet生命周期**:Servlet的生命周期包括加载和初始化、服务、销毁三个阶段。Servlet容器(如Tomcat)会在第一次请求时加载Servlet并调用init()方法,之后每次请求都会调用service()方法,最后在容器关闭或...

    Servlet技术入门教学

    它们负责管理Servlet的生命周期,解析请求,调用Servlet的方法,并将响应返回给客户端。 6. **Servlet的线程安全问题**: 由于Servlet实例默认是多线程的,因此在编写Servlet时需要注意线程安全问题。例如,避免在...

    Web_5_Listener和Filter1

    监听器是指Servlet API中的一个Listener接口,它允许开发人员监听Servlet的生命周期事件,例如ServletContextListener、ServletRequestListener、HttpSessionListener等。监听器可以实现一些特殊的功能,例如实现...

Global site tag (gtag.js) - Google Analytics