一、概述
在Spring Boot中,拦截器是一种用于拦截和处理HTTP请求的机制。它是Spring框架提供的一种中间件,用于在请求到达控制器(Controller)之前或之后执行一些共享的逻辑。
Spring Boot的拦截器基于Spring MVC框架中的HandlerInterceptor接口实现。通过创建一个自定义的拦截器类并实现HandlerInterceptor接口,可以定义拦截器要执行的逻辑和行为。
二、定义拦截器
在Spring Boot中定义拦截器十分的简单,只需要创建一个拦截器类,并实现HandlerInterceptor接口即可。
HandlerInterceptor接口中定义以下3个方法,如下表:
返回值类型方法声明描述booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作,返回true表示继续向下执行,返回false表示中断后续操作。voidpostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)该方法在控制器处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步修改。voidafterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)该方法在视图渲染结束后执行,可以通过此方法实现资源清理、记录日志信息等工作。它接收三个参数:
- HttpServletRequest request: 表示当前的HTTP请求
- HttpServletResponse response: 表示当前的HTTP响应
- Object handler: 表示被拦截的处理器(一般是Controller中的方法)
三、使用拦截器
3.1 自定义拦截器
- @Component
- public class LoginInterceptor implements HandlerInterceptor {
- //调用目标方法之前执行的方法
- //如果返回ture表示拦截器验证成功,执行目标方法
- //如果返回false表示拦截器验证失败,不再继续执行后续业务
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
- Object handler) throws Exception {
- //用户登录判断业务
- HttpSession session = request.getSession(false);
- if (session != null && session.getAttribute("session_userinfo") != null) {
- //用户已登录
- return true;
- }
- response.setStatus(401);
- return false;
- }
- }
复制代码 代码中的preHandle方法是拦截器的主要方法,在目标方法调用之前执行。
在preHandle方法中,首先通过request.getSession(false)获取当前请求的HttpSession对象(如果存在的话),然后判断该HttpSession对象是否为null并且是否存在名为"session_userinfo"的属性。如果这个条件成立,说明用户已经登录,可以继续执行后续的业务,于是返回true,否则验证失败,将HTTP响应的状态码设置为401,表示未授权,然后返回false,不再继续执行后续业务。
3.2 注册拦截器
- @Configuration
- public class MyConfig implements WebMvcConfigurer {
- //注入
- @Autowired
- private LoginInterceptor loginInterceptor;
- //将拦截器
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(loginInterceptor)
- .addPathPatterns("/**") //拦截所有的 url
- .excludePathPatterns("/user/login")//排除url: /user/login (登录)
- .excludePathPatterns("/user/reg") //排除url: /user/reg (注册)
- .excludePathPatterns("/image/**")//排除 image(图像) 文件夹下的所有文件
- .excludePathPatterns("/**/*.js")//排除任意深度目录下的所有".js"文件
- .excludePathPatterns("/**/*.css");
- }
- }
复制代码 UserController:- @RestController
- @RequestMapping("/user")
- public class UserController {
- @RequestMapping("/login")
- public String login(){
- return "login";
- }
- @RequestMapping("/index")
- public String index(){
- return "index";
- }
- @RequestMapping("/reg")
- public String reg(){
- return "reg";
- }
- }
复制代码 在配置类中,重写了addInterceptors方法,该方法用于注册拦截器。在这里,通过调用InterceptorRegistry的addInterceptor方法来添加拦截器,并设置拦截的路径和排除的路径。
具体地,通过调用addInterceptor(loginInterceptor)来添加LoginInterceptor拦截器。然后使用addPathPatterns方法指定需要拦截的URL路径模式,这里使用"/**"表示拦截所有的URL。使用excludePathPatterns方法来排除一些特定的URL路径,这些路径不会被拦截。
"//*.js","":表示零个或多个路径段(目录或文件夹),可以匹配任意深度的目录结构。
"/*.js":表示以".js"结尾的文件名。
常见的拦截配置:
拦截路径含义举例/*拦截一级路径能拦截 /user,/login,不能拦截 /user/login/**拦截任意路径拦截所有/user/*拦截/user的下一级路径能拦截 /user/getList,不能拦截 /user/getList/1 和 /user/user/**拦截/user下的所有路径拦截/user下的所有路径,但是不能拦截 /book/getList此外拦截器不仅可以拦截项目中的URL,还可以拦截静态资源(html,图片等)。
四、执行流程
有了拦截器之后,会在调用Controller之前进行相应的业务处理,执行的流程如下图
- 添加拦截器后,执行Controller的方法之前,请求会先被拦截器拦截住。
- 执行preHandle()方法,这个方法需要返回一个布尔类型的值。
- 如果返回true,就表示放行本次操作, 继续访问controller中的方法。
- 如果返回false,则不会放行(controller中的方法也不会执行)。
- controller当中的方法执行完毕后,再回过来执行postHandle()这个方法以及afterCompletion()方法。
- 执行完毕之后,最终给浏览器响应数据。
五、实际案例
5.1 统一访问前缀添加
所有请求地址添加test前缀:在WebMvcConfigurer接口中,configurePathMatch方法用于配置路径匹配规则。
[code]@Configurationpublic class MyConfig implements WebMvcConfigurer { //统一访问前缀的添加 @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.addPathPrefix("test", new Predicate |