zoukankan      html  css  js  c++  java
  • 信步漫谈之Struts2—拦截器

    主要介绍Struts2的拦截器,结合实例说明。

    代码结构:

    image

    关键代码:

    LoginCheckInterceptor.java
    MapParametersInterceptor.java
    TimeInterceptor.java
    LoginAction.java
    RegistAction.java
    UserAction.java
    User.java
    main.jsp
    login.jsp
    regist.jsp
    struts.xml

    实例程序中定义了三个拦截器:TimeInterceptor、MapParametersInterceptor、LoginCheckInterceptor,分别是时间捕捉、Map传值、登陆验证功能。

    TimeInterceptor实现了Interceptor接口,该接口是Struts2中拦截器的祖先,所有拦截器的最终实现。该接口有三个方法,分别是init、destory、intercept,分别是初始化时执行、销毁时执行、以及具体的拦截操作。同时,Struts2中还定义了一个抽象类AbstractInterceptor,该类实现了Interceptor接口,并空实现了init和destory方法,所以我们也可以直接通过继承AbstractInterceptor类来自定义拦截器(好处是不用实现init和destory方法,和实现Interceptor接口的区别也就在此,实际上这两个方法一般不会去使用)

    LoginCheckInterceptor继承自抽象类MethodFilterInterceptor,MethodFilterInterceptor类在AbstractInterceptor的基础上添加了方法过滤,所谓的方法过滤就是允许我们指定哪些action方法要进行拦截处理,哪些action方法不进行action拦截处理,分别定义在excludeMethods(不拦截)和includeMethods(要拦截)中。以下是相关的源码,可以看到MethodFilterInterceptor在intercept实现里添加了一层判断applyInterceptor,用于判断是否执行拦截。也因此继承自MethodFilterInterceptor的子类一般不去实现intercept方法,而是实现MethodFilterInterceptor提供的doIntercept方法(应为如果不实现doIntercept而直接实现intercept,那就等于没继承MethodFilterInterceptor)

    MethodFilterInterceptor.java
    MethodFilterInterceptorUtil.java

    MapParametersInterceptor继承自ParametersInterceptor类,ParametersInterceptor主要功能是实现参数过滤处理,他继承自MethodFilterInterceptor类,可以定义拦截判断参数名长度,参数格式。。。,我们通过继承ParametersInterceptor实现对参数的操作,MapParametersInterceptor重载了setParameters方法,实现的功能是将不是对象的参数(例如:user.username)存放至map中(例如:username->map.username),从而在传递非对象参数时不用在Action中定义大量的属性,而是只需要定义一个map,所有的传递参数都可以从map中获取。

    拦截器最关键的方法就是intercept或doIntercept,这是实现具体拦截操作的位置,该方法一个类型为ActionInvocation的参数,通过这个参数我们可以获取到ActionContext对象、调用的Action类名、调用的Action方法等等,方便我们在拦截器中对被拦截Action的判断以及操作。

    //获取拦截Action类名
    Class<?> cls = invocation.getAction().getClass();
    //获取拦截Action方法名
    String method = invocation.getProxy().getMethod();
    //获取ActionContext
    ActionContext actionContext = invocation.getInvocationContext();

    拦截器在struts.xml中的定义

    拦截器定义在interceptors标签中,定义拦截器名称和拦截器类:

    <interceptor name="TimeInterceptor" class="com.alfred.interceptor.TimeInterceptor" />

    拦截器栈定义在interceptors标签中,栈内包含有一系列的拦截器引用,之后加载拦截器栈就可以一次性加载该栈内的所有拦截器:

    <interceptor-stack name="myDefaultStack">
        <interceptor-ref name="TimeInterceptor"></interceptor-ref>
        <interceptor-ref name="MapParametersInterceptor"></interceptor-ref>
        <!-- 判断是否已登录 -->
        <interceptor-ref name="LoginCheckInterceptor">
            <!-- 允许执行的方法 如下只有execute这个方法允许调用该拦截器
            <param name="includeMethods">execute</param> -->
            <!-- 不允许执行的方法 如果有和includeMethods相同的,以includeMethods为主
            <param name="excludeMethods">loginAction,registAction</param> -->
        </interceptor-ref>
    </interceptor-stack>

    默认拦截器定义在package下,所谓默认拦截器,就是action在没有加载拦截器的情况下,默认加载的拦截器,通过查看struts-default.xml配置,我们可以看到struts为我们定义的默认拦截器是defaultStack,默认拦截器栈。

    <interceptor-stack name="defaultStack">
        <interceptor-ref name="exception"/>
        <interceptor-ref name="alias"/>
        <interceptor-ref name="servletConfig"/>
        <interceptor-ref name="i18n"/>
        <interceptor-ref name="prepare"/>
        <interceptor-ref name="chain"/>
        <interceptor-ref name="scopedModelDriven"/>
        <interceptor-ref name="modelDriven"/>
        <interceptor-ref name="fileUpload"/>
        <interceptor-ref name="checkbox"/>
        <interceptor-ref name="datetime"/>
        <interceptor-ref name="multiselect"/>
        <interceptor-ref name="staticParams"/>
        <interceptor-ref name="actionMappingParams"/>
        <interceptor-ref name="params"/>
        <interceptor-ref name="conversionError"/>
        <interceptor-ref name="validation">
            <param name="excludeMethods">input,back,cancel,browse</param>
        </interceptor-ref>
        <interceptor-ref name="workflow">
            <param name="excludeMethods">input,back,cancel,browse</param>
        </interceptor-ref>
        <interceptor-ref name="debugging"/>
        <interceptor-ref name="deprecation"/>
    </interceptor-stack>
    
    <default-interceptor-ref name="defaultStack"/>

    可以看到defaultStack中引用了大量的拦截器,需要提到的一点就是,如果我们action中引用了一个拦截器,那么就不会再加载默认拦截器了,所以如果想要在action中引用拦截器后仍旧可以使用默认拦截器中的拦截,需在手动加上默认拦截器的引用。

    另外,无论是拦截器的引用还是拦截器中都可以加入配置参数,例如:includeMethods、excludeMethods等等,具体参数可以查看API或者看对应拦截器类的属性参数。

  • 相关阅读:
    我用自己做的图书比价搜索买了一本书
    2.17
    最近的工作
    FireBug的Bug
    2.18
    tecent面试题解答
    .net杂记
    python的round测试
    最近在网上买书的体会
    关于迅雷评论的一个改造html css
  • 原文地址:https://www.cnblogs.com/alfredinchange/p/5349905.html
Copyright © 2011-2022 走看看