【Struts2】:拦截器实现方法过滤

  众所周知,我们在使用Struts2进行项目开发的时候,如果为某个Action配置拦截器,那么这个拦截器就会拦截该Action内的所有方法。但是在有些情况下,我们不需要拦截所有的方法,只想拦截指定的方法,此时就需要用到Struts2拦截器的方法过滤的特性了。

        为了实现方法过滤的特性,Struts2提供了一个MethodFilterInterceptor类,该类是AbstractInterceptor类的子类,如果想要自己实现的拦截器支持方法过滤特性,那就要继承MethodFilterInterceptor。

        MethodFilterInterceptor类重写了AbstractInterceptor类的intercept方法,但是提供了一个doIntercept抽象方法。从这种设计方法可以看出,MethodFilterInterceptor类的intercept已经实现了对Action的拦截行为,但是真正的拦截逻辑还需要开发者自己来写,也就是通过回调dointercept方法实现。可见,如果我们想要实现自己的拦截逻辑,则应该重写doIntercept方法。

        下面我们通过一个简单的方法过滤示例,来展示如何实现方法过滤,具体代码如下:

// 拦截方法的拦截器,应该继承MethodFilterInterceptor抽象类
public class MyFilterInterceptor
	extends MethodFilterInterceptor
{
	// 简单拦截器的名字
	private String name;
	// 为该简单拦截器设置名字的setter方法
	public void setName(String name)
	{
		this.name = name;
	}
	// 重写doIntercept()方法,实现对Action的拦截逻辑
	public String doIntercept(ActionInvocation invocation)
		throws Exception
	{
		// 取得被拦截的Action实例
		LoginAction action = (LoginAction)invocation.getAction();
		// 打印执行开始的时间
		System.out.println(name + " 拦截器的动作---------"
			+ "开始执行登录Action的时间为:" + new Date());
		// 取得开始执行Action的时间
		long start = System.currentTimeMillis();
		// 执行该拦截器的后一个拦截器,或者直接指定Action的被拦截方法
		String result = invocation.invoke();
		// 打印执行结束的时间
		System.out.println(name + " 拦截器的动作---------"
			+ "执行完登录Action的时间为:" + new Date());
		long end = System.currentTimeMillis();
		// 打印执行该Action所花费的时间
		System.out.println(name + " 拦截器的动作---------"
			+ "执行完该Action的时间为" + (end - start) + "毫秒");
		return result;
	}
}

 从上面的代码可以看出,上面的拦截逻辑与普通的拦截器的拦截逻辑并无多大差别,只是重写的方法不一样而已。需要注意的地方是:要想实现方法过滤的特性,必须继承MethodFilterInterceptor抽象类,并且重写doIntercept方法定义对Action的拦截逻辑。

        在MethodFilterInterceptor的方法中,增加了两个方法:

        SetExcludeMethods:排除需要过滤的方法,即设置方法的“黑名单”,在该方法参数里列举出来的方法都不会被拦截。

        SetIncludeMethods:设置需要过滤的方法,即设置方法的“白名单”,在该方法的参数里列出的方法都会被拦截。

        因为MethodFilterInterceptor类包含了如上的两个方法,则其子类也会获得这两个方法,因此我们可以在配置文件struts.xml中指定需要或者不需要被拦截的方法。

<package name="lee" extends="struts-default">
	<!-- 应用所需使用的拦截器都在该元素下配置 -->
	<interceptors>
		<!-- 配置mySimple拦截器 -->
		<interceptor name="mySimple"
		class="org.ljw.app.interceptor.MyFilterInterceptor">
			<!-- 为拦截器指定参数值 -->
			<param name="name">拦截方法的拦截器</param>
		</interceptor>
	</interceptors>
 
	<action name="login" class="org.ljw.app.action.LoginAction">
		<result name="error">/WEB-INF/content/error.jsp</result>
		<result>/WEB-INF/content/welcome.jsp</result> 
		<!-- 配置系统的默认拦截器 -->
		<interceptor-ref name="defaultStack"/>
		<!-- 应用自定义的mySimple拦截器 -->
		<interceptor-ref name="mySimple">
			<!-- 重新指定name属性的属性值 -->
			<param name="name">改名后的拦截方法过滤拦截器</param>
			<!-- 指定execute方法不需要被拦截 -->
			<param name="excludeMethods">execute</param>
		</interceptor-ref>
	</action>
	<action name="*">
		<result>/WEB-INF/content/{1}.jsp</result>
	</action>
</package>

 上面的配置文件中使用了拦截器参数excludeMethods制定了execute方法不用被拦截,如果需要同时指定多个方法不被拦截器拦截,则可以使用英文逗号将其隔开即可。另外如果出现同一个方法名同时出现在excludeMethods和includeMethods中,即二者产生冲突,最终以IncludeMethods参数指定的为准,也就是冲突的情况下,默认是拦截的

以上转自https://blog.csdn.net/u010929604/article/details/51546899

猜你喜欢

转载自blog.csdn.net/qq_21225505/article/details/81604991