Java中的拦截器、过滤器、监听器用法详解

本文实例讲述了Java中的拦截器、过滤器、监听器用法。分享给大家供大家参考,具体如下:

一、拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方 法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

1.Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现。

2.拦截器栈(Interceptor Stack)Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

package com.lzw.struts.Interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class MyInterceptor extends MethodFilterInterceptor {
  private static final long serialVersionUID = -6410044851077844880L;
  /**
   * 在struts.xml <param name="lzw">struts</param>
   */
  private String lzw;
  public String getLzw() {
    return lzw;
  }
  public void setLzw(String lzw) {
    this.lzw = lzw;
  }
  @Override
  public void destroy() {
    System.out.println("destroy!");
  }
  @Override
  public void init() {
    System.out.println("init!");
  }
  @Override
  protected String doIntercept(ActionInvocation invocation) throws Exception {
    System.out.println("MyInterceptor-start");
    System.out.println(lzw);
    String result = invocation.invoke();
    System.out.println("MyInterceptor-end");
    return result;
  }
}
package com.lzw.struts.Interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class FirstInterceptor extends MethodFilterInterceptor {
  private static final long serialVersionUID = 1L;
  @Override
  protected String doIntercept(ActionInvocation invocation) throws Exception {
    System.out.println("FirstInterceptor-Start");
    String result = invocation.invoke();
    System.out.println("FirstInterceptor-End");
    return result;
  }
}

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
  <!--开发模式开关,本地可以设为true帮助调试问题,部署到服务器上设为false-->
  <constant name="struts.devMode" value="false"/>
  <!--务必配上该属性,否则会导致AOP注入异常-->
  <constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>
  <constant name="struts.i18n.encoding" value="UTF-8" />
  <constant name="struts.multipart.maxSize" value="1000000000"/>
  <package name="strutsLzw" extends="struts-default" namespace="/">
    <interceptors>
      <interceptor name="lzwInterceptorA" class="com.lzw.struts.Interceptor.MyInterceptor">
        <param name="lzw">struts</param>
      </interceptor>
      <interceptor name="lzwInterceptorB" class="com.lzw.struts.Interceptor.FirstInterceptor">
      </interceptor>
      <!-- 定义自己的拦截器栈 -->
      <interceptor-stack name="myStack">
        <interceptor-ref name="lzwInterceptorA"></interceptor-ref>
        <interceptor-ref name="lzwInterceptorB"></interceptor-ref>
        <interceptor-ref name="defaultStack"></interceptor-ref>
      </interceptor-stack>
    </interceptors>
    <!-- 全局的每个action都会拦截 -->
    <default-interceptor-ref name="myStack"></default-interceptor-ref>
    <!-- 增加method="lzwTest" 执行LoginAction的lzwTest方法 否则执行execute方法 -->
    <action name="login" class="com.lzw.struts.action.LoginAction" method="lzwTest">
      <result name="success">/result.jsp</result>
      <result name="failer">/error.jsp</result>
      <result name="input">/error.jsp</result>
    </action>
  </package>
</struts>

或者:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
  <package name="strutsLzw" extends="struts-default">
    <interceptors>
      <interceptor name="lzwInterceptor" class="com.lzw.struts.Interceptor.MyInterceptor">
        <param name="lzw">struts</param>
      </interceptor>
    </interceptors>
    <!-- 增加method="lzwTest" 执行LoginAction的lzwTest方法 否则执行execute方法 -->
    <action name="login" class="com.lzw.struts.action.LoginAction" method="lzwTest">
      <result name="success">/result.jsp</result>
      <result name="failer">/error.jsp</result>
      <result name="input">/error.jsp</result>
      <interceptor-ref name="lzwInterceptor"></interceptor-ref>
      <!--增加defaultStack 否则 验证拦截器不执行,也就是 validate 方法不执行-->
      <interceptor-ref name="defaultStack"></interceptor-ref>
    </action>
  </package>
</struts>

web.xml中加入:

