九、Struts2之拦截器


一、拦截器介绍


拦截器是Struts2最重要的组成部分,因为Struts2的大部分操作都是通过他完成的,以下列举了一些内建拦截器:

(1)params :拦截HTTP请求参数,并完成类型转换

(2)fileUpload:文件上传拦截器;

(3)conversionError:处理类型转换错误的拦截器;

(4)exception:处理异常的拦截器,因此在execute方法中,才可以安心抛出异常;

(5)i18n:处理国际化拦截器;

(6)static-params:用于在struts.xml中注入action属性值;

(7)validation:在xml文件中配置的输入校验拦截器;

(8)workflow:处理手动校验的拦截器

以上内建拦截器都在struts2-core-Xxx.jar\struts-default.xml中定义,因此在定义<package>时需要填写 extends="struts-default",这样能够自动继承这些拦截器;

而我们还可以自己定义拦截器,不过注意,如果配置了自定义拦截器,则会让内建拦截器消失,因此我们必须要显式地引用内建拦截器,如下 <interceptor name="defaultStack"/>;

Struts2通过可插拔设计,可以添加、删除任意拦截器,非常灵活;


拦截器&拦截器栈

拦截器栈是由多个拦截器构成的,在使用时可以把他当作一个“大一点的拦截器”,除了定义不同,使用起来是相同的;

拦截器栈应用:多个拦截器同时使用时,方便管理;

拦截器栈

拦截器1

拦截器2

拦截器3

拦截器的使用:拦截器配置在<action>中,即为某个Action配置一个或多个拦截器, 即执行Action方法之前会被拦截器拦截,并执行拦截器方法;


二、自定义拦截器

1.配置自定义拦截器和拦截器栈

定义拦截器或拦截器栈的根元素为<interceptors>,而此元素是<package>的子元素;


(1)定义拦截器:<interceptors>的子元素

<interceptor name="拦截器名" class="实现类"/>

注:如果需要传入参数,则表示拦截器类属性的默认值;

<interceptor name="拦截器名" class="实现类"> <param name="name">value</param> </interceptor>

(2)引用拦截器:<action>或<interceptor-stack>的子元素

如果是<action>的子元素,则表示在action中配置一个拦截器;

<interceptor-ref name="拦截器名"/>

注:如果需要传入参数,则表示使用拦截器时类属性的值,将覆盖定义拦截器时传入的参数;

<interceptor-ref name="拦截器名"> <param name="name">value</param> </interceptor-ref>

(3)定义拦截器栈:<interceptors>的子元素

<interceptor-stack name="拦截器栈名">

<interceptor-ref name="拦截器名"/>

<interceptor-ref name="拦截器名"/>

</interceptor-stack>

(4)引用拦截器栈:<action>的子元素

<interceptor-ref name="拦截器栈名"/>

注:这里传递参数方法比较特殊,因为拦截器栈中有多个拦截器,因此必须以如下形式执行参数:

<interceptor-ref name="拦截器栈名">

<param name="interceptorName.attrName">value</param>

</interceptor-ref>

(5)定义默认拦截器:<package>的子元素

<default-interceptor-ref name="拦截器或拦截器栈名"/>

注:可以在此处传入参数:

<default-interceptor-ref name="默认拦截器名">

<param name="name">value</param>

</default-interceptor-ref>

默认拦截器使用时机:当action中没有显式地引用拦截器,则会使用默认拦截器;

2.定义拦截器类

实现Interceptor接口,并实现方法:

(1)public void init();//初始化,一般为空

(2)public void destroy();//销毁,一般为空

(3)public String interceptor(ActionInvocation invocation)throws Exception;//实现拦截功能,返回值为execute方法返回值;

