springmvc拦截器基本使用

1.HandlerExecutionChain是一个执行链,当用户的请求到达DispatcherServlet的时候,DispatcherServlet会到HandlerMapping中查找对应的Handler,找到后返回的就是这个:HandlerExecutionChain,里面包含了:

1) 正确的Handler对象

2) Handler的拦截器集合,这里的拦截器对象是:HandlerInterceptor

2.拦截器接口HandlerInterceptor

其中定义了三个方法:

preHandle:预处理回调方法,在Handler执行前执行,第三个参数为处理器(Controller 实现);

返回值:true 表示继续流程(如调用下一个拦截器或处理器);

false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器;

postHandle :后处理回调方法,实现处理器的后处理(但在渲染视图之前)

afterCompletion: :整个请求处理完毕回调方法,即在视图渲染完毕时回调

当然,这个接口还有一个适配器类:HandlerInterceptorAdapter,对三个方法进行了空实现。我们可以有选择的重写想要实现的方法。

3.拦截器的执行顺序

3.1正常执行顺序

3.2异常中断执行顺序

4.自定义拦截器

拦截器1:

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

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

public class MyInterceptor1 implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("**********我是拦截器1的后置处理方法。");

    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView mv) throws Exception {
        System.out.println("**********我是拦截器1的前置处理方法。"+mv.getViewName());
    }

    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        System.out.println("**********我是拦截器1的前置处理方法。");
        return true;
    }

}

拦截器2:

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

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

public class MyInterceptor2 implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("**********我是拦截器2的后置处理方法。");

    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView mv) throws Exception {
        System.out.println("**********我是拦截器2的处理方法。"+mv.getViewName());
        
    }

    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        System.out.println("**********我是拦截器2的前置处理方法。");
        return true;
    }

}

编写控制类:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("model/")
public class InterceptorController {
    
    @RequestMapping("show")
    public ModelAndView show1(){
        
        ModelAndView mv = new ModelAndView("hello");
        
        mv.addObject("msg", "拦截器");
        System.out.println("拦截器执行了");
        return mv;
    }
}

配置自定义拦截器:

<!--配置拦截器的方式-->
<mvc:interceptors>
     <!--方式1:直接在这里配置<bean>对所有的Controller都拦截-->
     <bean class="cn.pojo.Myinterceptor1">
     <!--方式2:通过mvc:interceptor来配置,同时可以指定要拦截的路径:-->
  
     <mvc:interceptor>
        <!--指定要拦截的路径,这里可以写固定路径,也可以使用Ant风格通配符,/**代表任意层数,任意路径-->
          <mvc:mapping path="/**"/>
          <bean class="cn.pojo.Myinterceptor2">
     </mvc:interceptor>

</mvc:interceptors>        

结果:

前置方法执行到拦截器2时,返回false,那么Controller和所有拦截器的后置方法以及视图解析都不会执行了。直接执行了前面返回true的拦截器(也就是拦截器1)的完成后方法。

总结:

l 拦截器的前置方法顺序执行,如果返回true,继续。返回false,流程终止,执行前面所有返回true的拦截器的完成方法

l 拦截器的后置方法倒序执行,在Controller执行结束后,视图解析前执行。

l 拦截器完成后方法倒序执行,在视图解析后执行。无论前面是否出错或返回false,已经执行过的拦截器的完成方法都会被执行,类似于finally

原文地址:https://www.cnblogs.com/lichangyun/p/8525233.html