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 

  • 相关阅读:
    matlab软件-了解
    C# 自定义异常demo
    C#二进制对象copy
    asp.net 缓存依赖demo
    权限管理细粒度问题
    三层架构中的异常处理二
    如何解决复杂问题——结构化思维方式
    入职新公司如何熟悉项目
    专业工具使用与复杂大型项目设计管理
    十分钟学会 tmux
  • 原文地址:https://www.cnblogs.com/enjoyjava/p/8997405.html
Copyright © 2011-2022 走看看