servletFilterAndListener

来源:互联网 发布:linq for sql 编辑:程序博客网 时间:2024/06/06 19:10

一、       Filter

Filter,过滤器技术,是servlet2.3新增的功能。过滤器,对指定的过滤对象进行拦截或增强的功能。在servlet中,filter主要用于request和response。在请求进入servlet前,对请求进行预处理,如拦截或修改;当响应从servlet发出后,对响应进行处理。Filter可以作用于servlet,具体通过对request和response的操作实现。开发中通过实现Filter接口创建filter类。

当客户端发起请求到服务器的过程中,首先服务器端会根据用户的url,执行xml中含有url-pattern的相关设置,其中涉及到url的元素的执行顺序从先到后是:listener---》filter---》struts拦截器---》servlet。

(一)            Java_eeapi

javax.servlet
Interface Filter

public interface Filter
过滤器是执行过滤任务的对象,这些任务是针对对某一资源(servlet 或静态内容)的请求或来自某一资源的响应执行的,抑或同时针对这两者执行。
Filter 用 doFilter 方法执行过滤。每个Filter 都有对 FilterConfig 对象的访问权,可从该对象获得其初始化参数以及对它可以使用的 ServletContext 的引用,以便为过滤任务加载所需的资源。

Filter 是在 Web 应用程序的部署描述符中配置的。

已经标识用于此设计的示例是
1) 验证过滤器
2) 日志记录和审计过滤器
3) 图像转换过滤器
4) 数据压缩过滤器
5) 加密过滤器
6) 标记过滤器
7) 触发资源访问事件的过滤器
8) XSL/T 过滤器
9) Mime 类型链过滤器

(二)            Filter接口的Method

void

destroy()
          Called by the web container to indicate to a filter that it is being taken out of service.

 void

doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
          The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.

 void

init(FilterConfig filterConfig)
          Called by the web container to indicate to a filter that it is being placed into service.

(三)            创建和配置过滤器

创建过滤器类

public class MyFilter implements Filter{

   //过滤器销毁方法

   public voiddestroy() {

     

   }

 

   //做过滤的方法,参数中传入了requestresponse对象,可以对requestresponse操作

   public voiddoFilter(ServletRequest arg0, ServletResponsearg1, FilterChainarg2)

         throws IOException, ServletException {

      System.out.println(new Date()+"拦截器发生了作用"); 

   }

 

   //过滤器初始化方法

   public voidinit(FilterConfig arg0)throwsServletException {

     

   } 

}

配置过滤器

  <filter>

      <filter-name>filter1</filter-name>

      <filter-class>com.servlet.test3.MyFilter</filter-class>

  </filter>

  <filter-mapping>

      <filter-name>filter1</filter-name>

      <url-pattern>/haha.txt</url-pattern>

  </filter-mapping>

(四)            调用过滤器的doFilter中的参数FilterChain的doFilter方法为过滤器放行

FilterChain,过滤器链,调用FilterChain对象的doFilter方法,表示在本过滤器执行放行,如果后面还有过滤器,则执行到下个过滤器,如果没有,则根据xml中url-pattern元素的顺序,放行请求进入servlet(当没有使用struts拦截器的情况下)。

多个过滤器的执行顺序是xml中filter-mapping的书写顺序,在前先执行。

执行放行时,请将请求和响应参数传入过滤器链。

javax.servlet
Interface FilterChain

public interface FilterChain
FilterChain 是 servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图。过滤器使用 FilterChain 调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。

 void

doFilter(ServletRequest request,ServletResponse response)
          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.

例子:

   //做过滤的方法,参数中传入了requestresponse对象,可以对requestresponse操作

   public voiddoFilter(ServletRequest request, ServletResponseresponse, FilterChainfilterChain)

         throws IOException, ServletException {

      System.out.println(new Date()+"拦截器发生了作用"); 

      //注意调用过滤器链放行时,将请求和响应参数传入过滤器链

      filterChain.doFilter(request,response);

   }

