zoukankan      html  css  js  c++  java
  • Struts2基础-4 -struts拦截器

    Struts2拦截器工作原理

      拦截器围绕着 Action和 Result的执行而执行。 Struts2拦截器的工作方式如图10.2所示。从上图中可以看出, Struts2拦截器的实现原理和 Servlet Filter的实现原理差不多,以链式执行对真正要执行的方法( execute()进行拦截。首先执行 Action配置的拦截器,在 Action和 Result执行之后,拦截器再一次执行(与先前调用相反的顺序),在此链式的执行过程中,任何一个拦截器都可以直接返回,从而终止余下的拦截器、 Action及 Result的执行。

      当 Actioninvocation的moke(方法被调用时,开始执行 Action配置的第一个拦截器,拦截器做出相应处理后会再次调用 Actioninvocation的 invoke()方法, Actioninvocation对象负责跟踪执行过程的状态,并且把控制权交给合适的拦截器。 Actioninvocation通过调用拦截器的 Intercept()方法将控制权转交给拦截器。因此,拦截器的执行过程可以看作一个递归的过程,后续拦截器继续执行,直到最后一个拦截器, invoke()方法会执行 Action。

    拦截器有一个三阶段的、有条件的执行周期,如下所示:
    (1)做一些 Action执行前的预处理。拦截器可以准备、过滤、改变或者操作任何可以访问的数据,包括 Action。
    (2)调用 Actioninvocation的 evoke()方法将控制权转交给后续的拦截器或者返回结果字符串终止执行。如果拦截器决定请求的处理不应该继续,可以不调用 invoke()方法,而是直接返回一个控制字符串。通过这种方式,可以停止后续的执行,并且决定将哪个结果呈现给客户端。
    (3)做一些 Action执行后的处理。此时拦截器依然可以改变可以访问的对象和数据,只是此时框架已经选择了一个结果呈现给客户端了

    自定义拦截器例子:

    (1)自定义拦截器类

     1 package cn.test.interceptor;
     2 
     3 import com.opensymphony.xwork2.ActionInvocation;
     4 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
     5 
     6 public class MyTimeIntercepter extends AbstractInterceptor {
     7 
     8     private static final long serialVersionUID = 1L;
     9 
    10     @Override
    11     public String intercept(ActionInvocation invocation) throws Exception {
    12         // 1.执行Action之前的工作:获取开始执行时间
    13         long startTime = System.currentTimeMillis();
    14         System.out.println("执行Action之前的工作,开始时间:" + startTime);
    15         // 2.执行后续拦截器或Action
    16         String result = invocation.invoke();
    17         // 1.执行Action之后的工作:计算并输出执行时间
    18         long endTime = System.currentTimeMillis();
    19 
    20         System.out.println("执行Action之后的工作,结束时间:" + endTime);
    21         System.out.println("总共用时:" + (endTime - startTime));
    22         return result;
    23     }
    24 
    25 }
       mytimerinterceptor拦截器记录动作执行所花费的时间,代码很简单。 Intercept()方法是拦截器执行的入口方法,需要注意的是它接收 Actioninvocation的实例。
      当 Intercept()方法被调用时,拦截器开始记录开始时间(也就是进行预处理的工作),接着 mytimerinterceptor 拦截器调用 ActionInvocation实例的 invoke()方法,将控制权转交给剩余的拦截器和 Action,因为记录执行时间没有理由终止执行,所以 My T imer Interceptor拦截器总是调用 invoke()方法。
      在调用 invoke()方法后, My T imer Interceptor拦截器等待这个方法的返回值。虽然这个结果字符串告诉 My Timer Interceptor拦截器哪个结果会被呈现,但并未指出 Action是否执行(可能剩余的拦截器终止了执行操作)。无论 Action是否执行,当 invoke()方法返回时,就表明某个结果已经被呈现了(响应页面已经生成完毕)。
      获得结果字符串之后, My Timer Interceptor拦截器记录了执行的用时,在控制台进行了输出。此时拦截器可以使用结果字符串做一些操作,但是在这里不能停止或者改变响应。对于
    My T imer Interceptor拦截器而言,它不关心结果,因此它不查看返回的结果字符串。
      MyTimer Interceptor拦截器执行到最后,返回了从 invoke()方法获得的结果字符串,从而使递归又回到了拦截器链,使前面的拦截器继续执行它们的后续处理工作。 
    (2) struts.xml 中拦截器配置
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE struts PUBLIC
     3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
     4     "http://struts.apache.org/dtds/struts-2.3.dtd">
     5 <struts>
     6     <package name="default" namespace="/" extends="struts-default">
     7         <!-- 配置默认的行为 -->
     8         <default-action-ref name="defaultAction"></default-action-ref>
     9         <!-- 配置默认action -->
    10         <action name="defaultAction">
    11             <result type="redirect">/error.jsp</result>
    12         </action>
    13     </package>
    14 
    15     <!-- 拦截器配置 -->
    16     <package name="intercepter" namespace="/" extends="struts-default">
    17         <!-- interceptors元素中使用interceptor子元素定义拦截器 -->
    18         <interceptors>
    19             <!--  interceptor元素name属性:拦截器的名称,class:自定义拦截器类的全限定类名-->
    20             <interceptor name="myTime" class="cn.test.interceptor.MyTimeIntercepter"></interceptor>
    21             <interceptor-stack name="myTimeStack">
    22                 <interceptor-ref name="myTime"></interceptor-ref>   <!-- 把自定义的拦截器设置为栈的顶部 -->
    23                 <interceptor-ref name="defaultStack"></interceptor-ref> <!--调用struts默认的拦截器-->
    24             </interceptor-stack>
    25         </interceptors>
    26 
    27         <!--浏览器输入http://localhost:8080/strutsstu4/index并访问,会触发拦截器的执行,计算拦截器执行的时间-->
    28         <action name="index">
    29             <result >/index.jsp</result>
    30             <interceptor-ref name="myTimeStack"></interceptor-ref>  <!-- 当访问index这个actio时,让myTimeStack这个拦截器栈去进行拦截 -->
    31         </action>
    32     </package>
    33 
    34 </struts>

    (3)视图页面:

    index.jsp
     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5   <head>
     6     <title>My JSP 'index.jsp' starting page</title>
     7   </head>
     8   
     9   <body>
    10     This is index page. <br>
    11   </body>
    12 </html>

    error.jsp

     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     3 <html>
     4   <head>
     5     <title>My JSP 'success.jsp' starting page</title>
     6    </head>
     7   
     8   <body>
     9     This is  error page. <br>
    10   </body>
    11 </html>

    (4)部署并测试

    浏览器输入http://localhost:8080/strutsstu4/index并访问,会触发拦截器的执行,控制台打印拦截器执行的时间,页面跳转到index.jsp,如下:

    如果访问一个没有对应action的URL,比如   http://localhost:8080/strutsstu4/sss 则执行默认的action,替换调404报错页面

     

    示例代码下载地址   https://github.com/liuch0228/Struts2SSH.git 

  • 相关阅读:
    无限维
    黎曼流形
    why we need virtual key word
    TOJ 4119 Split Equally
    TOJ 4003 Next Permutation
    TOJ 4002 Palindrome Generator
    TOJ 2749 Absent Substrings
    TOJ 2641 Gene
    TOJ 2861 Octal Fractions
    TOJ 4394 Rebuild Road
  • 原文地址:https://www.cnblogs.com/enjoyjava/p/8997405.html
Copyright © 2011-2022 走看看