<filter>
   <filter-name>struts2</filter-name>
   <!-- 已经过时了<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> -->
   <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
   <init-param>
    <param-name>actionPackages</param-name>
    <param-value>com.lzw.struts.action</param-value>
   </init-param>
 </filter>
 <filter-mapping>
   <filter-name>struts2</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>
package com.lzw.struts.action;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
  private static final long serialVersionUID = 1L;
  private String username;
  private String password;
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  @Override
  public String execute() throws Exception {
    System.out.println("=====execute=====");
    if ("hello".equals(this.getUsername().trim()) && "world".equals(this.getPassword().trim())) {
      return "success";
    } else {
      this.addFieldError("username", "username or password error");
      return "failer";
    }
  }
  @Override
  public void validate() {
    System.out.println("=====validate=====");
    if (null == this.getUsername() || "".equals(this.getUsername().trim())) {
      this.addFieldError("username", "username required");
    }
    if (null == this.getPassword() || "".equals(this.getPassword().trim())) {
      this.addFieldError("password", "password required");
    }
  }
  public String lzwTest() {
    System.out.println("======Test====");
    return SUCCESS;
  }
}
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <base href="<%=basePath%>" rel="external nofollow" >
  <title>My JSP 'login.jsp' starting page</title>
  <meta http-equiv="pragma" content="no-cache">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="expires" content="0">
  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  <meta http-equiv="description" content="This is my page">
  <!--
  <link rel="stylesheet" type="text/css" href="styles.css" rel="external nofollow" >
  -->
 </head>
 <body>
   <form action="login.action" method="post">
     username:<input type="text" name="username"><br>
     password:<input type="password" name="password"><br>
   <input type="submit" value="submit">
   </form>
 </body>
</html>

控制台结果:

init!
2013-10-31 13:51:15 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-apr-8080"]
2013-10-31 13:51:15 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-apr-8009"]
2013-10-31 13:51:15 org.apache.catalina.startup.Catalina start
信息: Server startup in 1699 ms
MyInterceptor-start
struts
FirstInterceptor-Start
=====validate=====
======Test====
FirstInterceptor-End
MyInterceptor-end

二、过滤器:是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符。主要为了减轻服务器负载,减少压力

package com.lzw.filter.demo;
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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class UserAccessFilter implements Filter{
  @Override
  public void destroy() {
    System.out.println("destroy!");
  }
  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)res;
    HttpSession session = request.getSession();
    if(session.getAttribute("user")== null && request.getRequestURI().indexOf("login.jsp")==-1 ){
      response.sendRedirect("login.jsp");
      return ;
    }
    chain.doFilter(req, res);
  }
  @Override
  public void init(FilterConfig config) throws ServletException {
    //ApplicationFilterConfig[name=UserFilter, filterClass=com.lzw.filter.demo.UserAccessFilter]
    System.out.println(config.toString());
  }
}

web.xml 中加入:

<filter>
    <filter-name>UserFilter</filter-name>
    <filter-class>com.lzw.filter.demo.UserAccessFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>UserFilter</filter-name>
    <url-pattern>/jsp/*</url-pattern>
</filter-mapping>

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。

个人认为过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);

过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;

Action处理完成返回后,拦截器还可以做其他过程,再向上返回到过滤器的后续操作。

三、监听器:Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。

主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。

package com.lzw.filter.demo;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class InitDataListener implements ServletContextListener {
  private static ServletContext servletContext;
  public static ServletContext getServletContext() {
    return servletContext;
  }
  @Override
  public void contextInitialized(ServletContextEvent contextEvent) {
    servletContext = contextEvent.getServletContext();
    //final ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
    System.out.println("服务器启动完毕!");
    System.out.println(servletContext);
  }
  @Override
  public void contextDestroyed(ServletContextEvent sce) {}
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>
  <listener>
    <listener-class>com.lzw.filter.demo.InitDataListener</listener-class>
  </listener>
</web-app>

控制台结果:

信息: Starting service Catalina
2013-10-31 15:13:55 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.42
服务器启动完毕!
org.apache.catalina.core.ApplicationContextFacade@7966340c
2013-10-31 15:13:56 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-apr-8080"]
2013-10-31 15:13:56 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-apr-8009"]
2013-10-31 15:13:56 org.apache.catalina.startup.Catalina start
信息: Server startup in 402 ms

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • servlet监听器的学习使用(三)

    本文为大家分享了servlet监听器的具体学习内容,供大家参考,具体内容如下 1.什么是servlet监听器? servlet监听器也叫web监听器.是servlet中一种特殊类.能够帮助开发者监听web应用中的特定事件.比如ServletContext,ServletSession,ServletRequest的创建和销毁,变量的创建和销毁等. 2 监听器常用的用途 通常使用Web监听器做以下的内容: 统计在线人数,利用HttpSessionLisener 加载初始化信息:利用ServletC

  • 浅谈java监听器的作用

    监听器是JAVA Web开发中很重要的内容,其中涉及到的知识,可以参考下面导图: Web监听器 1 什么是web监听器? web监听器是一种Servlet中的特殊的类,它们能帮助开发者监听web中的特定事件,比如ServletContext,HttpSession,ServletRequest的创建和销毁:变量的创建.销毁和修改等.可以在某些动作前后增加处理,实现监控. 2 监听器常用的用途 通常使用Web监听器做以下的内容: 统计在线人数,利用HttpSessionLisener 加载初始化信

  • 利用java监听器实现在线人数统计

    1.在工程中创建监听类SessionListener 并且实现HttpSessionListener接口,代码如下 import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class SessionListener implements HttpSessionListener { private static int count = 0; public vo

  • java web监听器统计在线用户及人数

    在线用户使用HttpSessionListener监听器统计  每当一个session会话建立  在线用户人数+1 每当一个session会话销毁 在线用户人数-1 使用ServletRequestListener监听器统计用户信息 每当一个request建立  将当前用户放入集合 每当session会话销毁  将当前用户移出集合 我使用的是Servlet3.0  监听器直接使用注解@webListener即可 不用在web.xml中布局 在web.xml中配置session-timeout标签

  • 快速学习JavaWeb中监听器(Listener)的使用方法

    一.监听器介绍 1.1.监听器的概念 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行. 1.2.监听器案例--监听window窗口的事件监听器 package me.gacl.listener.demo; import java.awt.Frame; imp

  • 浅析JAVA中过滤器、监听器、拦截器的区别

    1.过滤器:所谓过滤器顾名思义是用来过滤的,在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话).filter 流程是线性的, url传来之后,检查之后,可保持原来的流程

  • Java基础 Servlet监听器详解

    Java基础 Servlet监听器详解 1 概念:Servlet监听器,用来监听web容器的一些对象状态的变化,主要是ServletContext.HttpSession.HttpServletRequestl三类对象状态.Servlet的监听器 2  Servlet2.4和JSP2.0规范中一共定义了有八个接口类和六种事件. 3 web.xml中定义Servlet的url-pattern时如果url-pattern的值的"/",则说明该Servlet是该项目的默认Servlet,当请

  • 深入学习JavaWeb中监听器(Listener)的使用方法

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器. 这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener 和ServletRequestAttributeListener,这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换

  • JavaWeb监听器Listener实例解析

    首先来介绍一下什么是监听器: 监听器-就是一个实现待定接口的普通Java程序,此程序专门用于监听另外一个类的方法调用. 这是使用观察者模式的. 什么是观察者模式: 定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新. 示例: GUI编程中的addXxxxListener都是观察者模式. 比如为按钮点击添加监听事件,为键盘添加监听等等- 观察者模式的三个重要类: 被监听的事件源,也就是我们在使用的对象. 注册的那个监听器,是专门用来监听当前使用的对象的.

  • java使用监听器实现一个统计网站在线人数的示例

    本文主要介绍了java使用监听器实现一个统计网站在线人数的示例,具有一定的参考价值,有需要的朋友可以了解一下. (1)创建一个监听器实现类 要大致统计一个网站的在线人数,首先,可以通过ServletContextListener监听,当Web应用上下文启动时,在ServletContext中添加一个List,用来准备存放在线的用户名:然后,可以通过HttpSessionAttributeListener监听,当用户登录成功把用户名设置到Session中时同时将用户名存放到ServletConte

随机推荐