(五)            Filter的生命周期

创建:服务器启动加载项目的时候,如果有filter,就创建了filter。

销毁:服务器正常关闭或者非正常关闭的时候。

(六)            FilterConfig设置过滤器初始化时的配置信息

javax.servlet
Interface FilterConfig

public interface FilterConfig
servlet 容器使用的过滤器配置对象,该对象在初始化期间将信息传递给过滤器。

 String

getFilterName()
          Returns the filter-name of this filter as defined in the deployment descriptor.

 String

getInitParameter(String name)
          Returns a String containing the value of the named initialization parameter, or null if the parameter does not exist.

 Enumeration

getInitParameterNames()
          Returns the names of the filter's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the filter has no initialization parameters.

 ServletContext

getServletContext()
          Returns a reference to the ServletContext in which the caller is executing.

 

配置过滤器初始化参数

  <filter>

      <filter-name>filter1</filter-name>

      <filter-class>com.servlet.test3.MyFilter</filter-class>

      <init-param>

          <param-name>haha</param-name>

          <param-value>初始化参数的值</param-value>

      </init-param>

      <init-param>

          <param-name>haha2</param-name>

          <param-value>初始化参数的值2</param-value>

      </init-param>

  </filter>

使用FilterConfig对象

   public voidinit(FilterConfig filterConfig)throwsServletException {

      System.out.println("初始化");

      String filterName=filterConfig.getFilterName();

      String initParam=filterConfig.getInitParameter("haha");

      System.out.println(filterName+"--"+initParam);

      //枚举是无序的迭代方法

      Enumeration<String> initParams=filterConfig.getInitParameterNames();

      while(initParams.hasMoreElements()){

         String initparam=initParams.nextElement();

         System.out.println(filterConfig.getInitParameter(initparam));

         }

      filterConfig.getServletContext();

   }

(七)            关于filter的url-pattern的配置

Filter的url配置同servlet,包括三种形式。

1.       全路径匹配。/

