Struts2自定义拦截器与注解的使用

1、自定义拦截器

在Struts自带的配置文件struts-default.xml中,定义了默认包struts-default,这个包中定义了很多的拦截器,这些拦截器的作用是在请求访问到action之前和访问action之后进行拦截操作。一般自己在struts.xml中,如果不去指定拦截器,那么就会执行一组默认的拦截器:<default-interceptor-ref name="defaultStack"/>

            <interceptor-stack name="defaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="datetime"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params"/>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="deprecation"/>
            </interceptor-stack>

这些拦截器会对数据进行一系列的预处理,我们也可以在struts.xml中定义自己的拦截器和拦截器组,但是需要注意的是,即使定义了自己的拦截器组,也要执行默认的拦截器组,否则会发现很多问题,比如即使action实现了ModelDrivern接口,也无法获取到对象的值,这是因为这些封装就在默认的拦截器中,拦截器之间是从上到下递归调用的。

参考这些配置文件,web.xml,struts-default.xml,struts.xml以及源码,我们可以得出Struts2框架调用的基础完整流程,大致描述如下:

浏览器发起请求→web.xml中定义的struts2的核心过滤器会拦截请求,进入Struts2的数据处理流程→在该核心过滤器中的dofilter方法里,会判断当前的请求是否为访问action的请求,如果不是,直接放行,与Struts2后续处理流程无关,如直接访问html页面。而如果是访问action,此时会创建这个action的代理对象,invocation.invoke()调用invoke方法,获取所有配置的拦截器,依次递归调用→当拦截器执行完成后,会执行对应的action的方法→当action执行完成之后,会逆向再调用一次指定的过滤器(存疑?),最终返回一个逻辑视图名,根据配置文件到达最终的结果页面。

此处需要区分一下拦截器与过滤器的区别:

          过滤器属于web端的技术    /* 拦截所有资源  html 图片 jsp servlet...全部都拦

          拦截器属于struts2的技术  /* 只拦截action  html 图片 jsp 全部放行,不拦截

那么我们如何定义自己的拦截器来处理自己想要做的数据处理?可以直接模仿struts-default.xml来进行配置,描述如下:

a、创建一个拦截器,这个拦截器一般以Interceptor结尾,且必须实现Interceptor接口或者继承AbstractInterceptor类或者继承MethodFilterInterceptor类

b、在struts.xml中声明这个拦截器

c、声明拦截器组,也可以不声明拦截器组直接在action中配置调用单个拦截器。但是需要注意的是自己声明的拦截器组最好包含默认拦截器组,一个拦截器组中可以有一个或多个拦截器,拦截器组之间可以互相调用,一个拦截器可以出现在多个拦截器组中

d、在action标签内部声明需要执行的拦截器

*此外,拦截器可以执行拦截的方法,如果要进行指定,那么该拦截器必须继承MethodFilterInterceptor类,然后在拦截器标签内部通过param标签来指定需要拦截的函数和不需要拦截的函数,param的name值为excludeMethods时,代表不拦截该方法,多个方法用逗号隔开,为includeMethods时,代表拦截该方法。

以下为一个声明了拦截器的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>
			<package name="test1" extends="struts-default" namespace="/">
				<!--全局的: 为page下面的所有action申明拦截器 -->
				<interceptors>
					<interceptor name="MyInterceptor1" class="cn.itcast.interceptor.MyInterceptor1"></interceptor>
					<interceptor name="MyInterceptor2" class="cn.itcast.interceptor.MyInterceptor2"></interceptor>
					<interceptor name="MyInterceptor3" class="cn.itcast.interceptor.MyInterceptor3">
						<!-- 指定不拦截的方法 -->
						<param name="excludeMethods">findAll</param>
					</interceptor>
					
					<interceptor-stack name="MyInterceptors">
						<!--调用默认组的 -->
						<interceptor-ref name="defaultStack"></interceptor-ref>
						<interceptor-ref name="MyInterceptor2"></interceptor-ref>
						<interceptor-ref name="MyInterceptor1"></interceptor-ref>	
					</interceptor-stack>
				</interceptors>
				
				<!-- 执行在访问action的时候 需要执行的拦截器组 -->
				<default-interceptor-ref name="MyInterceptors"></default-interceptor-ref>
				
				
				<action name="ad1" class="cn.itcast.action.ActionDemo1" >
					<!-- 局部的 可以指定拦截器组  也可以指定单个拦截器 -->
					<interceptor-ref name="MyInterceptor1"></interceptor-ref>
					<interceptor-ref name="MyInterceptor2"></interceptor-ref>
					<result name="ok">/1.jsp</result>
				</action>
				<action name="ad2" class="cn.itcast.action.ActionDemo2" >
					<!-- 单个拦截器 -->
					<interceptor-ref name="MyInterceptor2"></interceptor-ref>
					<!-- 拦截器组 -->
					<interceptor-ref name="defaultStack"></interceptor-ref>
					<result name="ok">/1.jsp</result>
				</action>
				
				<action name="ad3" class="cn.itcast.action.ActionDemo3" method="findAll">
					<interceptor-ref name="MyInterceptor3"></interceptor-ref>
					<result name="ok">/1.jsp</result>
				</action>

			</package>	
	</struts>

 

2、Struts2的注解

可以使用注解代替package标签的配置,首先需要导入struts2的注解包struts2-convention-plugin-2.3.24.jar,然后必须注意的是,需要注解的action必须在action actions struts struts2含有这些名称包名下,这是因为struts2只会去他们这些包名下加载注解,四个最主要的注解举例如下:

    把action从配置文件的方式变成注解的方式
    <package name="test1" extends="struts-default" namespace="/">
        <action name="ad4" class="cn.itcast.action.ActionDemo4" >
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <result name="ok">/1.jsp</result>
        </action>
    </package>

@ParentPackage("struts-default") 定义在action类上的 指定继承的父包
@Namespace("/") 定义在action类上的 命名空间
@Action(value="ad4") 定义在方法上的 指定该方法的访问路径
@Action(@Result(name="oko",location="/2.jsp")}) 定义在方法上 指定返回的逻辑视图名 根据逻辑视图到指定的页面
            这2个注解可以合并写在一起

package cn.itcast.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cn.itcast.domain.User;

// 注解

@ParentPackage("struts-default")
@Namespace("/")
public class ActionDemo4 extends ActionSupport 
{
	
	
	@Action(value="ad4",results={@Result(name="ok",location="/1.jsp"),@Result(name="oko",location="/2.jsp")})
	public String execute() throws Exception {

		return "ok";
	}
	
}

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页