• Struts2拦截器


     

    一、内容提要

    1.拦截器的概念及应用

    2.STRUTS2自带的拦截器

    3.自定义拦截器

    4.自定义拦截器的应用

    二、拦截器的概念及应用

    拦截器(Interceptor)是Struts2的一个重要特性。Struts2框架的大多数核心功能都是通过拦截器来实现的,像避免表单重复提交、类型转换、对象组装、验证、文件上传等,都是在拦截器的帮助下实现的。拦截器之所以称为“拦截器”,是因为它可以在Action执行之前或执行之后拦截调用。

    Struts2将它的核心功能放到拦截器中实现而不是分散到Action中实现,有利于系统的解耦,使得功能的实现类类似于个人电脑的组装,变成了可插拔的。需要某个功能就“插入”一个拦截器,不需要某个功能就“拔出”。

    拦截器应用:

    • 为action动态添加输入验证
    • 对象组装(也就是进行数据类型转换)
    • 权限控制
    • 日志记录等

    三、STRUTS2自带的拦截器

    Struts2本身提供了很多的拦截器,这些拦截器已经在struts-default.xml文件中定义,在Web应用程序中可以直接引用这些拦截器。这也是为什么struts配置文件里经常有这样一个属性extends="struts-default"加载Struts2本身提供的拦截器。

    具体情况如下:

    序号

    拦截器名称

    作用

    1

    alias

    在请求之间转换名字不同的相似参数

    2

    chain

    将所有的属性从前一个Aciotn复到当前Action中

    3

    params

    最基本的一个拦截器,负责解析HTTP请求中的参数,并将参数值设置成Action对应的属性值

    4

    cookie

    基于cookie的名/值设置Action的属性

    5

    conversionError

    将类型转换错误从ActionContext中取出,添加到Action字段错误中

    6

    createSession

    自动创建一个HttpSession对象

    7

    debugging

    当struts.devMode属性设置为true,才有,用于调试

    8

    execAndWait

    可以用于防止后台Action Http请求超时

    9

    exception

    提供了异常处理的核心功能

    10

    fileUpload

    用于对文件上传提供支持

    11

    i18n

    用于支持国际化

    12

    timer

    负责输出action的执行时间,用于分析action

    13

    token

    检查传到Action的token值的有效性,防表单重复提交

    四、自定义拦截器

    作为“框架(framework)”,可扩展性是不可或缺的,因为世上没有放之四海而皆准的东西。虽然,Struts 2为我们提供如此丰富的拦截器实现,但是这并不意味我们失去创建自定义拦截器的能力,恰恰相反,在Struts 2自定义拦截器是相当容易的一件事。

    在Struts2中编写拦截类,有如下二种方式:

    实现Interceptor此接口

    继承AbstractInterceptor类(一般会选择此种方式)

    案例:

    编写拦截器类:

    注意:在编写拦截器时要注意,拦截器必顺是无状态的,换句话 说,在拦截器类中不应该有实例变量。这是因为struts2对每一个Action的请求使用的是同一个拦截器实例来处理,如果拦截器有状态,在多线程并发情况下,拦截器的状态将不可预测。

    package com.silvan.interceptor;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    
    public class AroundInterceptor extends AbstractInterceptor {
             public void init() {
                       System.out.println("这是一个初始化方法");
             }
             public String intercept(ActionInvocation invocation) throws Exception {
                       String result = "";
                       System.out.println("我是在action的execute方法执行之前动作");
                       result = invocation.invoke();
                       System.out.println("我是在action的execute方法执行之后动作");
                      return result;
             }
             public void destroy() {
                       System.out.println("这是一个清理方法");
             }
    }

    Struts.xml配置拦截器

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
       <package name="InterceptorDemo" extends="struts-default">
           <!--在这里定义拦截器 -->
           <interceptors>
               <interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" />
           </interceptors>
           <action name="interceptor" class="com.silvan.action.InterceptorAction">
               <result>/index.jsp </result>
      <!--在这里使用拦截器,当使用自定义的拦截器后,默认的拦截器将失效,这样原本struts提供的拦截器功能就会失效,比如用于类型转换的params拦截器 -->
               <interceptor-ref name="around"/>
           </action>
        </package>
    </struts>

    Action类

    public class InterceptorAction extends ActionSupport {
    
       private int id;
    
       private String userName;
    
       @Override
    
       public String execute() throws Exception {
    
          System.out.println("执行interceptor Action……");
    
          return SUCCESS;
    
       }
    
    //Get/set……
    
    }

    页面显示Login

    <form action="interceptor">
    
            <table>
    
               <tr><td>编号:<input type="text" name="id" value="1"></td></tr>
    
               <tr><td>姓名:<input type="text" name="userName" value="ross"></td></tr>
    
               <tr><td><input type="submit" value="submit"></td></tr>
    
            </table>
    
    </form>

    返回显示index

    <body>
    
        编号:<s:property value="id"/><br/>
    
        用户名:<s:property value="userName"/>
    
      </body>

    当自定义了拦截器后,默认的拦截器将失效, index页面取不到登录的值,所以需要引入默认的拦截器。配置如下:

    Struts.xml配置拦截器

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE struts PUBLIC
    
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    
        <package name="InterceptorDemo" extends="struts-default">
    
           <!--在这里定义拦截器 -->
    
           <interceptors>
    
               <interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" />
    
                         <!-- 定义拦截器栈 -->
    
               <interceptor-stack name="myStack">
    
                  <!--引用拦截器  -->
    
                  <interceptor-ref name="around"></interceptor-ref>
    
                  <!-- 引入默认的拦截器 -->
    
                  <interceptor-ref name="defaultStack"></interceptor-ref>
    
               </interceptor-stack>
    
           </interceptors>
    
    <!—针对包引用拦截器,这样就不仅仅对某个action起作用 -->
    
    <!--       <default-interceptor-ref name="mystack"/> -->
    
           <action name="interceptor" class="com.silvan.action.InterceptorAction">
    
               <result>/index.jsp </result>
    
                <!—引用拦截器栈 -->
    
               <interceptor-ref name="myStack"/>
    
           </action>
    
        </package>
    
    </struts>

    Struts.xml配置多个拦截器方式:

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE struts PUBLIC
    
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    
        <package name="InterceptorDemo" extends="struts-default">
    
           <!--在这里定义拦截器 -->
    
           <interceptors>
    
               <interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" />
    
               <interceptor name="around1" class="com.silvan.interceptor.AroundInterceptor1" />
    
               <!-- 定义拦截器栈 -->
    
               <interceptor-stack name="myStack">
    
                  <!--引用拦截器  -->
    
                  <interceptor-ref name="around"></interceptor-ref>
    
                  <interceptor-ref name="around1"></interceptor-ref>
    
                  <!-- 引入默认的拦截器 -->
    
                  <interceptor-ref name="defaultStack"></interceptor-ref>
    
               </interceptor-stack>
    
           </interceptors>
    
    <!--       <default-interceptor-ref name="mystack"/> -->
    
           <action name="interceptor" class="com.silvan.action.InterceptorAction">
    
               <result>/index.jsp </result>
    
               <interceptor-ref name="myStack"/>
    
           </action>
    
        </package>
    
    </struts>

    五、练习

    需求分析

    在一个系统中,如果用户没有选择登录系统就直接使用相应的资源,从常理上来讲这是不允许的。也就是说在当用户访问受保护资源时,拦截器截获用户请求,判断用户是否已经登录,如果没有登录,则向用户显示登录页面,请求用户登录如果用户已经登录,则向用户显示资源。

    Action   

    public String execute() throws Exception {
    
          System.out.println("执行interceptor Action……");
    
          if(userName!=null){
    
             ActionContext context = ActionContext.getContext();
    
             Map<String,Object> session = context.getSession();
    
             session.put("userName", userName);
    
          }
    
          return SUCCESS;
    
       }

    Interceptor

    public String intercept(ActionInvocation invocation) throws Exception {
    
          String result = "";
    
          System.out.println("我是在action的execute方法执行之前动作");
    
          String user =(String) ActionContext.getContext().getSession().get("userName");
    
          if(user!=null && "".equals(user)){
    
             System.out.println("非法访问……");
    
             return "error_login";
    
          }
    
          result = invocation.invoke();
    
          System.out.println("我是在action的execute方法执行之后动作");
    
          return result;
    
       }

    配置

    <!--     <global-results name="error_login">/login.jsp</global-results> -->
    
    <!--     <default-interceptor-ref name="mystack"/> -->
    
          <action name="interceptor" class="com.silvan.action.InterceptorAction">
    
             <result>/index.jsp </result>
    
             <result name="error_login">/login.jsp</result>
    
             <interceptor-ref name="myStack"/>
    
          </action>

    思考:过滤器和拦截器的区别?

  • 相关阅读:
    Document
    Document
    Document
    Document
    Document
    Document
    set常见操作:
    select 不存在字段,并设置默认值
    c#为字段设置默认值,以及构造函数初始化List对象。
    ThreadLocal
  • 原文地址:https://www.cnblogs.com/zhouyeqin/p/7172930.html
Copyright © 2020-2023  润新知