zoukankan      html  css  js  c++  java
  • (转)关于struts2的自定义拦截器和struts2的详细流程

    转自 http://www.94cto.com/index/Article/content/id/63218.html。话说,写的真不错。

    1.其实我们大家平常都会用struts2用的很多,但是有的时候我们并不是真正的了解struts2的运行机制,下面给大家分享一下struts2的运行流程。MVC框架

    解释如下:

    1. 所有请求被Struts2核心控制器StrutsPreparaedAndExecuteFilter拦截

    2.根据ActionMapper提供的信息决定如何进行下一步

    3.ActionMapper主要依赖Struts2的配置文件struts.xml

    4.接下来为每个Action创建Action代理类ActionProxy

    5.执行ActionProxy的execute()方法

    6.在执行execute()方式时会逐个执行Struts2中的拦截器

    7.执行完成拦截器后才会真正执行目标Action

    8.目标Action需要返会转向的视图名称

    9.ActionProxy取得视图名称对象Result完成转向

    10.生成resposne对象完成本次请求

    2.在struts2中默认有18个拦截器,他们帮助完成很多的工作,比如像处理异常啊,国际化,文件上传等等18个拦截器如下,如果没有拦截器我们都没法为属性设值,所以在struts2的xml文件中,我们必须需要extends=“struts-defalut”。

    <span style="font-size:18px;"><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="debugging"/>
                    <interceptor-ref name="scopedModelDriven"/>
                    <interceptor-ref name="modelDriven"/>
                    <interceptor-ref name="fileUpload"/>
                    <interceptor-ref name="checkbox"/>
                    <interceptor-ref name="multiselect"/>
                    <interceptor-ref name="staticParams"/>
                    <interceptor-ref name="actionMappingParams"/>
                    <interceptor-ref name="params">
                      <param name="excludeParams">dojo..*,^struts..*</param>
                    </interceptor-ref>
                    <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-stack></span>

    3.如果我们想扩展框架的功能,那么我们就需要自己写拦截器,那么如何来实现拦截器呢?

    ① 首先在创建计算action执行时间拦截器时,两种方法,继承父类:AbstractInterceptor,实现接口:Interceptor。重写里边的方法:intercept()方法。代码如下:

    第一种方式:

    import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    
    public class MyLogInterceptor extends AbstractInterceptor {
    
            @Override
            public String intercept(ActionInvocation invocation) throws Exception {
                    System.out.println("开始记录日志");
                    //继续执行(调用后面的拦截器(取决于actionInvocation放置拦截器的迭代器中是否存在拦截器)
                    //如果存在拦截器就执行拦截器,否则执行Action)
                    String resultCode = invocation.invoke();
                    System.out.println("结束记录日志");
                    return resultCode;
            }
    
    }

    第二种方式

    import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.Interceptor;
    
    public class MySecurityInterceptor implements Interceptor {
    
            public void destroy() {
            }
    
            public void init() {
            }
    
            public String intercept(ActionInvocation invocation) throws Exception {
                    System.out.println("开始检查安全性");
                    //继续调用
                    String resultCode = invocation.invoke();
                    System.out.println("结束检查安全性");
                    return resultCode;
            }
    
    }

    ②然后struts.xml中需要声明我们拦截器,如果直接声明,那么我们默认的18个拦截器将不起作用,如何配置及时每个action都能起到作用,又是所有的拦截器都执行呢?需要利用到拦截器栈来对框架默认的拦截器栈进行覆盖:(代码如下)

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
            <!-- 当struts.xml配置文件发生修改,会立刻加载,在生产环境下最好不要配置 -->
            <constant name="struts.configuration.xml.reload" value="true"/>
            <!-- 会提供更加友好的提示信息 -->
            <constant name="struts.devMode" value="true"/>
            <!-- 需要继承struts-default包,这样就拥有的最基本的功能 -->
            <package name="struts2" extends="struts-default">
                    <interceptors>
                            <!-- 定义记录日志拦截器 -->
                            <interceptor name="myLogInterceptor" class="com.bjpowernode.struts2.MyLogInterceptor"/>
                            <!-- 定义检查安全性拦截器 -->
                            <interceptor name="mySecurityInterceptor" class="com.bjpowernode.struts2.MySecurityInterceptor"/>
                            
                            <interceptor-stack name="myInterceptorStack">
                                     <interceptor-ref name="defaultStack"/>
                                     <interceptor-ref name="myLogInterceptor"/>
                                     <interceptor-ref name="mySecurityInterceptor"/>
                            </interceptor-stack>
                    </interceptors>
                    <!-- 定义为缺省拦截器,所有的Action都会得到使用 -->
                    <default-interceptor-ref name="myInterceptorStack"/>           
                    <action name="login" class="com.bjpowernode.struts2.LoginAction">
                            <!-- 
                                    使用日志记录拦截器 
                                    如果自定了拦截器,必须显示引用Struts2默认的拦截器
                            <interceptor-ref name="myLogInterceptor"/>
                            -->
                        <!-- 引用Struts2默认的拦截器 -->
                        <!-- 
                        <interceptor-ref name="defaultStack"/>
                         -->
                            <!-- 使用日志记录拦截器  -->
                            <!-- 
                            <interceptor-ref name="myLogInterceptor"/>
                             -->
                            <!-- 使用检查安全性拦截器 -->
                            <!-- 
                            <interceptor-ref name="mySecurityInterceptor"/>
                             -->
                             <!-- 引入自定义的拦截器栈 -->
                            <!-- 
                            <interceptor-ref name="myInterceptorStack"/>
                             -->
                            <result>/login_success.jsp</result> 
                            <result name="error">/login_error.jsp</result>
                    </action>
            </package></struts>

    4.总结一下

    Struts2的拦截器

    1、Struts2的拦截器只能拦截Action,拦截器是AOP的一种思路,可以使我们的系统架构更松散(耦合度低),可以插拔,容易互换,代码不改变的情况下很容易满足客户需求其实体现了OCP

    2、如何实现拦截器?(整个拦截器体现了责任链模式,Filter也体现了责任链模式)

      * 继承AbstractInterceptor(体现了缺省适配器模式)

      * 实现Interceptor

    3、如果自定了拦截器,缺省拦截器会失效,必须显示引用Struts2默认的拦截器

    4、拦截器栈,多个拦截器的和

    5、定义缺省拦截器<default-interceptor-ref>,所有的Action都会使用

    6、拦截器的执行原理,在ActionInvocation中有一个成员变量Iterator,这个Iterator中保存了所有的拦截器,每次都会取得Iterator进行next,如果找到了拦截器就会执行,否则就执行Action,都执行完了拦截器出栈(其实出栈就是拦截器的intercept方法弹出栈)

     
  • 相关阅读:
    BZOJ3670: [Noi2014]动物园
    BZOJ4424: Cf19E Fairy
    BZOJ1257: [CQOI2007]余数之和
    BZOJ2438: [中山市选2011]杀人游戏
    SDOI2017第一轮
    BZOJ4820: [Sdoi2017]硬币游戏
    NOIP2016
    HDU1848 Fibonacci again and again(SG 函数)
    HDU1517 Multiply Game
    HDU1907 Jhon
  • 原文地址:https://www.cnblogs.com/zhao307/p/5422017.html
Copyright © 2011-2022 走看看