Struts2拦截器

1、拦截器:拦截器和过滤器很相似。在 action 执行的前后执行。Struts2 的核心功能都是通 过拦截器来实现。

2、拦截器栈:由多个拦截器组成。

3、作用:对于 action 的一些公共处理代码可以放到拦截器中来实现。如:权限控制,日志 等等。

4、多个拦截器之间的执行是采用责任链设计模式来实现。

5、拦截器的执行流程

1、拦截器:拦截器和过滤器很相似。在 action 执行的前后执行。Struts2 的核心功能都是通 过拦截器来实现。

2、拦截器栈:由多个拦截器组成。

3、作用:对于 action 的一些公共处理代码可以放到拦截器中来实现。如:权限控制,日志 等等。

4、多个拦截器之间的执行是采用责任链设计模式来实现。

5、拦截器的执行流程

6、拦截器的实现步骤:

a) 编写拦截器(实现 Interceptor 接口或者继承 AbstractInterceptor 类)

b) struts.xml 配置拦截器

c) action 中引用拦截器

7、案例: 定义拦截器

/*** *计算 action 执行时间 */

public class TimeInterceptor extends AbstractInterceptor{

        @Override public String intercept(ActionInvocation invocation) throws Exception {

            long start=System.currentTimeMillis();

//执行下一个拦截器,当拦截器执行完后执行

            String result= invocation.invoke();

            long end=System.currentTimeMillis();

    System.out.println("执行该 Action 所用时间为: "+(end-start)+"ms");

            return result;

            }}}

 

struts.xml 配置拦截器,以及引用拦截器

<struts>

    <package name="default" extends="struts-default" namespace="/">

     <!-- 配置拦截器 -->

    <interceptors>

     <interceptor name="time"class="cn.sxt.interceptor.TimeInterceptor"/>

   </interceptors>

   <action name="hello" class="cn.sxt.action.HelloAction">

    <result>/index.jsp</result>

  <!-- 应用拦截器 -->

 <interceptor-ref name="time"/>

 </action> </package>

 </struts>

 

、拦截器的配置详解

a) 当引用了自定义拦截器时,默认拦截器将不起作用

b) 默认拦截器: struts-default.xml 中,配置了默认拦截器。当配置默认拦截器以后,

如果不引用拦截器,那么默认的拦截器将起作用。

    <default-interceptor-ref name="defaultStack"/>

c) 当引用自定义拦截器后,又想使用 struts2 提供的拦截器功能,那么需要手动引用

<action name="hello" class="cn.sxt.action.HelloAction">

<result>/index.jsp</result>

 <!-- 引用拦截器 --> <interceptor-ref name="time"/>

 <!-- 引用默认的拦截器栈 ;引用拦截器和引用拦截器栈的方式一 -->

  <interceptor-ref name="defaultStack"/> </action>

 

action 引用的拦截器个数比较多时,可以将多个拦截器放入一个拦截器栈中

<!-- 一个拦截器栈中,可以包含多个拦截器的引用 拦截器栈的引用和拦截器一致 -->

 <interceptor-stack name="myStack">

<!-- 引用拦截器 --> <interceptor-ref name="time"/>

<!-- 引用默认的拦截器栈 ;引用拦截器和引用拦截器栈的方式一样-->

<interceptor-ref name="defaultStack"/>

<action name="hello" class="cn.sxt.action.HelloAction">

 <result>/index.jsp</result> <interceptor-ref name="myStack"/> </action>

 

 当自定义拦截器栈在这个包下的所有 action 都使用的时,可以定义为默认的拦截器 栈,或默认的拦截器

    <!-- 定义默认的拦截器/ -->

<default-interceptor-ref name="myStack"/>

    <action name="hello" class="cn.sxt.action.HelloAction">

    <result>/index.jsp</result>

    </action>

 

拦截器的运用案例:

对于登录权限的控制: 拦截器的实现:

public class LoginInterceptor extends AbstractInterceptor{

        @Override public String intercept(ActionInvocation invocation) throws Exception {

            //判断是否是 login.action 如果是则直接执行下一个拦截器

            //如果不是 则判断是否登录,如果登录执行下一个拦截器

            //如果没有则返回登录页面 //actionName 没有扩展名

            String actionName=invocation.getProxy().getActionName();

            if("login".equals(actionName)){

                return invocation.invoke();

            }

            Object obj = invocation.getInvocationContext().getSession().get("user");

            if(obj==null){//没有登录 return Action.LOGIN; }

                return invocation.invoke();

                }

               }

            }

        }

    }

 

Struts.xml 的配置

<struts> <package name="default" extends="struts-default" namespace="/">

<!-- 配置拦截器 --> <interceptors> <interceptor name="time" class="cn.sxt.interceptor.TimeInterceptor"/>

<interceptor name="loginInterceptor" class="cn.sxt.interceptor.LoginInterceptor"/>

 <!-- 一个拦截器栈中,可以包含多个拦截器的引用 拦截器栈的引用和拦截器一致 -->

 <interceptor-stack name="myStack"> <interceptor-ref name="loginInterceptor"/>

 <!-- 引用拦截器 -->

  <interceptor-ref name="time"/>

   <!-- 引用默认的拦截器栈 ;引用拦截器和引用拦截器栈的方 式一样-->

   <interceptor-ref name="defaultStack"/>

    </interceptor-stack> </interceptors>

    <!-- 定义默认的拦截器/ --> <default-interceptor-ref name="myStack"/>

    <global-results> <result name="login">/login.jsp</result>

</global-results> <action name="hello" class="cn.sxt.action.HelloAction">

 <result>/WEB-INF/index.jsp</result> </action>

 <action name="login" class="cn.sxt.action.LoginAction">

 <result>/success.jsp</result>

 </action> </package>

 </struts>

 

 页面

<body>

 <form action="user/login.action" method="post">

 用户名:<input type="text" name="name"/><br>

  密码:<input type="password" name="pwd"/><br>

  <input type="submit" value=" "/>

   </form>

   </body>

 

Action 代码

    public class LoginAction {

        private String name; private String pwd;

        //处理方法

        public String execute(){

            System.out.println(name+"---"+pwd);

            if("siggy".equals(name)&&"1111".equals(pwd)){

                ActionContext.getContext().getSession().put("user", name);

                return "success"; }else{ return "login"; }

            }

        public String logout(){ System.out.println("退出"); return"success"; }

        public String getName() { return name; } public void setName(String name) { this.name = name; }

        public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; }

 }

 

10、方法拦截器:方法拦截器时比 Action 拦截器更加细粒度的控制,主体实现和 Action 截器一致。但是方法拦截器时继承 MethodFilterInterceptor 类,重写 doIntercept()方法。 引用方法拦截器配置会发生改变:

<interceptor-ref name="methodInterceptor">

<!-- 配置被拦截的方法 -->

<param name="includeMethods">list,add</param>

<!-- 配置不被拦截的方法 -->

<param name="excludeMethods">login</param> </interceptor-ref>