西安西部数码备案网站鹤壁市城乡一体化示范区教师招聘
西安西部数码备案网站,鹤壁市城乡一体化示范区教师招聘,c c也能干大事网站开发,品牌网站如何做目录
一、核心角色对应#xff08;责任链模式#xff09;
二、场景 1#xff1a;HandlerInterceptor 拦截器链#xff08;核心#xff09;
1. 核心流程#xff08;请求处理全生命周期#xff09;
2. 代码示例#xff08;自定义拦截器链#xff09;
步骤 1#x…目录一、核心角色对应责任链模式二、场景 1HandlerInterceptor 拦截器链核心1. 核心流程请求处理全生命周期2. 代码示例自定义拦截器链步骤 1定义抽象处理者复用 Spring 原生接口步骤 2实现具体处理者自定义拦截器步骤 3配置责任链指定拦截器顺序和拦截路径步骤 4核心处理器Controller责任链终点3. 执行效果分场景场景 1请求已登录token 有效场景 2请求未登录token 无效4. 责任链管理器HandlerExecutionChain 核心逻辑三、场景 2Servlet Filter 过滤器链底层补充1. 代码示例自定义 Filter2. 与 HandlerInterceptor 的核心区别四、Spring MVC 责任链的核心特点1. 灵活性2. 中断性3. 解耦性五、典型应用场景六、总结Spring MVC 的责任链模式主要体现在两大核心场景拦截器链HandlerInterceptor和Servlet 过滤器链Filter其中HandlerInterceptor是 Spring MVC 原生封装的责任链Filter是基于 Servlet 规范的责任链二者共同构成了请求处理的 “双层责任链”。核心目标将请求处理的通用逻辑如登录校验、日志、跨域与核心业务逻辑Controller解耦支持按顺序执行、灵活扩展且可中断请求流程。一、核心角色对应责任链模式责任链模式角色Spring MVC 对应实现核心职责抽象处理者HandlerHandlerInterceptor接口 /Filter接口定义处理方法如preHandle/doFilter约定处理规则具体处理者自定义HandlerInterceptor/Filter实现抽象接口处理特定逻辑如登录校验、日志记录责任链管理器HandlerExecutionChain拦截器/FilterChain过滤器管理处理者顺序触发执行控制请求传递请求对象HttpServletRequest/HttpServletResponse被传递和处理的核心对象最终处理者HandlerAdapterController拦截器链终点/Servlet过滤器链终点责任链传递的最终目标处理核心业务逻辑二、场景 1HandlerInterceptor 拦截器链核心1. 核心流程请求处理全生命周期Spring MVC 拦截器链是不纯责任链可中断、可部分处理执行流程如下plaintextDispatcherServlet → 1. 构建 HandlerExecutionChain包含拦截器列表 Controller→ 2. 按序执行拦截器 preHandle() - 若任意 preHandle 返回 false → 中断链反向执行已通过拦截器的 afterCompletion() - 若全部返回 true → 传递到 Controller 执行核心业务 → 3. 倒序执行拦截器 postHandle()仅 preHandle 全通过→ 4. 视图渲染完成后倒序执行拦截器 afterCompletion()无论是否中断2. 代码示例自定义拦截器链步骤 1定义抽象处理者复用 Spring 原生接口java运行// 无需自定义抽象类直接实现 Spring 提供的 HandlerInterceptor public interface HandlerInterceptor { // 前置处理请求到达 Controller 前执行返回 false 中断链 default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } // 后置处理Controller 执行后、视图渲染前执行仅 preHandle 全通过 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 {} }步骤 2实现具体处理者自定义拦截器java运行// 1. 登录校验拦截器 Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(token); if (token null || !valid_token.equals(token)) { response.setStatus(401); System.out.println(LoginInterceptor未登录中断请求); return false; // 中断责任链 } System.out.println(LoginInterceptor登录校验通过); return true; // 传递给下一个拦截器 } Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println(LoginInterceptor后置处理Controller 执行后); } Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(LoginInterceptor完成后处理资源清理); } } // 2. 日志拦截器 Component public class LogInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(LogInterceptor记录请求日志 - request.getRequestURI()); return true; } Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println(LogInterceptor记录响应日志 - response.getStatus()); } Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(LogInterceptor归档日志); } }步骤 3配置责任链指定拦截器顺序和拦截路径java运行Configuration public class WebConfig implements WebMvcConfigurer { Autowired private LoginInterceptor loginInterceptor; Autowired private LogInterceptor logInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { // 注册拦截器指定执行顺序order 越小preHandle 越先执行 registry.addInterceptor(logInterceptor) .addPathPatterns(/**) // 拦截所有路径 .order(1); // 日志拦截器先执行 registry.addInterceptor(loginInterceptor) .addPathPatterns(/api/**) // 仅拦截 /api 前缀路径 .order(2); // 登录拦截器后执行 } }步骤 4核心处理器Controller责任链终点java运行RestController RequestMapping(/api) public class UserController { GetMapping(/user) public String getUser() { System.out.println(Controller处理 /api/user 请求); return success; } }3. 执行效果分场景场景 1请求已登录token 有效plaintextLogInterceptor记录请求日志 - /api/user LoginInterceptor登录校验通过 Controller处理 /api/user 请求 LoginInterceptor后置处理Controller 执行后 LogInterceptor记录响应日志 - 200 LoginInterceptor完成后处理资源清理 LogInterceptor归档日志执行顺序preHandleLog → Login→ Controller → postHandleLogin → Log→ afterCompletionLogin → Log倒序执行原因HandlerExecutionChain会记录已通过的拦截器索引反向遍历执行后置 / 完成方法。场景 2请求未登录token 无效plaintextLogInterceptor记录请求日志 - /api/user LoginInterceptor未登录中断请求 LogInterceptor归档日志中断逻辑LoginInterceptor 的 preHandle 返回 false触发triggerAfterCompletion()仅执行已通过拦截器LogInterceptor的 afterCompletion核心 Controller 未执行postHandle 也不执行。4. 责任链管理器HandlerExecutionChain 核心逻辑Spring MVC 通过HandlerExecutionChain管理拦截器链核心源码简化如下java运行public class HandlerExecutionChain { private final Object handler; // 最终的 ControllerHandler private final ListHandlerInterceptor interceptors new ArrayList(); private int interceptorIndex -1; // 记录已通过的拦截器索引 // 执行前置处理 boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { for (int i 0; i interceptors.size(); i) { HandlerInterceptor interceptor interceptors.get(i); if (!interceptor.preHandle(request, response, handler)) { triggerAfterCompletion(request, response, null); // 中断执行完成方法 return false; } interceptorIndex i; // 更新已通过索引 } return true; } // 执行后置处理倒序 void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { for (int i interceptors.size() - 1; i 0; i--) { HandlerInterceptor interceptor interceptors.get(i); interceptor.postHandle(request, response, handler, mv); } } // 执行完成后处理倒序 void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { for (int i interceptorIndex; i 0; i--) { HandlerInterceptor interceptor interceptors.get(i); try { interceptor.afterCompletion(request, response, handler, ex); } catch (Throwable e) { // 忽略异常保证所有拦截器的完成方法都执行 } } } }三、场景 2Servlet Filter 过滤器链底层补充Filter 是 Servlet 规范的责任链由 Tomcat 等容器管理执行时机早于 HandlerInterceptor核心流程plaintextTomcat → ApplicationFilterChain → Filter1.doFilter() → Filter2.doFilter() → ... → DispatcherServlet.service() → HandlerInterceptor 链 → Controller1. 代码示例自定义 Filterjava运行// 字符编码过滤器 Component public class CharsetFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(UTF-8); response.setCharacterEncoding(UTF-8); System.out.println(CharsetFilter设置编码为 UTF-8); chain.doFilter(request, response); // 传递给下一个 Filter } }2. 与 HandlerInterceptor 的核心区别维度HandlerInterceptorFilter所属规范Spring MVC 自定义Servlet 规范执行时机DispatcherServlet 内部DispatcherServlet 之前拦截范围仅拦截 Controller 请求拦截所有 Web 请求如静态资源中断方式preHandle 返回 false不调用 chain.doFilter ()扩展能力可访问 Spring 上下文注入 Bean原生 Servlet 接口无 Spring 依赖四、Spring MVC 责任链的核心特点1. 灵活性动态扩展新增拦截器只需实现HandlerInterceptor并注册无需修改原有代码顺序可控通过order()指定执行顺序适配 “先日志、后校验” 等逻辑路径匹配可指定拦截 / 排除路径精准控制拦截范围。2. 中断性支持 “提前终止请求”如登录校验失败直接返回 401避免无效的核心逻辑执行中断后仍保证已通过拦截器的afterCompletion执行避免资源泄漏。3. 解耦性请求发送者客户端无需知道处理逻辑处理者拦截器无需知道完整链路只需关注自身职责核心业务Controller无需耦合通用逻辑如日志、校验。五、典型应用场景权限控制登录校验、角色 / 数据权限校验日志监控请求 / 响应日志、接口耗时统计跨域处理添加 CORS 响应头参数预处理请求参数解密、XSS 过滤资源清理线程局部变量ThreadLocal清理、连接关闭。六、总结Spring MVC 是责任链模式的 “经典落地”核心载体HandlerExecutionChain管理HandlerInterceptor链是 Spring MVC 原生责任链执行规则preHandle 正序执行可中断postHandle/afterCompletion 倒序执行扩展价值通过责任链解耦通用逻辑与核心业务是 Spring MVC 灵活扩展的核心机制双层补充Filter 链作为底层补充覆盖更广泛的 Web 请求场景。