• Struts2拦截器


    拦截器(interceptor)是Struts2最强大的特性之一,拦截器可以让你在Action和result被执行之前或之后进行一些处理。同时,拦截器也可以让你将通用的代码模块化并作为可重用的类。Struts2中的很多特性都是由拦截器来完成的。例如params拦截器将HTTP请求中的参数解析出来,并设置为Action的属性。servlet-config拦截器直接将HTTP请求中的HttpServletRequest对象化HttpServletResponse对象传给Action。

    image

    Struts2中内置类许多的拦截器,它们提供了许多Struts2的核心功能和可选的高级特性。这些内置的拦截器在struts-default.xml中配置。只有配置了拦截器,拦截器才可以正常的工作和运行。在struts-default.xml中拦截器的配置片段为:

    <package name="struts-default" abstract="true"><interceptors>
            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/><interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
            //…其他拦截器配置
            <interceptor-stack name="defaultStack"><interceptor-ref name="exception"/>
                  <interceptor-ref name="alias"/>
                    <interceptor-ref name="servletConfig"/>
                    <interceptor-ref name="i18n"/>
                    //…其他拦截器的引用
              </interceptor-stack>    
        </interceptors>
        <default-interceptor-ref name="defaultStack"/></package>

    ① package将属性abstract设置为true,代表此package为一个抽象的package。抽象package和非抽象package的区别在于抽象的package中不能配置action。

    ② name属性指定拦截器的名字,class属性指定拦截器的完全限定名。

    ③ 多个拦截器可以组成拦截器栈。name属性为拦截器栈的名字。

    ④ 指定当前package的默认拦截器(栈)。当前指定的默认拦截器栈为defaultStack,该拦截器栈是Struts2运行的一个基本拦截器栈,一般我们不用在自己配置它,因为在大多数情况下,我们自定义的package是继承自struts-default这个package的。

    我们以Struts2内置的timer拦截器为例,来学习如何在我们的应用中添加其他的拦截器。timer拦截器可以统计action执行的时间。我们可以修改package中默认的拦截器,那么将替换掉struts-default中配置的defaultStack拦截器栈,导致Struts2无法正常运行,比如无法获取表单的值等等。那么该如何正确的配置呢?可以在添加新的拦截器的基础上加入defaultStack拦截器栈,这样就可以保证defaultStack拦截器栈的存在。

    <package name="myStruts" extends="struts-default">
    	<interceptors>
    		<interceptor-stack name="myInterceptor"><interceptor-ref name="timer"/>  
    			<interceptor-ref name="defaultStack"/>  
    		</interceptor-stack>
    	</interceptors>
    	<default-interceptor-ref name="myInterceptor"/><action name="userAction"
    		class="com.kay.action.UserAction">
    		<result name="success">suc.jsp</result>
    		<result name="input">index.jsp</result>
    		<result name="error">err.jsp</result>
    	</action>
    </package>

    ① 添加一个自定义的拦截器栈,并在其中包含time拦截器和defaultStack拦截器栈。

    ② 设置当前的package的默认拦截器栈为自定义的拦截器栈。

    修改package的默认拦截器会应用的package中的所有Action中,如果只想给其中一个Action添加拦截器,则可以这样来做:

    <package name="myStruts" extends="struts-default">
    	<interceptors>
    		<interceptor-stack name="myInterceptor">
    			<interceptor-ref name="timer"/>
    			<interceptor-ref name="defaultStack"/>
    		</interceptor-stack>
    	</interceptors>
    	<action name="userAction"
    		class="com.kay.action.UserAction">
    		<interceptor-ref name="myInterceptor"/><result name="success">suc.jsp</result>
    		<result name="input">index.jsp</result>
    		<result name="error">err.jsp</result>
    	</action>
    </package>

    ① 给UserAction添加拦截器。

    如果要创建自己的拦截器,只需要实现Interceptor接口,该接口中定义了以下三个方法:

    void init():

    在拦截器初始化之后,在执行拦截之前,系统调用该方法。对于一个拦截器而言,init方法只会被调用一次。

    String intercept(ActionInvocation invocation) throws Exception:

    该方法是拦截器的拦截方法,返回一个字符串,系统将会跳转到该字符串对应的视图资源。该方法的ActionInvocation参数包含了被拦截的Action的引用,可以通过该对象的invoke方法,将控制权转给下一个拦截器或者转给Action的execute方法。

    void destroy():

    该方法与init方法对应,在拦截器示例被销毁之前,系统将会调用该方法。

    除了Interceptor接口外,Struts2中还提供了一个AbStractInterceptor类,该类提供了一个init和destroy方法的空实现。如果不需要就不用重写这两个方法,可见继承自AbstractInterceptor类可以让我们构建拦截器时变得简单。

    下面我们构建自己的拦截器,实现timer拦截器的效果。

    public class MyInterceptor extends AbstractInterceptor {
    	public String intercept(ActionInvocation invocation) throws Exception {
    		long startTime = System.currentTimeMillis();  ①
    		String result = invocation.invoke();  ②
    		long endTime = System.currentTimeMillis();  ③
    		System.out.println("Action执行共需要" + (endTime - startTime) + "毫秒");
    		return result; 
    	}
    }

    ① 获得Action执行的开始时间。

    ② 将控制权交给下一个拦截器,如果该拦截器是最后一个拦截器,则调用Action的execute方法。

    ③ 获得Action执行的结束时间。

    在配置文件struts.xml中配置拦截器:

    <package name="myStruts" extends="struts-default">
    	<interceptors>
    		<interceptor name="myTimer" class="com.kay.interceptor.MyInterceptor"></interceptor><interceptor-stack name="myInterceptor">
    			<interceptor-ref name="myTimer"/><interceptor-ref name="defaultStack"/>
    		</interceptor-stack>
    	</interceptors>
    	<action name="userAction"
    		class="com.kay.action.UserAction">
    		<interceptor-ref name="myInterceptor"/>
    		<result name="success">suc.jsp</result>
    		<result name="input">index.jsp</result>
    		<result name="error">err.jsp</result>
    	</action>
    </package>

    ① 定义一个新的拦截器,name属性为拦截器的名字,class属性为拦截器的完全限定名。

    ② 在拦截器栈中加入新的拦截器。

    从拦截器的运行原理上和我们以前学习的Servlet中的过滤器是不是很相像呢?其实它们只有一个重要的区别,就是拦截器的工作是不依赖容器的,这会在进行单元测试时变得简单。

  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/kay/p/1566805.html
Copyright © 2020-2023  润新知