Struts2拦截器(二)

来源:互联网 发布:自动发微博软件 编辑:程序博客网 时间:2024/05/19 14:52

前一个例子讲了对于前台数据的拦截。但是问题出现了,我们定义了拦截器后,它会对Action下面的所有方法进行拦截。有时候,我们只需要拦截Action中的部分方法,怎么办呢?

1.方法的过滤

我们就要通过过滤的方式。

struts2提供了一个MethodFilterInterceptor类,该类是AbstractInterceptor类的子类,如果用户需要自己实现的拦截器支持方法过滤,则应该继承MethodFilterInterceptor类。该类需要实现一个方doInterceptor(ActionInvocation invocation)

实现过滤的方法和普通拦截器并没有太大区别,只需要继承MethodFilterInterceptor类和实现该类的doInterceptor方法便可。

但是注意的一点是:

MethodFilterInterceptor类中,增加了两个方法

1)public void setExcludeMethods(String excludeMethods):

作用:排除需要过滤的方法

2)public void setIncludeMethods(String includeMethods):

设置需要过滤的方法

看struts.xml配置文件中怎么写

 <interceptors>        <interceptor name="a1" class=""></interceptor>     </interceptors>     <action name="los" class="">        <interceptor-ref name="拦截器名">          <param name="excldeMethods">execute</param>        </interceptor-ref>     </action>

可以看到,execludeMethods标签去掉了execute()方法,也就是拦截器不会拦截execute方法,如果要设置多个方法不被拦截,可以通过下面的代码


<package name="t" extends="struts-default">     <interceptors>        <interceptor name="a1" class=""></interceptor>     </interceptors>     <action name="los" class="">        <interceptor-ref name="拦截器名">          <param name="excldeMethods">execute,add,delete</param>        </interceptor-ref>     </action>   </package>


如果includeMethods同时选中一个方法,那该方法默认被选中,也就是遵循includeMethods的选择。

2.拦截器监听的结果

前面例子中,我们执行完invocation.invoke()方法后,执行execute后,会继续执行没有执行完的代码,这样结构上看上不不清晰。

为了说明execute()方法结束后再执行Result执行的动作,Struts2提供了用于拦截器结构的监听器,这个监听器是通过手工注册到拦截器内部的。

实现拦截器的监听要实现PreResultListener接口,其代码如下:

import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.PreResultListener;public class TestPreResultListener implements PreResultListener {public void beforeResult(ActionInvocation invocation,String resultCode){System.out.println("最后逻辑视图为:"+resultCode);}}


与前面直接在intercepte方法中定义的,在execute()方法执行之后执行的代码相比,在beforeResult()方法内有另一个参数:resultCode,这个参数就是被拦截Action的execute()方法的返回值。

虽然上面的beforeResult()也获得了ActionInvocation类型的参数,但通过这个参数来控制Action的作用已经不再那么明显——因为Action的execute()方法已经执行完了。

监听器需要通过代码手动注册给某个拦截器,需要在拦截器类中的intercept(ActionInvocation invocation)方法中加上下面代码进行注册监听器。

invoaction.addPreResultListener(new TestPreResultListener());

通过代码手动注册了一个拦截结果的监听器TestPreResultListener,该监听器中的Result()方法肯定会在系统处理Result之前执行。

虽然beforeResult()方法中再对ActionInvocation方法处理已经没有太大意义,但是Action已经执行完毕,而Result还没有开始执行的时间点也非常重要,可以让开发者精确控制到Action处理的结果,并且对处理结果做出针对性的处理。

3.Struts2自带拦截器

如果<package> extends了struts-default包,那就可以使用默认拦截器。但是如果引用了自定的拦截器,那必须要显示的声明引用默认拦截器。

struts2的内置拦截器概览:

