以前在【快学springboot】6.WebMvcConfigurer配置静态资源和解决跨域里有用到WebMvcConfigurer接口来实现静态资源的映射和解决跨域请求,而且在文末还说了WebMvcConfigurer(springboot2.x以后使用该接口,springboot1.x使用WebMvcConfigurerAdapter类,不过该类已经被标识过时了)能够配置不少东西,以下:java
下面,咱们就经过代码,使用WebMvcConfigurer接口来实现一个springboot的拦截器。spring
这里都是基于以前的项目开发的,以前的WebConfig.java以下:跨域
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**")
.addResourceLocations("file:D:\"); } /** * 跨域支持 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowCredentials(true) .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH") .maxAge(3600 * 24); } } 复制代码
以前已经实现了静态资源和解决跨域问题的配置。咱们能够重写WebMvcConfigurer的addInterceptors方法来实现拦截器:springboot
@Override
public void addInterceptors(InterceptorRegistry registry) {
}
复制代码
咱们只须要经过registry.addInterceptor( )添加一个拦截器便可bash
新建一个RequestInterceptor.java,实现HandlerInterceptor接口,以下:app
@Component
public class RequestInterceptor implements HandlerInterceptor {
}
复制代码
这里别忘了加上Component注解。ide
咱们能够经过接口的方法列表查看下,咱们能够实现那些功能:post
能够看到,咱们能够实现preHandle、postHandle和afterCompletion这三个方法。ui
preHandlespa
preHandle 方法,经过字面意思不难理解,此方法会在处理每一个请求以前先执行。此方法的返回一个布尔值,若是返回为false ,表示请求结束。咱们重写该方法,直接返回一个false:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("请求进来了");
return false;
}
复制代码
而且把该拦截器在WebConfig中进行注册:
这时候启动项目,拦截器已经能够起做用了,不过这时候访问会没有返回,咱们能够经过response来返回一些信息,以下:
这时候,直接访问项目根路径:
查看控制台
若是有全局异常捕获的话,咱们还能够经过抛出异常的形式来返回值。
postHandle
这个方法是处理请求以后,可是在返回数据以前执行的。咱们能够经过这样一个方法(这个方法是以前文章里有的啦)来验证,在return处打一个端点:
@PostMapping
public Object addUser() {
Map<String, String> map = new HashMap<>();
map.put("name", "happyjava");
return "OK";
}
复制代码
实现postHandle方法,以下:
运行程序,请求接口:
在断点处停了下来,可是并无看到控制台输出了“执行了postHandle”。
afterCompletion
顾名思义,这个方法实在处理完成而且返回结果以后执行的。这个方法更可能是用来关闭一些资源的吧,好比ThreadLocal,日志MDC之类的。实现afterCompletion方法以下:
咱们在sout出打一个断点,而后发起接口请求。效果以下:
线程在断点处中止了,可是请求已经拿到了数据。不过须要注意的是,若是在处理请求出现异常的时候,该方法仍是会在返回数据以前执行的(Exception参数就是给咱们处理异经常使用的),而且你能够拿到执行时所抛出的异常信息(没有配置异常拦截器的话,若是配置饿了异常拦截器,ex会为null,因此咱们须要先把全局异常拦截器去掉)。修改controller方法以下:
@PostMapping
public Object addUser() {
// 新增一个用户
Map<String, String> map = new HashMap<>();
map.put("name", "happyjava");
throw new RuntimeException();
// return "OK";
}
复制代码
使他抛出一个异常。而后执行请求:
只是后,postman还在等待数据,而且程序执行到了断点处。而且能够看到,ex就是咱们手动抛出的异常。
把断点放掉,postman成功拿到了数据。其实咱们也能够经过这个来作一个全局异常处理器,不过彻底没有这个必要性。