SpringBoot
拦截器有两种方式配置:
HandlerInterceptor
HandlerInterceptorAdapter
推荐第一种,第二种官方不推荐使用,拦截器最常用的场景是做角色权限资源控制,接口请求日志打印。
创建拦截器:HandlerInterceptorCommon
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HandlerInterceptorCommon implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURL().toString();
String method = request.getMethod();
String uri = request.getRequestURI();
System.out.println(url);
System.out.println(method);
System.out.println(uri);
//只有为true的时候才会接着走你访问的接口方法,如果为false就不会访问到你想访问的接口方法里面了
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("被拦截的方法走完之后走这");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("最后走这");
}
}
创建拦截器配置类:InterceptorConfig
实现WebMvcConfigurer
并且添加@Configuration
注解
import com.example.mybatis.demo.common.HandlerInterceptorCommon;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 自定义拦截器,添加拦截路径和排除拦截路径
registry.addInterceptor(new HandlerInterceptorCommon()).addPathPatterns("/**");
}
}
创建一个Controller
测试下:
@RestController
@RequestMapping(value = "/api")
public class UserRestController {
@PostMapping(value = "test")
public void generateUuid() {
System.out.println("走完拦截器之后接着到我这了");
}
}
preHandle
调用时间:Controller方法处理之前
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行
若返回false,则中断执行,注意:不会进入afterCompletion
postHandle
调用前提:preHandle返回true
调用时间:Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒着执行。
备注:postHandle虽然post打头,但post、get方法都能处理
afterCompletion
调用前提:preHandle返回true
调用时间:DispatcherServlet进行视图的渲染之后
多用于清理资源
## 二. 继承HandlerInterceptorAdapter
2.1 创建拦截类,继承HandlerInterceptorAdapter
2.2 创建拦截器配置类,继承WebMvcConfigurerAdapter,设置拦截路径
**补充: WebMvcConfigurer接口**
```java
addInterceptors:拦截器
addViewControllers:页面跳转
addResourceHandlers:静态资源
configureDefaultServletHandling:默认静态资源处理器
configureViewResolvers:视图解析器
configureContentNegotiation:配置内容裁决的一些参数
addCorsMappings:跨域
configureMessageConverters:信息转换器
SpringBoot—WebMvcConfigurer详解
三、也可以通过自定义注解的方式,对特地的方法进行拦截处理,虽然没有加这个自定义注解的也会被拦截,但是没这个自定义注解的直接返回true,不做拦截处理
新建自定义注解StringResult
:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface StringResult {
String value();
}
preHandle
里面就可以这样写了:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURL().toString();
String requestMethod = request.getMethod();
String uri = request.getRequestURI();
System.out.println(url);
System.out.println(requestMethod);
System.out.println(uri);
if(handler instanceof HandlerMethod){
HandlerMethod method = (HandlerMethod)handler;
StringResult stringResult = method.getMethodAnnotation(StringResult.class);
//如果没有@StringResult注解则跳过拦截
if(stringResult==null){
return true;
}else{
//这边就是写拦截的逻辑,也就是加了@StringResult注解的
}
}
//只有为true的时候才会接着走你访问的接口方法,如果为false就不会访问到你想访问的接口方法里面了
return true;
}
Java 自定义注解及使用场景