1.实现自定义的拦截器:
(1)实现HandlerInterceptor接口。
(2)继承实现了HandlerInterceptor接口的类。比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter。
public interface HandlerInterceptor {
//在请求处理之前进行调用,该方法的返回值是Boolean类型的,当它返回为false时,表示请求结束,
//后续的Interceptor和Controller都不会再执行;
//当返回值为true 时就会继续调用下一个Interceptor的preHandle方法,
//如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法。
boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception;
//该方法会在Controller方法调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之
//前被调用,并且只能是在当前所属的Interceptor的preHandle方法的返回值为true时才能被调用。
void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception;
//该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。
//这个方法的主要作用是用于进行资源清理工作的,
//并且只能是在当前所属的Interceptor的preHandle方法的返回值为true时才能被调用。
void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception;
}
2.自定义实现
(1)实现HandlerInterceptor 接口
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
//在这里可以对参数做一些预处理和做一些验证
return true;//方法给予执行,就是允许controller的方法进行执行
//false 不允许,可以在这之前在reponse中编写返回的结果
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
//Controller执行完毕后,返回之前,可以对request和reponse进行处理
//如果是前后端没有分离,在进入View层中前执行
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
//在一个请求处理完毕,即将销毁的时候,执行,可以做一些资源释放之类的工作
}
}
(2)将拦截器加入配置中
@Configuration
public class MyConfig extends WebMvcConfigurerAdapter{
@Autowired
private MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).addPathPatterns("/user/**");
}
}
3.执行顺序说明
- 首先按照执行顺序执行所有拦截器的preHandle()方法,如果遇到返回值是false,则不会执行还未执行的拦截器,而是直接倒序执行afterCompletion()方法,如果为true,则依次执行剩下的拦截器;
- 如果所有拦截器的preHandle()方法返回值都为true,则执行相应的控制层接口(controller),如果在该接口中有异常抛出,则和preHandle()方法返回false一样,不会执行postHandle(),而是直接倒序执行afterCompletion()方法;
- 如果接口(controller)中业务逻辑执行完成(页面还未渲染数据),会倒序执行postHandle()方法,渲染完数据后,然后倒序执行afterCompletton()方法。