欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-21 15:51:40
本文实例讲述了java中的拦截器、过滤器、监听器用法。分享给大家供大家参考,具体如下: 一、拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方...

本文实例讲述了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程序设计有所帮助。