String result = invocation.invoke()即可调用拦截器拦截的Action的execute()方法,并返回逻辑视图;
public String interceptor(ActionInvocation invocation)throws Exception{

//调用execute()方法之前

String result = invocation.invoke();

//调用execute()方法之后

return result;

注意:

(1)在使用自定义拦截器时,会丢失默认内建拦截器,因此需要显式引用默认拦截器栈:<interceptor-ref name="defaultStack"/>

(2)如果在一个Action中配置了两个拦截器,则如果拦截器A在拦截器B之前引用,即:

<action>

<interceptor-ref name="A"/>

<interceptor-ref name="B"/>

</action>

则虽然在两个拦截器中都调用了invocation.invoke(),但是只会执行一遍Action方法;Action方法执行之前,拦截器A比拦截器B先执行;Action方法执行之后,则拦截器B比拦截器A先执行;

即结果为:

A拦截器语句

B拦截器语句

execute

B拦截器语句

A拦截器语句


代码实例:

HelloAction.java


package org.xiazdong.action; import com.opensymphony.xwork2.ActionSupport; public class HelloAction extends ActionSupport { public String execute()throws Exception{ System.out.println("execute..."); return SUCCESS; } }

Interceptor01.java


package org.xiazdong.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; public class Interceptor01 implements Interceptor { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void destroy() { } @Override public void init() { } @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println("name属性:"+name); System.out.println("execute方法之前..."); String result = invocation.invoke(); System.out.println("execute方法之后..."); return result; } }

struts.xml


<?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> <constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor name="interceptor01" class="org.xiazdong.interceptor.Interceptor01"> <param name="name">xiazdong</param> </interceptor> <interceptor-stack name="stack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="interceptor01"></interceptor-ref> </interceptor-stack> </interceptors> <action name="hello" class="org.xiazdong.action.HelloAction"> <interceptor-ref name="stack"></interceptor-ref> <result>/index.jsp</result> </action> </package> </struts>

3.方法过滤


默认自定义拦截器将会拦截Action的所有方法,比如在Action中定义了login()方法、regist()方法,则默认会拦截两个方法,如果只想拦截login()方法,则需要通过如下步骤实现过滤:

(1)继承 MethodFilterInterceptor类;

(2)重写public String doIntercept(ActionInvocation invocation)throws Exception;此方法和intercept方法功能一致,只是名字不一样;

(3)在struts.xml中配置参数进行过滤:在<interceptor-ref>的子元素中设置:

<param name="excludeMethods">不过滤的方法1,不过滤的方法2</param>、<param name="includeMethods">需要过滤的方法</param>


注意:如果一个方法在includeMethods和excludeMethods参数中同时列出,则还是会被拦截;


代码实例:
如果Action中提供了login()、regist()方法,则struts.xml中如下配置,可以实现login()不被拦截器拦截:

struts.xml

<?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> <constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor name="interceptor01" class="org.xiazdong.interceptor.Interceptor01"> <param name="name">xiazdong</param> </interceptor> <interceptor-stack name="stack"> <interceptor-ref name="defaultStack"> </interceptor-ref> <interceptor-ref name="interceptor01"> <param name="excludeMethods">login</param> </interceptor-ref> </interceptor-stack> </interceptors> <action name="hello" class="org.xiazdong.action.HelloAction"> <interceptor-ref name="stack"></interceptor-ref> <result>/index.jsp</result> </action> </package> </struts>

补充:PreResultListener应用


在Action的介绍中也介绍过这个类,是用于在Action方法执行之后、转入物理视图之前被调用;
这个类也可以在拦截器类中被添加,则只要应用该拦截器的action都会起作用,步骤如下:
(1)定义MyPreResultListener:
public class MyPreResultListener implements PreResultListener{
public void beforeResult(ActionInvocation invocation,String resultCode);
}
(2)在intercept方法中添加invocation.addPreResultListener(new MyPreResultListener());
即可;

代码:

MyPreResultListener.java
package org.xiazdong.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.PreResultListener; public class MyPreResultListener implements PreResultListener { @Override public void beforeResult(ActionInvocation arg0, String arg1) { System.out.println("beforeResult..."); } }
Interceptor01.java

package org.xiazdong.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; public class Interceptor01 extends MethodFilterInterceptor{ @Override public String doIntercept(ActionInvocation invocation) throws Exception { invocation.addPreResultListener(new MyPreResultListener()); System.out.println("execute1方法之前..."); String result = invocation.invoke(); System.out.println("execute1方法之后..."); return result; } }

结果如下:

execute1方法之前...
regist...
beforeResult...
execute1方法之后...

可以看出,此方法在Action方法一执行完就触发PreResultListener,比拦截器先执行;




最后配上一张图作为结尾:








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值