您的位置:首页 > 编程语言 > Java开发

Struts2的拦截器实现

2014-01-20 14:13 369 查看
Struts2中的拦截器是Struts2框架中的重要组成部分,它几乎完成了框架中的70%的工作。

譬如:params拦截器负责完成解析http请求的参数并设置到Action中的属性。

servlet-config拦截器直接将http请求中的request以及response实例传给action

fileUploadl拦截器负责解析请求参数中的文件域并将一个文件域设置成action实例中的三个属性,等等,这些都是通过拦截器实现的。

通过以上可以看出,拦截器实质就是AOP(面向切面编程)的思想。

在Struts2框架中,只要我们配置的action 包继承了struts-default包,struts2就会为我们自动开启以上的拦截器。

首先。先编写一个简单的拦截器的实现。

1、编写一个拦截器类,只需实现了Interceptor接口即可(注意代码中的注释)

package org.meify.core;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
/**
 * 登录拦截器
 * 仅对登入、登出、注册等操作放行
 * @description 
 * @version 1.0
 * @author meify  2014-1-20 上午11:28:12
 */
public class LoginInterceptor implements Interceptor ,Synchronize{

	/**
	 * 在拦截器实例销毁之前系统回调该方法销毁在init()方法中打开的资源
	 *(non-Javadoc)
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#destroy()
	 */
	@Override
	public void destroy() {
		System.out.println("LoginIntercepter....destroy()");
	}

	/**
	 * 在拦截器实例初始化之后,执行拦截方法之前,系统将回调该方法
	 *(non-Javadoc)
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#init()
	 */
	@Override
	public void init() {
		System.out.println("LoginIntercepter....init()");
	}

	/**
	 * 拦截器的核心方法——实现拦截的逻辑方法
	 *(non-Javadoc)
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
	 */
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		Action action=(Action) invocation.getAction();
		String actionName=invocation.getInvocationContext().getName();
		if(action instanceof Synchronize || actionName.equals("login")||actionName.equals("logout")||actionName.equals("register")){
			invocation.invoke();
		}
		return "login";  //返回到登录页面
	}

}


其中的Synchronize匿名登录接口的代码如下

package org.meify.core;
/**
 * 匿名登录接口,仅作为一标识存在
 * @description 
 * @version 1.0
 * @author meify  2014-1-20 上午11:31:47
 */
public interface Synchronize {

}


2、在struts配置文件中对拦截器进行相应的配置以及应用

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    
<struts>
    <!-- 进入登陆页、主页 -->
	<package name="app-index" extends="struts-default" namespace="/index">
	    
	    <!--定义全部拦截器 -->
	    <interceptors>
	        <interceptor  name="loginInterceptor" class="org.meify.core.LoginInterceptor"/>
	    </interceptors>
	    
	    
	    <!-- 设置全局的显示层路径 -->
	    <global-results>
			<!-- <result name="login" type="redirect">login.action</result> -->
			<result name="login" >/WEB-INF/login.jsp</result>
		</global-results>
	
	
	
	
	
	
		<action name="index"  class="org.meify.action.index.IndexAction" >
			<result name="login_success">/index/index.jsp</result>
			<result name="login_fail">/WEB-INF/login.jsp</result>
			<!-- 使用自定义的登录拦截器 -->
			<interceptor-ref name="loginInterceptor"/>
		</action>
		

	</package>
	
	
</struts>


以上即完成了一个简单的登录拦截器的实现,该拦截器会拦截除了免登陆、登入、登出、注册以外的所有请求

Struts2还可以进行一个默认拦截器的配置,也就是说,当你没有显式说明action执行哪个拦截器的话,就会去指向默认的拦截器

默认的拦截器类的实现同普通的拦截器一样,只是配置的时候稍有不同

