您的位置:首页 > 编程语言 > Java开发

springmvc学习笔记(28)——自定义拦截器

2015-04-29 11:53 573 查看
自定义拦截器

配置拦截器的作用范围

多个拦截器的调用顺序

特殊情况

1. 自定义拦截器

在之前的一篇笔记中有使用到拦截器,当时没有对拦截器做解释,在这里:springmvc学习笔记(13)——国际化资源文件

所谓的拦截器,就是用来拦截请求,因此我们可以对用户发来的请求做处理。

写一个类,实现拦截器的接口

package com.zj.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class FirstInterceptor implements HandlerInterceptor{

    /**
     * 该方法在 目标方法之前被调用
     * 可以用来做 权限,日志,事务
     * 若 return false,后续的拦截器和目标方法将不被调用
     * 若 return true,后续的拦截器和目标方法正常调用
     */
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    /**
     * 该方法在 目标方法之后,渲染视图之前 被调用
     * 可以用来 修改请求域,修改目标视图等
     */
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        System.out.println("postHandle");

    }
    /**
     * 该方法在 目标方法被调用,渲染视图之后被调用
     * 可以用来 释放资源
     */
    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("afterCompletion");

    }

}


代码中已经有了详细的注释,包括三个方法的调用顺序方法

在三个方法中打印出一句话,以便我们能看到效果

让拦截器起作用,就要在springmvc配置文件中配置

<!-- 拦截器 -->
    <mvc:interceptors>
        <!-- 配置自定义的拦截器 -->
        <bean class="com.zj.interceptor.FirstInterceptor"></bean>
    </mvc:interceptors>


到这里,配置就完成了,访问任意目标方法,控制台打印出如下结果



2. 配置拦截器的作用范围

<mvc:interceptors>

        <!-- 配置自定义的拦截器 -->
        <bean class="com.zj.interceptor.FirstInterceptor"></bean>

        <mvc:interceptor>
            <!-- 只有访问/hello这个路径,拦截器才起作用 -->
            <mvc:mapping path="/hello"/>
            <!-- 
                除了/index这个路径,其他都起作用
                <mvc:exclude-mapping path="/index"/>
             -->
            <bean class="com.zj.interceptor.SecondInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>



在最外层是一个mvc:interceptors,在里面,我们又配置了一个mvc:interceptor。请注意,前者有s,后者没有。

在mvc:interceptor中,我们可以配置拦截器SecondInterceptor的作用范围,只作用于某个路径或者只有某个路径不被作用



3. 多个拦截器的调用顺序

上面我们配了两个拦截器,现在我们来测试以下他们的调用顺序

访问某个路径,控制台打印出如下结果




在配置文件中,FirstInterceptor拦截器的配置在SecondInterceptor前面

根据结果分析可以得到,preHandle()方法的调用顺序和拦截器的配置顺序一致

postHandle()和afterCompletion()方法的调用顺序则是反序



4. 特殊情况

刚刚的例子中,FirstInterceptor和SecondInterceptor两个拦截器的preHandler方法都是return true,因此后面的方面都可以正常执行。

现在假设SecondInterceptor的preHandle返回false,会怎样?我们来看结果截图




从结果中看到,FirstInterceptor 的preHandle先被执行,这没问题

然后执行SecondInterceptor的preHandle,它返回false,因此后续的目标方法都不被执行,但是,FirstInterceptor的afterCompletion方法居然被执行了。

如果从源码分析,可以明白这是为什么,但是对于大多数人来说这太难。

我们从这个结果中总结出一个结论:一个拦截器一旦preHandle被执行return true,那么它就一定要释放资源(之前说过afterCompletion方法用来释放资源)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: