15. 在 Spring Boot 中怎么使用拦截器的?
在Spring Boot中,拦截器(Interceptor)是一种非常强大的机制,用于在处理请求之前和之后执行某些操作。拦截器类似于过滤器,但比过滤器更灵活,通常用于在不改变控制器逻辑的情况下实现统一的处理逻辑,比如记录日志、权限校验等。
1. 什么是拦截器?
拦截器是一种AOP(面向切面编程)的实现,它可以在请求到达控制器之前、控制器处理请求之后以及视图渲染之前执行特定的操作。Spring的拦截器通过实现HandlerInterceptor
接口来定义拦截逻辑。
2. 创建一个拦截器
首先,需要创建一个拦截器类。这个类要实现HandlerInterceptor
接口,并覆盖其方法:
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
:- 在请求处理之前执行,返回
true
继续执行请求,返回false
中断请求处理。
- 在请求处理之前执行,返回
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
:- 在请求处理完毕后执行,但在视图渲染之前执行,可以用来修改ModelAndView或处理其他逻辑。
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
:- 在整个请求完成后执行,通常用于清理资源或记录日志等收尾工作。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Pre Handle method is Calling");
return true; // 继续执行请求
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Post Handle method is Calling");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("Request and Response is completed");
}
}
3. 注册拦截器
拦截器需要注册到Spring的拦截器链中。可以通过实现WebMvcConfigurer
接口并覆盖addInterceptors
方法来注册自定义的拦截器。
import org.springframework.beans.factory.annotation.Autowired;
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 WebConfig implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor)
.addPathPatterns("/api/**") // 拦截路径
.excludePathPatterns("/api/login", "/api/register"); // 排除的路径
}
}
addPathPatterns
:指定拦截的URL模式,可以使用通配符,比如/api/**
。excludePathPatterns
:指定不需要拦截的URL模式。
4. 配置多个拦截器
如果需要配置多个拦截器,可以在addInterceptors
方法中按顺序注册多个拦截器。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
@Autowired
private AnotherInterceptor anotherInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor)
.addPathPatterns("/api/**");
registry.addInterceptor(anotherInterceptor)
.addPathPatterns("/admin/**");
}
}
在这种情况下,拦截器的执行顺序是按照它们被注册的顺序来的。第一个拦截器先执行preHandle
方法,最后一个拦截器最后执行postHandle
和afterCompletion
方法。
5. 在拦截器中处理登录验证
拦截器的一个常见应用场景是处理登录验证。可以在拦截器的preHandle
方法中检查用户是否已登录,如果未登录则重定向到登录页面或返回错误信息。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 这里可以加入登录验证的逻辑
Object user = request.getSession().getAttribute("user");
if (user == null) {
response.sendRedirect("/login"); // 未登录,重定向到登录页面
return false; // 终止请求处理
}
return true; // 已登录,继续执行请求
}
}
6. 总结
在Spring Boot中,拦截器通过实现HandlerInterceptor
接口并在配置类中注册来使用。拦截器可以在请求处理的不同阶段(如处理前、处理后、请求完成后)执行逻辑,用于实现日志记录、登录验证、权限检查等常见功能。拦截器的配置灵活,可以拦截指定的URL模式,并支持多拦截器链式处理。
通过拦截器,你可以在不改变控制器逻辑的情况下,添加统一的请求处理逻辑,是Spring MVC架构中一个非常有用的机制。