拦截器的实现有三个点:
一是拦截器所要拦截的类(一般为 Controller )
二是拦截器处理程序(也就是拦截了请求之后,需要进行处理的方法)
三是拦截器配置(注册拦截器,设置拦截器的过滤路径规则等)
1. 写个测试 Controller
package com.gh.baseUserSystem.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author gaohan
* @version 1.0
* @date 2021/6/22 23:56
*/
@RestController
@RequestMapping(value = "/test")
@Slf4j
public class TestController {
@PostMapping(value = "/a")
public String a(){
log.info("执行了Controller的方法a");
return "a";
}
@PostMapping(value = "/b")
public String b() {
log.info("执行了Controller的方法b");
return "b";
}
}
2. 先定义一个拦截器
拦截器需要实现 HandlerInterceptor 接口,然后重写 preHandle 预处理方法(在请求处理之前进行调用,即 Controller 方法调用之前),和 postHandler 后处理方法(在拦截请求方法执行结束时调用),一般的前后端分离项目只需要用到这两个,还有一个 afterCompletion 是在渲染视图完成之后使用。这里重写了 HandlerInterceptor 接口的 preHandle 和 postHandler 方法
代码如下:
package com.gh.auth.config;
import com.gh.auth.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author gaohan
* @version 1.0
* @date 2021/6/20 22:12
*/
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {
@Autowired(required = false)
private AuthService authService;
/**
* 预处理(在请求处理之前进行调用,即Controller方法调用之前)
*
* @param request 入参
* @param response 返回参
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
log.info("执行了拦截器的preHandle方法");
log.info("handler:" + handler.toString());
return true;
}
/**
* 后处理(在拦截请求方法执行结束时调用)
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("执行了拦截器的postHandle方法");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
}
3. 拦截器做好后,需在配置类里进行拦截器注册和拦截器设置
配置类需要实现 WebMvcConfigurer 类,且需要在类上加 @Configuration 注解,以标识配置类
WebMvcConfigurer 类的常用方法如下
/* 拦截器配置 */
void addInterceptors(InterceptorRegistry registry);
/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);
/* 静态资源处理 */
void addResourceHandlers(ResourceHandlerRegistry registry);
/* 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/* 这里配置视图解析器 */
void configureViewResolvers(ViewResolverRegistry registry);
/* 配置内容裁决的一些选项 */
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/* 解决跨域问题 */
void addCorsMappings(CorsRegistry registry) ;
此处只需重写 addInterceptors 方法即可,设置哪些请求会进入拦截器,哪些请求不会被拦截
代码如下:
package com.gh.auth.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author gaohan
* @version 1.0
* @date 2021/6/20 23:22
*/
@Configuration
public class AuthConfig implements WebMvcConfigurer {
@Bean
public AuthInterceptor getAuthInterceptor(){
return new AuthInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器
InterceptorRegistration interceptorRegistration = registry.addInterceptor(this.getAuthInterceptor());
// 所有路径都会被拦截
interceptorRegistration.addPathPatterns("/**");
// 添加不拦截的路径
interceptorRegistration.excludePathPatterns("/test/b");
}
}
4. 测试验证
请求方法a,打印日志如下
请求方法b,打印日志如下
由上图可知,
请求方法 a,进入了拦截器,且拦截器里的perHandle方法执行顺序在方法 a 之前,postHandle方法执行顺序在方法 a 之后;
请求方法 b没有进如拦截器;