免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

SpringMVC拦截器原理与登录验证实战

SpringMVC拦截器原理与登录验证实战 1. SpringMVC拦截器核心机制解析SpringMVC拦截器是基于Java反射和动态代理实现的AOP实践其本质是通过HandlerInterceptor接口在控制器方法执行前后插入横切逻辑。与Servlet Filter不同拦截器工作在Spring上下文层面能够直接获取IoC容器中的Bean实例。1.1 拦截器三大生命周期方法public interface HandlerInterceptor { // 控制器方法执行前触发预处理 default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {} // 控制器方法执行后触发后处理视图渲染前 default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {} // 整个请求完成后触发资源清理 default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {} }预处理阶段(preHandle)的返回值决定是否继续执行后续拦截器和控制器方法。返回false时会中断执行链常用于权限校验失败时的拦截。2. 登录验证拦截器实现细节2.1 会话状态检查方案对比方案类型实现方式优点缺点Session校验request.getSession()服务端状态可靠集群环境需要会话共享Token验证解析Authorization头无状态、适合分布式需要处理Token续期Cookie检测读取加密的Cookie值实现简单安全性较低推荐采用JWTSession的混合方案用Session存储敏感权限信息用JWT实现无状态校验。2.2 完整登录拦截器实现public class AuthInterceptor implements HandlerInterceptor { private final ListString excludePaths Arrays.asList( /login, /register, /static/**); Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri request.getRequestURI(); // 放行白名单路径 if(excludePaths.stream().anyMatch(uri::startsWith)){ return true; } HttpSession session request.getSession(false); if(session null || session.getAttribute(user) null) { response.sendRedirect(/login?redirect URLEncoder.encode(uri, UTF-8)); return false; } return true; } }关键细节session.getSession(false)参数避免自动创建新会话防止内存泄漏3. 拦截器执行流程深度剖析3.1 典型执行时序图用户请求/admin/dashboardDispatcherServlet确定HandlerMapping执行拦截器链preHandle()方法按注册顺序正向执行任一返回false则终止流程实际控制器方法执行执行拦截器链postHandle()方法按注册顺序逆向执行视图渲染执行afterCompletion()方法按注册顺序逆向执行即使控制器抛出异常也会执行3.2 多拦截器协作示例Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LogInterceptor()) .order(1) .addPathPatterns(/**); registry.addInterceptor(new AuthInterceptor()) .order(2) .addPathPatterns(/admin/**); } }执行顺序LogInterceptor#preHandleAuthInterceptor#preHandleController方法AuthInterceptor#postHandleLogInterceptor#postHandleAuthInterceptor#afterCompletionLogInterceptor#afterCompletion4. 生产环境实战经验4.1 性能优化要点在preHandle中进行轻量级校验如登录态将耗时操作权限树加载移到postHandle使用Order控制拦截器顺序安全类拦截器应靠后对静态资源配置excludePathPatterns4.2 常见问题排查问题1拦截器不生效检查是否被ComponentScan扫描到确认路径模式是否匹配/**会匹配所有路径查看是否有更高优先级的拦截器返回了false问题2循环重定向// 错误示例对登录页也进行拦截 public boolean preHandle(...) { if(未登录){ response.sendRedirect(/login); // 导致死循环 } }解决方案务必配置excludePaths排除登录相关URL问题3跨域拦截冲突当同时使用CORS Filter和拦截器时建议在Filter中设置基础CORS头在拦截器preHandle中处理复杂跨域逻辑确保OPTIONS请求不被拦截5. 进阶开发技巧5.1 注解式权限控制结合自定义注解实现更灵活的权限管理Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface RequireRole { String[] value(); } public class AuthInterceptor implements HandlerInterceptor { Override public boolean preHandle(...) { HandlerMethod handlerMethod (HandlerMethod)handler; RequireRole annotation handlerMethod.getMethodAnnotation(RequireRole.class); if(annotation ! null) { // 角色校验逻辑 } } }5.2 异步请求处理对于Async请求需要额外配置AsyncHandlerInterceptorpublic class AsyncAuthInterceptor extends HandlerInterceptorAdapter { Override public void afterConcurrentHandlingStarted(...) { // 异步请求开始时触发 // 可在此处清理ThreadLocal变量 } }实际项目中建议结合Spring Security进行更完善的安全控制拦截器适合处理业务层面的轻量级校验逻辑。对于需要精细权限控制的场景推荐使用PreAuthorize注解方案。
返回列表