• java之struts2之拦截器


    1.struts2能完成数据的设置,数据的封装,数据的类型转换,数据的校验等等。struts2是如何来完成这些功能的?struts2的所有功能都是由拦截器来完成的

    2.拦截器是struts2的核心。拦截器是一个类似于过滤器的类。在执行action的处理方法前会 先执行拦截器,然后再执行action的处理方法,然后再执行拦截器,再响应

    3. struts2的所有功能都是由拦截器来实现的,而拦截器在struts2中时可以自由配置和自由装配的。所以struts2的所有功能也都是可插拔的。并且struts2中的拦截器是可以自定义的,所以如果struts2没有提供项目所需的功能时,可以通过自定义拦截器来实现

    4. struts2的拦截器有哪些,分别有什么功能:

    • alias : 对于HTTP请求包含的参数设置别名
    • autowiring : 将某些JavaBean实例自动绑定到其他Bean对应的属性中。有点类似Spring的自动绑定,在Spring部分会详细说明
    • chain : 在Web项目开发中,以前使用Struts开发的时候经常碰到两个Action互相传递参数或属性的情况。该拦截器就是让前一个Action的参数可以在现有Action中使用。
    • conversionError : 从ActionContext中将转化类型时候发生的错误添加到Action的值域错误中,在检验的时候经常被使用来显示类型转化的错误信息
    • cookie : 从Struts2.0.7版本开始,可以把cookie注入Action中可设置的名字或值中
    • createSession : 自动创建一个HTTP的 Session, 尤其是对需要HTTP的Session的拦截器特别有用。比如下面介绍的TokenInterceptor
    • debugging : 用来对在视图间传递的数据进行调试
    • execAndWait : 不显示执行Action, 在视图上显示给用户的是一个正在等待的页面,但是Action其实是在背后正在执行着。该拦截器尤其在对进度条进行开发的时候特别有用。
    • exception : 将异常和Action返回的result相映射
    • fileUpload : 支持文件上传功能的拦截器
    • i18n : 支持国际化的拦截器
    • logger : 拥有日志功能的拦截器
    • modelDriven : Action执行该拦截器的时候,它可以从一个scope范围检索和存储model值,通过调用setModel方法去设置model的值
    • params : 将HTTP请求中包含的参数值设置到Action中
    • prepare : 假如Action继承了Preparable接口,则会调用prepare方法
    • staticParams : 对于在struts.xml文件中的Action中设置的参数设置到对应的Action中
    • scope : 在session或者application范围中设置Action的状态
    • servletConfig : 该拦截器提供访问包括HttpServletRequest和HttpServletResponse对象的Map方法
    • timer : 输出Action的执行时间
    • token : 避免重复提交的校验拦截器
    • tokenSession : 和token拦截器类似,但它还能存储提交的数据到session里
    • validation : 运行在action-validation.xml文件中定义的校验规则。(数据校验部分)
    • workflow : 在Action中调用validate检验方法。如果Action有错误则返回到 input 视图
    • store : 执行校验功能的时候,该拦截器提供存储和检索Action的所有错误和正确信息的功能
    • checkbox : 视图中如果有checkbox存在的情况,该拦截器自动将unchecked的checkbox当做一个参数(通常为false)记录下来。这样可以用一个隐藏的表单值来记录所有未提交的checkbox,而且缺省unchecked的checkbox值是布尔类型的,如果视图中checkbox的值设置的不是布尔类型,它就会被覆盖成布尔类型的值
    • profiling : 通过参数来激活或者不激活分析检测功能,前提示Web项目是在开发模式下。(涉及到调试和性能检验时使用)
    • roles : 进行权限配置的拦截器,如果登录用户拥有相应的权限才去执行某一特定的Action

    5.struts2中拦截器定义的位置在struts-default.xml中

    6.自定义拦截器步骤

    a) 编写类,实现Interceptor接口

     

    public class ActionExecuteTimeInterceptor implements Interceptor{
    
        @Override
        public void destroy() {
            
        }
    
        @Override
        public void init() {
            
        }
    
        @Override
        public String intercept(ActionInvocation invocation) throws Exception {
            long start=System.currentTimeMillis();
            //执行下一个拦截器  如果下面没有拦截器则执行action的处理方法,并将结果返回
            String result = invocation.invoke();
            System.out.println("执行时间为:"+(System.currentTimeMillis()-start));
            return result;
        }
    
    }

     

    b) struts.xml中配置拦截器

     

    <!-- 拦截器配置 -->
    <interceptors>
       <!-- 配置自定义拦截器
            name 是唯一的
            class 是自定义拦截器的完全限定名
       -->
       <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor>
    </interceptors>

    c) 在对应action中 引用自定义拦截器

    <package name="default" extends="struts-default" namespace="/">
            <!-- 拦截器配置 -->
            <interceptors>
                <!-- 配置自定义拦截器
                    name 是唯一的
                    class 是自定义拦截器的完全限定名
                 -->
                <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor>
            </interceptors>
            <action name="add" class="cn.sxt.action.UserAction" method="add">
                <result>/success.jsp</result>
                <!-- 在action中引用自定义的拦截器 -->
                <interceptor-ref name="executeTime"></interceptor-ref>
            </action>
        </package>

    7.自定义拦截器有两种方式实现一种实现Interceptor接口还可以继承AbstractInterceptor类来实现:如:

    public class HelloInterceptor extends AbstractInterceptor{
    
        @Override
        public String intercept(ActionInvocation invocation) throws Exception {
            System.out.println("hello interceptor 被执行");
            return invocation.invoke();
        }
        
    }

    8.如果引用了自定义拦截器,那么struts2的拦截器将不再起作用。如果需要使用struts2的拦截器需要手动引入。

    <action name="add" class="cn.sxt.action.UserAction" method="add">
                <result>/success.jsp</result>
                <!-- 在action中引用自定义的拦截器 -->
                <interceptor-ref name="executeTime"></interceptor-ref>
                <interceptor-ref name="helloInterceptor"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </action>

    9.当自定义拦截器比较多时,在action中引用拦截器将会变得比较麻烦,所以呢,struts2提供了拦截器栈拦截器栈是用来引用已经定义好的拦截器的。一个拦截器栈可以包括多个拦截器,引用拦截器栈的方式和引用拦截器的方式一样。

    <!-- 拦截器配置 -->
            <interceptors>
                <!-- 配置自定义拦截器
                    name 是唯一的
                    class 是自定义拦截器的完全限定名
                 -->
                <interceptor name="helloInterceptor" class="cn.sxt.interceptor.HelloInterceptor"></interceptor>
                <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor>
                <!-- 定义拦截器栈 -->
                <interceptor-stack name="myStack">
                    <interceptor-ref name="executeTime"></interceptor-ref>
                    <interceptor-ref name="helloInterceptor"></interceptor-ref>
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <action name="add" class="cn.sxt.action.UserAction" method="add">
                <result>/success.jsp</result>
                <!-- 在action中引用自定义的拦截器 -->
                <interceptor-ref name="myStack"></interceptor-ref>
            </action>

    10.struts2如果没有自定义拦截器时,action类会引用默认的拦截器栈如果有自定义拦截器后,想自定义拦截器设置为默认拦截器应该如何操作?

    package中去定义一个default-interceptor-ref即可

    <!-- 设置默认拦截器 -->
            <default-interceptor-ref name="myStack"></default-interceptor-ref>
            <action name="add" class="cn.sxt.action.UserAction" method="add">
                <result>/success.jsp</result>
            </action>

    11.拦截器的使用

    登录拦截器用来实现用户登录检查

    public class LoginInterceptor extends AbstractInterceptor{
        @Override
        public String intercept(ActionInvocation invocation) throws Exception {
            //判断执行的Action是否login.action
            //如果不是 判断用户是否登录
            //如果登录了 执行下一个拦截器,如果没有登录 去登录
            //获取执行action的名称
            String actionName=invocation.getProxy().getActionName();
            if("login".equals(actionName)){
                return invocation.invoke();
            }
            Object obj=ServletActionContext.getRequest().getSession().getAttribute("currentUser");
            if(obj!=null){
                return invocation.invoke();
            }
            return Action.LOGIN;
        }
    }

    配置

    <struts>
        <package name="default" extends="struts-default" namespace="/">
            <!-- 拦截器配置 -->
            <interceptors>
                <interceptor name="loginInterceptor" class="cn.sxt.interceptor.LoginInterceptor"></interceptor>
                <interceptor-stack name="myStack">
                    <interceptor-ref name="loginInterceptor"></interceptor-ref>
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <default-interceptor-ref name="myStack"></default-interceptor-ref>
            <!-- 定义全局结果集 -->
            <global-results>
                <result name="login">/login.jsp</result>
            </global-results>
            <action name="login" class="cn.sxt.action.UserAction" method="login">
                <result>/success.jsp</result>
            </action>
            <action name="show" class="cn.sxt.action.UserAction" method="show">
                <result>/show.jsp</result>
            </action>
        </package>
    </struts>

    12.总结:

    拦截器是单列的,所有action执行的都是同一个拦截器。所以在自定义拦截器时要注意线程安全的问题。拦截器只拦截action

    13.注意过滤器和拦截器区别

    14. 方法拦截器

    方法拦截器是比拦截器更加细粒度的拦截器,只拦截方法。通过配置方法拦截器可以有效提高系统性能。

    /**
     * 自定义方法拦截器
     *
     */
    public class AddMethodInterceptor extends MethodFilterInterceptor{
    
        @Override
        protected String doIntercept(ActionInvocation invocation) throws Exception {
            System.out.println("进入方法拦截器");
            return invocation.invoke();
        }
    
    }

    配置

    <!-- 配置方法拦截器 -->
                <interceptor name="addInterceptor" class="cn.sxt.interceptor.AddMethodInterceptor">
                    <!-- 配置哪些方法 需要被拦截 -->
                    <param name="includeMethods">add</param>
                    <!-- 排除哪些方法不被拦截
                    <param name="excludeMethods"></param> -->
                </interceptor>
  • 相关阅读:
    Delphi Class of 类引用
    Class-reference types 类引用类型--快要失传的技术
    最简单的TabHost
    修改一些IntelliJ IDEA 11的设置,使Eclipse的使用者更容易上手(转)
    uva 10494
    uva748
    uva 465
    高精度
    uva 694
    uva414
  • 原文地址:https://www.cnblogs.com/Vincent-yuan/p/11154909.html
Copyright © 2020-2023  润新知