Servlet、Filter 和Listener 工作原理

Servlet工作原理
一、Servlet生命周期分为三个阶段:
     1、初始化阶段,调用init()方法
     2、响应客户请求阶段,调用service()方法
     3、终止阶段,调用destroy()方法
 
二、Servlet初始化阶段,在下列时刻Servlet容器装载Servlet:
     1、Servlet容器启动时自动装载某些Servlet,这些Servlet在web.xml文件中的<Servlet></Servlet>内添加了如下代码:
          <loadon-startup>1</loadon-startup> 
     2、在Servlet容器启动后,客户首次向Servlet发送请求。
     3、Servlet类文件被更新后,重新装载Servlet。
 
三、Servlet接收和响应客户请求的过程:
     1、首先客户发送一个请求。
     2、Servlet容器会创建特定于这个请求的ServletRequest对象和ServletResponse对象,然后调用Servlet的service()方法对请求进行响应。
     3、service()方法中,对请求的方式进行了匹配,选择调用doGet,doPost等这些方法
     4、在doGet、doPost等方法中调用逻辑层的方法,实现对客户的响应。
 
注:
     在Servlet接口和GenericServlet类中是没有doGet、doPost等等这些方法的,HttpServlet中定义了这些方法,但是都是返回error信息,所以我们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。
     Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest,ServletResponse强转为HttpRequest和HttpResponse。
 
Filter工作原理
     Filter可以使用户修改 request 和response。Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response。换种说法,filter其实是一个servlet chaining”(servlet 链).
     每一个filter从doFilter()方法中得到当前的request及response。在这个方法里,可以进行任何的针对request及 response的操作(包括收集数据、包装数据等)。filter调用chain.doFilter()方法把控制权交给下一个filter。如果一个filter想停止request处理而获得对response的完全的控制,那它可以不调用下 一个filter。
例如:
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
     HttpServletRequest httpServletRequest = (HttpServletRequest)request;
     
     //在servlet被调用之前截获,此时可以检查、修改request头和request数据;
     logger.info( "Intercept Url="+httpServletRequest.getRequestURI());
     long start=System. currentTimeMillis();

     //Causes the next filter in the chain to be invoked, or if the calling filter is the last filter in the chain, causes the resource at the end of the chain to be invoked.
     chain.doFilter(request, response);
     
     //在servlet被调用之后截获,此时可以修改response头和response数据;
     long end=System. currentTimeMillis();
     logger.info(request.getRemoteAddr()+ ": time used :"+(end-start));
     response.getWriter().write( "--@2013 Mr.Shao" );
}
Listener和Event:
     Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,这样就可以给在线人数加1。
   Servlet、Filter都是针对请求的,而listener是针对对象的操作的,如session的创建,session.setAttribute的发生,在这样的事件发生时做一些事情。
     
  在javax.servlet和javax.servlet.http两个包下,能够找到一共8个以Listener结尾的接口以及6个以Event结尾的类,它们共同构成了Servlet的事件处理模型。
1. ServletContextListener接口 
[接口方法] contextInitialized()与 contextDestroyed() 
[接收事件] ServletContextEvent 
[触发场景] 在Container加载Web应用程序时(例如启动 Container之后),会呼叫contextInitialized(),而当容器移除Web应用程序时,会呼叫contextDestroyed ()方法。
 
2. ServletContextAttributeListener 
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved() 
[接收事件] ServletContextAttributeEvent 
[触发场景] 若有对象加入为application(ServletContext)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、attributeRemoved()。
 
3. HttpSessionListener 
[接口方法] sessionCreated()与sessionDestroyed () 
[接收事件] HttpSessionEvent 
[触发场景] 在session (HttpSession)对象建立或被消灭时,会分别呼叫这两个方法。
 
4. HttpSessionAttributeListener 
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved() 
[接收事件] HttpSessionBindingEvent 
[触发场景] 若有对象加入为session(HttpSession)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。
 
5. HttpSessionActivationListener 
[接口方法] sessionDidActivate()与 sessionWillPassivate() 
[接收事件] HttpSessionEvent 
[触发场景] Activate与Passivate是用于置换对象的动作,当session对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透 过对象序列化),所作的动作称之为Passivate,而硬盘或储存器上的session对象重新加载JVM时所采的动作称之为Activate,所以容 易理解的,sessionDidActivate()与 sessionWillPassivate()分别于Activeate后与将Passivate前呼叫。
 
6. ServletRequestListener 
[接口方法] requestInitialized()与 requestDestroyed() 
[接收事件] RequestEvent 
[触发场景] 在request(HttpServletRequest)对象建立或被消灭时,会分别呼叫这两个方法。
 
7. ServletRequestAttributeListener 
[接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved() 
[接收事件] HttpSessionBindingEvent 
[触发场景] 若有对象加入为request(HttpServletRequest)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。
 
8. HttpSessionBindingListener 
[接口方法] valueBound()与valueUnbound() 
[接收事件] HttpSessionBindingEvent 
[触发场景] 实现HttpSessionBindingListener接口的类别,其实例如果被加入至session(HttpSession)对象的属性中,则会 呼叫 valueBound(),如果被从session(HttpSession)对象的属性中移除,则会呼叫valueUnbound(),实现 HttpSessionBindingListener接口的类别不需在web.xml中设定。
原文地址:https://www.cnblogs.com/windlaughing/p/2989052.html