拦截器名功能alias实现在不同请求中相似参数别名的转换autowiring这个是自动装配的拦截器,主要用于当struts2和spring整合时,struts可以使用自动装配的方式访问spring容器中的beanchain构建一个Action链,使当前Action可以访问前一个Action的属性,一般和<result type="chain".../>一起使用conversionError这是一个负责处理类型转换错误的拦截器,它负责将类型转换错误从ActionContext中取出,并转换成Action的FieldError错误createSession该拦截器负责创建一个HttpSession对象,主要用于那些需要HttpSession对象才能正常工作的拦截器debugging当使用struts2的开发模式时,这个拦截器将提供更多的调试信息execAndWait后台执行Action,负责将等待画面发送给用户exception这个拦截器负责处理异常,它将异常映射为结果fileUpload这个拦截器主要用于文件上传,它负责解决表单文件域的内容il8n这是支持国际化的拦截器,它负责把所选的语言、区域放入用户的session中logger这个是负责日志记录的拦截器,主要输出Action的名字model-driven这是一个用于模型驱动的拦截器,当某个Action类实现了ModelDriven接口时,它负责把getModel()方法的结果放入ValueStack中scoped-model-driven如果一个Action实现了ScopedModelDriven接口,该拦截器负责从指定生成范围中找出指定的Model,并通过setModel()方法将该Model传给Action实例params这是一个最基本的拦截器,它负责解析HTTP请求中的参数,并将参数值设置成Action对应的属性prepare

如果Action实现了Prepareable接口,将会调用该拦截器的parepare()方法

static-params该拦截器负责将xml中<action>标签下的<param>标签中的参数传入Actionscope这是范围转换拦截器,它可以将Action状态信息保存到HttpSession范围,或者保存到ServletContext范围中servlet-config如果某个Action需要直接访问Servlet API,就是通过这个拦截器实现的roles这是一个JAAS(Java Authentication and Authorization Service,Java授权和认证服务)拦截器,只有当浏览者取得合适的授权后,才可以调用被拦截器拦截的Actiontimer这个拦截器负责输出Action的执行时间,这个拦截器在分析该Action的性能瓶颈时比较常用token这个拦截器用于防止重复提交,它检查到Action中的token,从而防止多次提交token-Session这个拦截器的作用于前一个基本类似,只是它把token保存在HttpSession中validation通过执行在xxxAction-validation.xml中定义的校验器,从而完成数据校验workflow这个拦截器负责调用Action类中的validate()方法,如果校验失败,则返回input的逻辑视图

4.使用拦截器注解

Struts2在com.opensymphony.xwork2.interceptor.annotations包中定义了3个拦截器注解类型,可以通过注解的方式指定在Action前或者Action后需要调用的方法。

1)Before

用于标注一个Action方法,该方法将在 Action的execute方法执行之前调用。如果标注的方法有返回值,且不为null,那它的返回结果将作为Action的结果代码。

2)After

用于标注一个Action方法,该方法将在Action的execute方法执行之后且result执行之后调用。有返回值 返回值也将被忽略

3)BeforeResult

标识一个Action方法,该方法将在Action的主要方法调用之后,在result方法调用之前调用。

import java.util.Map;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.interceptor.annotations.Before;import com.zhuxuli.model.User;public class LoginAction extends ActionSupport {private User user;public User getUser() {return user;}public void setUser(User user) {this.user = user;}@Beforepublic String checkUser(){ActionContext context=ActionContext.getContext();Map Session=context.getSession();if(user!=null&&user.getUsername().equals("micheal")){Session.put("user", user);return null;}else{return "input";}}public String execute() throws Exception{return "main";}}


并且struts.xml中要配置相应的拦截器

<package name="logs" extends="struts-default">   <interceptors>      <interceptor name="annotationInterceptor" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor">              </interceptor>      <interceptor-stack name="annotatedStack">        <interceptor-ref name="defaultStack"></interceptor-ref>        <interceptor-ref name="annotationInterceptor"></interceptor-ref>      </interceptor-stack>   </interceptors>  <global-results>         <result name="error">/error.jsp</result>     </global-results>      <action name="logs" class="com.zhuxuli.action.LoginAction">           <result name="input">/index.jsp</result>           <result name="main">/main.jsp</result>           <interceptor-ref name="annotatedStack"></interceptor-ref>      </action>  </package>


在上边,拦截器中定义了Struts2的com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor拦截器,然后再拦截器栈中定义了默认拦截器栈和本拦截器。在Action中引用。

这样的话,每当页面提交信息后,表单首先通过了Before注释的方法的验证,如果返回空,将执行execute()方法,如果不为空,那就会作为result的结果返回逻辑视图。

 

原创粉丝点击