如下面的配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    
<struts>
    <!-- 进入登陆页、主页 -->
	<package name="app-index" extends="struts-default" namespace="/index">
	    
	    <!--定义全部拦截器 -->
	    <interceptors>
	        <!-- 默认拦截器 -->
	         <interceptor  name="defaultInterceptor" class="org.meify.core.DefaultInterceptor"/>
	        <!-- 定义登录拦截器 -->
	        <interceptor  name="loginInterceptor" class="org.meify.core.LoginInterceptor"/>
	    </interceptors>
	    
	   <!--  设置默认拦截器:注意一个包只能指定一个默认的拦截器 -->
	    <default-interceptor-ref name="defaultInterceptor"/>
	    
	    
	    
	    <!-- 设置全局的显示层路径 -->
	    <global-results>
			<!-- <result name="login" type="redirect">login.action</result> -->
			<result name="login" >/WEB-INF/login.jsp</result>
		</global-results>
	

		<action name="index"  class="org.meify.action.index.IndexAction" >
			<result name="login_success">/index/index.jsp</result>
			<result name="login_fail">/WEB-INF/login.jsp</result>
			<!-- 使用自定义的登录拦截器 -->
			<interceptor-ref name="loginInterceptor"/>
		</action>
		

	</package>

</struts>


以上的拦截器都是拦截action中的所有方法,实际开发中,肯定不需要拦截所有的方法,只需拦截其中特定的方法即可。

Struts2提供了一个可以实现过滤的方法拦截器MethodsFilterInterceptor,只需继承该类即可实现拦截哪些方法,放行哪些方法

package org.meify.core;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
/**
 * 拦截器——实现方法的选择性拦截
 * @description 
 * @version 1.0
 * @author meify  2014-1-20 下午1:37:16
 */
public class MyFilterInterceptor extends MethodFilterInterceptor{

	private String name;
	
	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		Action action=(Action) invocation.getAction();
		String actionName=invocation.getInvocationContext().getName();
		if(action instanceof Synchronize || actionName.equals("login")||actionName.equals("logout")||actionName.equals("register")){
			invocation.invoke();
		}
		return "login";  //返回到登录页面
	}
	
	

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
相关配置

<!-- 定义一个方法拦截器 -->
	        <interceptor  name="myFilterInterceptor" class="org.meify.core.MyFilterInterceptor">
	            <!-- 设置黑名单 ——这些方法不需拦截 -->
	             <param name="excludeMethods">login</param>
	            <!--  设置白名单 ——这些方法需要拦截-->
	             <param name="includeMethods">execute</param>
	        </interceptor>
这样就可以指定该拦截器拦截action中的哪些方法,放行哪些方法。

此外,还需注意一下拦截器的执行顺序。

通常是配置在前面的拦截器优先执行,但是注意:

在Action特定方法执行之前,位于拦截器链前面的拦截器将先发生作用;在Action特定方法执行之后,位于拦截器链前面的拦截器将后发生作用。

拦截结果的监听器:实现在Action中的特定方法执行结束之后,在处理物理资源转向之前进行拦截动作。

实现拦截结果的拦截器只需实现PreResultListener接口即可,如下

package org.meify.core;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.PreResultListener;
/**
 * 拦截结果的监听器
 * @description 
 * @version 1.0
 * @author meify  2014-1-20 下午2:05:45
 */
public class MyPreResultListener implements PreResultListener {

	/**
	 * 该方法将在跳转到指定页面之前执行 
	 *(non-Javadoc)
	 * @see com.opensymphony.xwork2.interceptor.PreResultListener#beforeResult(com.opensymphony.xwork2.ActionInvocation, java.lang.String)
	 */
	@Override
	public void beforeResult(ActionInvocation invocation, String forwardPath) {
		System.out.println("页面即将跳转的路径为======"+forwardPath);
	}

}


然后在相应的拦截器中加入

invocation.addPreResultListener(new MyPreResultListener()); //注册该监听器

该行代码即可注册该结果监听器,当拦截器所拦截的action的方法执行完,在跳转之前就会去执行监听器中的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: