快速了解:
1、登录拦截使用filter过滤器或者Interceptor各自的利与弊
2、过滤器、拦截器、ControllerAdvice、Aspect的执行顺序
在Spring应用程序中,实现登录拦截的逻辑,既可以使用 Filter 过滤器,也可以使用 Interceptor 拦截器,二者各有优缺点,选择哪一种取决于具体的需求。
Filter使用场景:当你需要进行跨多个模块、甚至是跨多个 Spring 组件的统一认证(比如基于 cookie、session 或 token 的认证)时,Filter 是一个很好的选择。
Interceptor使用场景:当你需要针对某些特定的请求路径或 Controller 进行登录拦截时,使用 Interceptor 会更方便,尤其是在处理与 Spring MVC 相关的任务时。
Filter vs Interceptor
特性 | Filter | Interceptor |
执行时机 | 在 Spring MVC 之前 | 在 Spring MVC 的请求处理过程中 |
访问对象 | 只能访问 Servlet API,无法访问 Spring MVC 的上下文 | 可以访问 Spring MVC 的上下文,访问 Controller |
适用场景 | 适用于全局的登录认证、权限校验等 | 适用于精细化的请求路径、Controller 层的拦截 |
配置方式 | 配置在 web.xml 或 FilterRegistrationBean 中 | 配置在 Spring 的 @Configuration 类中 |
功能范围 | 可以处理请求和响应 | 可以处理请求、响应和业务逻辑的控制 |
Filter 过滤器
Filter 是基于 Servlet 规范的,主要用于请求和响应的预处理。它工作在请求到达 Spring MVC 的 DispatcherServlet 之前,可以非常方便地进行一些底层的操作,比如身份验证、日志记录、请求参数的修改等。
优点:
- 请求级别处理:Filter 可以拦截所有的 HTTP 请求,无论它们是来自哪一个 Controller,因此非常适合于全局的登录认证、权限检查等场景。
- 处理请求与响应:Filter 在请求到达 Spring MVC 之前就可以进行处理,可以有效拦截请求并进行身份认证。
- 不依赖于 Spring MVC:即使你的应用中没有使用 Spring MVC,Filter 也可以用来处理请求,这使得它更为通用。
缺点:
- 不支持 Spring MVC 的特性:Filter 并不直接与 Spring MVC 的拦截器机制兼容,比如无法像 Interceptor 一样访问到 HandlerMethod 或 Spring MVC 的上下文。
- 无法直接与 Controller 的业务逻辑绑定:如果需要在登录拦截中与具体的 Controller 交互或执行特定的业务逻辑,Filter 会显得较为复杂。
使用场景:当你需要进行跨多个模块、甚至是跨多个 Spring 组件的统一认证(比如基于 cookie、session 或 token 的认证)时,Filter 是一个很好的选择。
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 检查用户是否登录
if (httpRequest.getSession().getAttribute("user") == null) {
httpResponse.sendRedirect("/login"); // 未登录重定向到登录页
return;
}
chain.doFilter(request, response); // 放行,继续执行后续的过滤器或请求处理
}
@Override
public void destroy() {
}
}
2.Interceptor 拦截器
Interceptor 是 Spring MVC 框架的一部分,它允许你在请求处理的不同阶段(例如请求处理前、请求处理后、视图渲染前等)执行逻辑。拦截器更为贴近于 Spring MVC 的生命周期,因此可以更容易地访问到 Spring 的上下文、Controller 方法等。
优点:
- 与 Spring MVC 集成:拦截器可以与 Spring MVC 的 Controller 交互,获取 Controller 的执行信息,能够访问到 HandlerMethod。
- 细粒度控制:拦截器能够根据 Handler 映射来决定是否执行某个拦截器,可以精确控制拦截的范围。
- 更适合用于 Controller 层的拦截:拦截器可以在请求进入 Controller 前进行拦截,并且可以在请求结束后处理返回值。
缺点:
- 依赖于 Spring MVC:Interceptor 只能在 Spring MVC 环境下工作,如果你的项目中没有使用 Spring MVC,则无法使用拦截器。
- 执行顺序依赖于配置:如果需要处理多个拦截器,它们的执行顺序依赖于配置,可能会带来一定的复杂性。
使用场景:当你需要针对某些特定的请求路径或 Controller 进行登录拦截时,使用 Interceptor 会更方便,尤其是在处理与 Spring MVC 相关的任务时。
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 检查用户是否登录
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login"); // 未登录重定向到登录页
return false; // 返回false表示拦截,后续不会执行
}
return true; // 返回true表示继续处理请求
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 可以处理 Controller 执行后的逻辑
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 可以进行请求完成后的清理操作
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 配置拦截路径
.excludePathPatterns("/login", "/register"); // 配置不拦截的路径
}
}
过滤器、拦截器、ControllerAdvice、Aspect的执行顺序
Filter->Interceptor->ControllerAdvice->Aspect
先进后出。包括多个Filter或者多个Interceptor
阶段 | 执行顺序 | 说明 |
过滤器(Filter) | 最先执行(在DispatcherServlet之前) | 过滤器先处理请求,再传递到Spring MVC层。 |
拦截器(Interceptor) | 过滤器之后,Spring MVC中请求处理之前 | 拦截器可以对请求进行预处理和后处理。 |
Controller业务逻辑 | 拦截器之后,Controller执行请求处理 | 控制器处理实际的请求逻辑。 |
AOP(Aspect) | Controller业务逻辑前后执行 | AOP切面通常在业务逻辑之前或之后。 |
@ControllerAdvice | Controller执行后,视图渲染前 | 用于全局异常处理、数据绑定等。 |
例子:一个请求的生命周期
- 请求进入过滤器链,过滤器执行。
- 请求进入Spring MVC的DispatcherServlet。
- 执行拦截器的preHandle方法。
- DispatcherServlet将请求分发给目标Controller。
- 执行AOP切面(如在方法调用之前或之后执行)。
- Controller处理请求逻辑。
- 如果Controller抛出异常,@ControllerAdvice捕获并处理。
- 执行拦截器的postHandle方法。
- 请求返回响应,执行AOP切面(如返回后执行)。
- 执行拦截器的afterCompletion方法。
- 最终返回响应给客户端。
本文暂时没有评论,来添加一个吧(●'◡'●)