2.       通配符匹配。/*

3.       后缀名匹配。*.后缀名(如*.txt)

(八)            关于过滤servlet,由于servlet配置了url,在配置过滤servlet的时候,直接使用servlet-name即可,使用url也可以。

配置filter要过滤的servlet

  <filter>

      <filter-name>filterServlet</filter-name>

      <filter-class>com.servlet.test3.ServletFilter</filter-class>

  </filter>

  <filter-mapping>

      <filter-name>filterServlet</filter-name>

      <servlet-name>servletTest</servlet-name>

  </filter-mapping>

在过滤器中获取此servlet的url带过来的request信息,做业务需要的操作。

   public voiddoFilter(ServletRequest request, ServletResponseresponse, FilterChainchain)throwsIOException, ServletException {

      String username=request.getParameter("username");

      HttpServletResponse res=(HttpServletResponse)response;

      if(username==null){

          res.sendRedirect(request.getServletContext().getContextPath()+"/login.jsp");

      }

      System.out.println("testServlet过滤器");

   }

二、       Listener

Listener用于监听javaweb中的事件,如request,session,context等的变化,并触发响应的事件。Listener基于java观察者模式设计。Servlet2.5提供了8种listener。Listener通过这8种接口实现相应的监听功能。8种接口根据功能分为3类。

Listener类需要在web.xml中配置才可以生效。

(一)            监听session,request,context的创建和销毁

1.       HttpSessionListener

javax.servlet.http
Interface HttpSessionListener

All Superinterfaces:

EventListener

public interface HttpSessionListener

extends EventListener

Implements:java.util.EventListener
对 Web 应用程序中活动会话列表的更改将通知此接口的实现。要接收通知事件,必须在 Web 应用程序的部署描述符中配置实现类。

 void

sessionCreated(HttpSessionEvent se)
          Notification that a session was created.

 void

sessionDestroyed(HttpSessionEvent se)
          Notification that a session is about to be invalidated.

2.       ServletContextListener

javax.servlet
Interface ServletContextListener

All Superinterfaces:

EventListener

public interface ServletContextListener

extends EventListener

Implements:java.util.EventListener
此接口的实现接收有关其所属 Web 应用程序的 servlet 上下文更改的通知。要接收通知事件,必须在 Web 应用程序的部署描述符中配置实现类。

 void

contextDestroyed(ServletContextEvent sce)
          Notification that the servlet context is about to be shut down.

 void

contextInitialized(ServletContextEvent sce)
          Notification that the web application initialization process is starting.

3.       ServletRequestListener

javax.servlet
Interface ServletRequestListener

All Superinterfaces:

EventListener

public interface ServletRequestListener

extends EventListener

Implements:java.util.EventListener
ServletRequestListener 可由想要在请求进入和超出 Web组件范围时获得通知的开发人员实现。当请求即将进入每个 Web 应用程序中的第一个 servlet 或过滤器时,该请求将被定义为进入范围,当它退出链中的最后一个servlet 或第一个过滤器时,它将被定义为超出范围。

 void

requestDestroyed(ServletRequestEvent sre)
          The request is about to go out of scope of the web application.

 void

requestInitialized(ServletRequestEvent sre)
          The request is about to come into scope of the web application.

例子:

public class Listener1 implementsServletRequestListener,ServletContextListener,HttpSessionListener{

   public voidsessionCreated(HttpSessionEvent se) {

      HttpSession session=se.getSession();

      System.out.println("创建一个session"+session.getId());

   }

   public voidsessionDestroyed(HttpSessionEvent se) {

      HttpSession session=se.getSession();

      System.out.println(session.getId()+"销毁了");

   }

   public voidcontextDestroyed(ServletContextEvent ce) {

      ServletContext context=ce.getServletContext();

      System.out.println("清除一个"+context);

   }

   public voidcontextInitialized(ServletContextEvent ce) {

      ServletContext context=ce.getServletContext();

      System.out.println("新建一个"+context);

   }

   public voidrequestDestroyed(ServletRequestEvent re) {

      ServletRequest request=re.getServletRequest();

      System.out.println("结束一个"+request);

   }

   public voidrequestInitialized(ServletRequestEvent re) {

      ServletRequest request=re.getServletRequest();

      System.out.println("发起一个"+request);

   }

}

  <listener>

      <listener-class>com.servlet.test4.Listener1</listener-class>

  </listener>

4.       利用ServletContext的随项目作用域的特征设置定时输出

   public voidcontextInitialized(ServletContextEvent ce) {

      ServletContext context=ce.getServletContext();

      System.out.println("新建一个"+context);

      Timer timer=new Timer();

      timer.schedule(newTimerTask() {

         public void run() {

            System.out.println(new Date());

         }

      },0,1000);

   }

(二)            监听session,request,context的属性值的变化

1.       HttpSessionAttributeListener

javax.servlet.http
Interface HttpSessionAttributeListener

All Superinterfaces:

EventListener

public interface HttpSessionAttributeListener

extends EventListener

Implements:java.util.EventListener
为了获取此 Web 应用程序内会话属性列表更改的通知,可实现此侦听器接口。

void

attributeAdded(HttpSessionBindingEvent se)
          Notification that an attribute has been added to a session.

 void

attributeRemoved(HttpSessionBindingEvent se)
          Notification that an attribute has been removed from a session.

 void

attributeReplaced(HttpSessionBindingEvent se)
          Notification that an attribute has been replaced in a session.

2.       ServletContextAttributeListener

javax.servlet
Interface ServletContextAttributeListener

All Superinterfaces: EventListener

public interface ServletContextAttributeListener

extends EventListener

Implements:java.util.EventListener
此接口的实现接收 Web 应用程序的 servlet 上下文中的属性列表更改通知。要接收通知事件,必须在 Web 应用程序的部署描述符中配置实现类。

 void

attributeAdded(ServletContextAttributeEvent scab)
          Notification that a new attribute was added to the servlet context.

 void

attributeRemoved(ServletContextAttributeEvent scab)
          Notification that an existing attribute has been removed from the servlet context.

 void

attributeReplaced(ServletContextAttributeEvent scab)
          Notification that an attribute on the servlet context has been replaced.

3.       ServletRequestAttributeListener

javax.servlet
Interface ServletRequestAttributeListener

All Superinterfaces: EventListener

public interface ServletRequestAttributeListener

extends EventListener

Implements:java.util.EventListener
ServletRequestAttributeListener 可由想要在请求属性更改时获得通知的开发人员实现。当请求位于注册了该侦听器的 Web 应用程序范围中时,将生成通知。当请求即将进入每个 Web 应用程序中的第一个 servlet 或过滤器时,该请求将被定义为进入范围,当它退出链中的最后一个servlet 或第一个过滤器时,它将被定义为超出范围。

 void

attributeAdded(ServletRequestAttributeEvent srae)
          Notification that a new attribute was added to the servlet request.

 void

attributeRemoved(ServletRequestAttributeEvent srae)
          Notification that an existing attribute has been removed from the servlet request.

 void

attributeReplaced(ServletRequestAttributeEvent srae)
          Notification that an attribute was replaced on the servlet request.

例子:

public class Listener2 implements HttpSessionAttributeListener{

   public voidattributeAdded(HttpSessionBindingEvent sbe) {

      System.out.println("添加的session的键为:"+sbe.getName()+"值为:"+sbe.getValue());

   }

   public voidattributeRemoved(HttpSessionBindingEvent sbe) {

      System.out.println("移除的session的键为:"+sbe.getName()+"值为:"+sbe.getValue());

   }

   public voidattributeReplaced(HttpSessionBindingEvent sbe) {

      System.out.println("替换的session的键为:"+sbe.getName()+"值为:"+sbe.getValue());

   }

}

(三)            监听session内的对象

1.       HttpSessionBindingListener

javax.servlet.http
Interface HttpSessionBindingListener

All Superinterfaces: EventListener

public interface HttpSessionBindingListener

extends EventListener

Implements:java.util.EventListener


使对象在被绑定到会话或从会话中取消对它的绑定时得到通知。该对象通过 HttpSessionBindingEvent对象得到通知。这可能是 servlet 编程人员显式从会话中取消绑定某个属性的结果(由于会话无效,或者由于会话超时)。

void

valueBound(HttpSessionBindingEvent event)
          Notifies the object that it is being bound to a session and identifies the session.

 void

valueUnbound(HttpSessionBindingEvent event)
          Notifies the object that it is being unbound from a session and identifies the session.

2.       HttpSessionActivationListener

javax.servlet.http
Interface HttpSessionActivationListener

All Superinterfaces: EventListener

public interface HttpSessionActivationListener

extends EventListener

Implements:java.util.EventListener
绑定到会话的对象可以侦听通知它们会话将被钝化和会话将被激活的容器事件。在 VM 之间迁移会话或者保留会话的容器需要通知绑定到实现 HttpSessionActivationListener 的会话的所有属性。

void

sessionDidActivate(HttpSessionEvent se)
          Notification that the session has just been activated.

 void

sessionWillPassivate(HttpSessionEvent se)
          Notification that the session is about to be passivated.

例子:

public class BeanTest implements HttpSessionBindingListener{

   private Stringhaha;

   public voidvalueBound(HttpSessionBindingEvent sbe) {

      System.out.println("javabean绑定到session");

   }

   public voidvalueUnbound(HttpSessionBindingEvent sbe) {

      System.out.println("javabean解绑出session");

   }

}