且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

12 Struts2 拦截器

更新时间:2022-08-22 10:20:30

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hxdeng/article/details/81941425

拦截器

拦截器在概念上和Servlet过滤器或JDK代理类一样。拦截器允许横切功能在动作和框架中单独实现。你可以使用拦截器实现下面的内容:

  • 在动作被调用之前提供预处理逻辑。
  • 在动作被调用之后提供预处理逻辑。
  • 捕获异常,以便可以执行交替处理。

Struts 2 框架提供的许多功能都是使用拦截实现的;例如包括异常处理,文件上传,生命周期回调和验证等。

Struts 2 框架的拦截器
Struts 2框架提供了一个良好的开箱即用的拦截器列表,这些拦截器预先配置好并可以使用。 下面列出了几个重要的拦截器:

编号 拦截器名称 拦截器说明
1 alias 允许参数有不同的跨请求的别名。
2 checkbox 通过为没有被检查的复选框添加一个参数值 false 来协助管理复选框。
3 conversionError 把从字符串转化为参数类型的错误信息放置到动作的字段错误中。
4 createSession 如果不存在 HTTP 会话,则自动创建一个 HTTP 会话。
5 debugging 为开发人员提供几种不同的调试屏幕。
6 execAndWait 当action在后台执行时,将用户发送到中间的等待页面。
7 exception 映射从action到结果抛出的异常,允许通过重定向自动处理异常。
8 fileUpload 有利于简单的文件上传。
9 i18n 在用户的会话期间,跟踪选定的语言环境。
10 logger 通过输出正在执行的action的名称提供简单的日志记录。
11 params 设置action上的请求参数。
12 prepare 它通常是用来做预处理工作,如设置数据库连接。
13 profile 允许记录action的简单分析信息。
14 scope 在会话或应用程序范围内存储和检索action的状态。
15 ServletConfig 提供可访问各种基于servlet信息的action。
16 timer 以action执行时间的形式提供简单的分析信息
17 token 检查action的有效性,以防止重复提交表单。
18 validation 提供action的验证支持。

如何使用系统提供的拦截器

我们将首先使用timer拦截器,目的是测量执行action方法所需的时间。同时我们使用params拦截器,目的是将请求参数发送给action。你可以尝试不在你的例子中使用这个拦截器,然后你会发现name属性没有被设置,因为参数无法发送给action。

struts.xml

<constant name="struts.devMode" value="true" />
<package name="helloworld" extends="struts-default">
    <action name="hello" class="com.javaee.struts2.HelloWorldAction" method="execute">
        <interceptor-ref name="params"/>
        <interceptor-ref name="timer" />
        <result name="success">/index.jsp</result>
    </action>
</package>

创建自定义的拦截器

在你的应用程序中使用自定义的拦截器是一种提供横切的应用功能的简洁的方式。创建一个自定义的拦截器是很容易的,需要实现的接口是下面的 Interceptor 接口,或者继承AbstractInterceptor类,它提供了一个对 init() 和 destroy() 方法的默认的无操作实现。

自定义拦截器实现Action执行时间

==Interceptor类==

public class SelectActionTimeInter extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation inv) throws Exception {

        Long startTime = System.currentTimeMillis();

        // 将请求交给下一个拦截器或者Action。返回值是Action中方法的返回值
        String result = inv.invoke();

        Long entTime = System.currentTimeMillis();

        System.out.println(inv.getAction().getClass() + "类的" + inv.getProxy().getMethod() + ",执行时间" + ((entTime - startTime) / 1000) + "秒");

        return result;
    }
}

==struts.xml配置==

<!-- 注册拦截器 -->
<interceptors>
    <interceptor name="getActionTime" class="com.javaee.struts2.interceptor.SelectActionTimeInter"></interceptor>
</interceptors>

<!-- Action中引用具体拦截器 -->
<interceptor-ref name="getActionTime" />
<!-- <interceptor-ref name="params" /> -->
<interceptor-ref name="defaultStack" />
<result>/success.jsp</result>
自定义拦截器实现登录验证

==Interceptor类==

Map<String, Object> sesion = invocation.getInvocationContext().getSession();

==struts.xml配置==

实际的动作将通过使用拦截器调用 invocation.invoke() 来执行。所以,你可以根据你的需求做一些预处理和一些后处理。

注意:当为包中的某个action显示指定了某个拦截器,则 默认拦截器不会起作用

拦截器栈

将多个拦截器组合在一起使用就是拦截器栈。配置拦截器栈的好处就是在action中就不用引入多个拦截器,只需要引入拦截器栈即可。

<!-- 注册拦截器 -->
<interceptors>
    <interceptor name="getActionTime" class="com.javaee.struts2.interceptor.SelectActionTimeInter" />
    <interceptor name="checkLogin" class="com.javaee.struts2.interceptor.CheckUserLoginInterceptor" />

    <!-- 拦截器栈 -->
    <interceptor-stack name="myInterceptorStack">
        <interceptor-ref name="checkLogin" />
        <interceptor-ref name="getActionTime" />
        <interceptor-ref name="defaultStack" />
    </interceptor-stack>

    <interceptor-stack name="myInterceptorStack2">
        <interceptor-ref name="getActionTime" />
        <interceptor-ref name="defaultStack" />
    </interceptor-stack>
</interceptors>

<!-- 在需要使用拦截器起的Action中引用拦截器栈名称 -->
<action name="findUserPrimaryKey" class="com.javaee.struts2.action.UserinfoAction" method="selectPrimaryKey">
    <interceptor-ref name="myInterceptorStack" />
    <result>/success.jsp</result>
    <result name="input">/login.jsp</result>
</action>

Struts2 执行流程

  1. 客户端向Servlet容器(如Tomcat)提交一个请求
  2. 请求经过一系列过滤器(如ActionContextCleanUp过滤器等)
  3. 核心控制器被调用,询问ActionMapper来决定请求是否需要调用某个Action
  4. 如果ActionMapper决定需要调用某个Action,核心控制器把控制权委派给ActionProxy(备注:JSP请求无需调用Action)
  5. ActionProxy通过Configuration Manager询问框架的配置文件(struts.xml),找到需调用的Action类
  6. ActionProxy创建一个ActionInvocation的实例
  7. ActionInvocation负责调用Action,在此之前会依次调用所有配置的拦截器
  8. Action执行完毕,ActionInvocation负责根据结果码字符串在struts.xml的配置中找到对应的返回结果
  9. 拦截器被再次执行
  10. 过滤器被再次执行