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%>">
    
    <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">
	-->

  </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



  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值