自定义拦截器
我们需要实现HandlerInterceptor接口来自定义拦截器。HandlerInterceptor接口中有三个默认方法:
boolean preHandle(...)
void postHandle(...)
void afterCompletion(...)
- preHandle: 方法执行前拦截。返回false表示请求终止。
- postHandle : 方法执行完,在返回视图前拦截。
- afterCompletion : 都有都执行完成,或者异常时拦截。
结合这三个方法的特性,我们可以根据需求来实现自己的拦截器。
先简单的来实现第一个拦截器:
public class MyFirstInterceptor implements HandlerInterceptor {
private final Logger logger = LoggerFactory.getLogger (MyFirstInterceptor.class);
@Override
public boolean preHandle (
HttpServletRequest request, HttpServletResponse response, Object handler ) throws Exception {
logger.info ("请求前拦截 :{}",request.getRequestURL () );
return true;
}
@Override
public void postHandle (
HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView ) throws Exception {
logger.info ("postHandle: {}" ,request.getRequestURL ());
}
@Override
public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
logger.info ("after:执行完成");
}
}
配置拦截器
在spring mvc 中,实现了拦截器之后,需要在web.xml中配置拦截器,而spring boot 是没有web.xml文件的,那么我们需要自己来实现这个功能。官方推荐通过实现WebMvcConfigurer接口来完成。
@Configuration //此注解相当于spring mvc 的web.xml 配置文件
public class MyMvc implements WebMvcConfigurer{
@Autowired
private MyFirstInterceptor firstInterceptor;
@Override
public void addInterceptors ( InterceptorRegistry registry) {
List<String> staticResource = new ArrayList <> ();
staticResource.add ("/js/**");
staticResource.add ("/views/**");
registry.addInterceptor (firstInterceptor).addPathPatterns ("/**").excludePathPatterns (staticResource);
}
}
在springbootApplication启动类中注入自定义的拦截器
@Bean
public MyFirstInterceptor myFirstInterceptor (){
return new MyFirstInterceptor ();
}
application.yaml 配置文件
server:
port: 882
servlet:
context-path: /
spring:
mvc:
view:
suffix: .html
prefix: /views/
static-path-pattern: /**
resources:
static-locations: classpath:/templates/,classpath:/static/
添加一个controller
@RequestMapping ("/test")
String test () {
logger.info ("controller 逻辑处理。。。");
return "index";
}
浏览器请求 http://localhost:881/test 可以看到拦截器中三个方法的执行顺序。
INFO 5456 --- [-nio-881-exec-1] c.f.i.s.config.MyFirstInterceptor : 请求前拦截 :http://localhost:881/test
INFO 5456 --- [-nio-881-exec-1] c.f.i.s.controller.TestController : controller 逻辑处理。。。
INFO 5456 --- [-nio-881-exec-1] c.f.i.s.config.MyFirstInterceptor : postHandle: http://localhost:881/test
INFO 5456 --- [-nio-881-exec-1] c.f.i.s.config.MyFirstInterceptor : after:执行完成
多个拦截器
有时根据需求,我们需要多个拦截器。跟MyFirstInterceptor一样,再来实现两个自定义拦截器分别是MySecondInterceptor ,MyThirdInterceptor。改造一下MyMvc
@Configuration //此注解相当于spring mvc 的web.xml 配置文件
public class MyMvc implements WebMvcConfigurer{
@Autowired
private MyFirstInterceptor firstInterceptor;
@Autowired
private MySecondInterceptor secondInterceptor;
@Autowired
private MyThirdInterceptor thirdInterceptor;
@Override
public void addInterceptors ( InterceptorRegistry registry) {
List<String> staticResource = new ArrayList <> ();
staticResource.add ("/js/**");
staticResource.add ("/views/**");
registry.addInterceptor (firstInterceptor).addPathPatterns ("/**").excludePathPatterns (staticResource);
//第三个拦截器
registry.addInterceptor (thirdInterceptor).addPathPatterns ("/**").excludePathPatterns (staticResource);;
registry.addInterceptor (secondInterceptor).addPathPatterns ("/**").excludePathPatterns (staticResource);;
}
}
执行结果
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MyFirstInterceptor : 请求前拦截 :http://localhost:881/test
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MyThirdInterceptor : MyThirdInterceptor -->请求前拦截 :http://localhost:881/test
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MySecondInterceptor : MySecondInterceptor -->请求前拦截 :http://localhost:881/test
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.controller.TestController : controller 逻辑处理。。。
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MySecondInterceptor : MySecondInterceptor --> postHandle: http://localhost:881/test
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MyThirdInterceptor : MyThirdInterceptor --> postHandle: http://localhost:881/test
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MyFirstInterceptor : postHandle: http://localhost:881/test
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MySecondInterceptor : MySecondInterceptor --> after:执行完成
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MyThirdInterceptor : MyThirdInterceptor --> after:执行完成
INFO 8256 --- [-nio-881-exec-1] c.f.i.s.config.MyFirstInterceptor : after:执行完成
根据执行结果可以看出拦截器的执行顺序跟addInterceptor()这个方法添加拦截器的先后顺序有关
preHandle这个方法时先添加,先执行。postHandle 和 afterCompletion 是先添加后执行。