news 2026/2/10 4:21:04

SpringBoot 统⼀功能处理以及DispatcherServlet

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot 统⼀功能处理以及DispatcherServlet

拦截器

定义

拦截器是Spring框架提供的核⼼功能之⼀, 主要⽤来拦截⽤⼾的请求, 在指定⽅法前后, 根据业务需要执 ⾏预先设定的代码.

实现拦截器

1. 定义拦截器

创建类,实现HandlerInterceptor接口,重写preHandle和postHandle两个方法,在方法中实现拦截器逻辑

其中,preHandle方法,是在controller类之前进行,用于检查;postHandle是controller实现完成后(或者拦截成功后)逆序进行,用于收尾。

实现流程:

假设拦截器有三个功能

情况一

放行:调用preHandle方法,实现功能1,2,3,如果放行,则调用controller方法,完成后调用postHandle方法,实现功能3,2,1

情况二

拦截:调用preHandle方法,实现功能1,2,3,在第3个功能处拦截,随后跳过controller方法,调用postHandle方法,只实现功能2,1。因为3并没有在preHandle实现。

package com.spring.bookmanage.interceptor; import com.spring.bookmanage.constant.Constants; import com.spring.bookmanage.entity.Result; import com.spring.bookmanage.entity.UserInfo; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Slf4j @Component public class LoginInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("目标代码执行前"); HttpSession session = request.getSession(false); if(!checkStatus(session)){ response.setStatus(401); return false; } //true放行,false拦截 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("目标方法执行后"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("完成后"); } public boolean checkStatus(HttpSession session) { if(session==null||(session.getAttribute(Constants.SESSION_USER_INFO)==null)){ //用户未登录 return false; } UserInfo userInfo=(UserInfo)session.getAttribute(Constants.SESSION_USER_INFO); if ((userInfo==null)||(userInfo.getId()<=0)){ //用户未登录 return false; } return true; } }

2. 注册拦截器

创建类,实现WebMvcConfigurer接口,实例化LoginInterceptor类,并重写addInterceptors⽅法,方法中定义拦截路径"/book/**"

package com.spring.bookmanage.config; import com.spring.bookmanage.interceptor.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor).addPathPatterns("/book/**"); } }

通过打印日志,可以看到拦截器生效(红框标出):

拦截路径

@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns("/**") .excludePathPatterns("/user/login");//设置拦截器拦截的请求路径 (/** 表⽰拦截所有请求) }

统一数据返回格式

该功能将统一格式返回前端

实现

创建类,实现ResponseBodyAdvice接口,重写supports和beforeBodyWrite方法。

supports方法: 判断是否要执行beforeBodyWrite方法. true为执行, false不执行. 通过该方法可以选择哪些类或哪些方法的response要进行处理, 其他的不进行处理.

beforeBodyWrite方法: 对response方法进行具体操作处理

package com.spring.bookmanage.config; import com.spring.bookmanage.entity.BookInfo; import com.spring.bookmanage.entity.Result; import lombok.SneakyThrows; import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import tools.jackson.databind.ObjectMapper; @ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice { @Autowired private ObjectMapper objectMapper; @Override public boolean supports(MethodParameter returnType, Class converterType) { //false:不处理 true:处理 return true; } @SneakyThrows @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if(body instanceof String){ return objectMapper.writeValueAsString(Result.success(body)); } if(body instanceof Result){ return body; } return Result.success(body); } }

统⼀异常处理

统⼀异常处理使用的是 @ControllerAdvice + @ExceptionHandler 来实现的, @ControllerAdvice 表⽰控制器通知类,@ExceptionHandler 是异常处理器,两个结合表示当出现异常的时候执行某个通知,也就是执行某个方法事件

package com.spring.bookmanage.config; import com.spring.bookmanage.entity.Result; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @Slf4j @ControllerAdvice @ResponseBody public class ExceptionAdvice { @ExceptionHandler public Result handler(Exception e){ log.error("error: "+e); return Result.fail("inner error"); } }

三组件及Controller背后的调度者:DispatcherServlet

我们看看Spring是怎么实现的, 还是从 DispatcherServlet 的代码开始分析。DispatcherServlet 对象在创建时会初始化一系列的对象

源码过于复杂,笔者作为和各位读者同样甚至更加稚嫩的初学者,就不大量展示了,以下为一小部分DispatcherServlet源码:

public class DispatcherServlet extends FrameworkServlet { //... protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); //url-方法映射 initHandlerAdapters(context); //适配器(可理解为统一接口格式工具) initHandlerExceptionResolvers(context); //异常处理器 initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); } //...

springboot启动时,由Servlet容器在80端口(默认)监听,并且DispatchServlet类启动,初始化这九大对象,其中就包括url-方法映射,这就是我们的controller,适配器,异常处理机制等。

当请求某个方法,DispatcherServlet调用拦截器,对请求进行检验,如果没有问题则放行,如果有问题则直接跳过controller调用;

当请求被拦截器放行,DispatcherServlet查找所有Controller方法,找到对应的请求路径的方法调用;

当返回某个结果DispatcherServlet查找所有结果统一格式方法,调用并封装结果返回;

当出现异常,DispatcherServlet查找所有异常处理,找到合适的异常处理方法并调用。

总结

本章节主要介绍了SpringBoot 对⼀些统⼀功能的处理⽀持.

1. 拦截器的实现主要分两部分: 定义拦截器(实现HandlerInterceptor 接口) + 配置拦截器

2. 统⼀数据返回格式通过@ControllerAdvice + ResponseBodyAdvice 来实现

3. 统⼀异常处理使⽤@ControllerAdvice + @ExceptionHandler 来实现, 并且可以分异常来处理

4. 学习了DispatcherServlet的一点点源码

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 11:52:50

c语言结构体操作示例

structs.c 完整代码 #include <stdio.h> #include <string.h>// 结构体定义 struct Student {char name[50];int id;float gpa; };// 嵌套结构体定义 struct Date {int day;int month;int year; };struct Employee {char name[50];int employeeId;struct Date hir…

作者头像 李华
网站建设 2026/2/5 7:59:45

专业的康有利到家理疗小程序哪家好

专业的康有利到家理疗小程序哪家好在当今数字化时代&#xff0c;到家理疗服务借助小程序得到了更广泛的推广与应用。康有利到家理疗小程序为用户提供了便捷的理疗服务预约途径&#xff0c;那么专业的康有利到家理疗小程序哪家好呢&#xff1f;市场现状分析目前市场上的康有利到…

作者头像 李华
网站建设 2026/2/7 11:56:39

大模型RAG技术深度剖析:提升AI回答质量的黑科技

本文详细解读了RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;分析了其解决LLMs幻觉、知识过时等问题的意义&#xff0c;介绍了RAG系统的三大发展范式&#xff08;朴素、高级、模块化&#xff09;&#xff0c;探讨了检索、生成、增强环节的关键技术和评估方法&#…

作者头像 李华
网站建设 2026/2/5 14:31:17

STM32学习——编码器接口测速

1.编码器接口测速1.基本要点1.void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);//配置定时器编码器接口模式的核心函数&#xff0c;用于将定时器配置为编码器模式&#xff0c;实现对正交编…

作者头像 李华
网站建设 2026/2/5 11:35:51

学Simulink——基础MPPT控制场景实例:基于Simulink的电导增量法(INC)光伏MPPT仿真

目录 手把手教你学Simulink 一、引言:为什么“扰动观察法在快速变化光照下会‘跑偏’”?——因为P&O仅比较前后功率大小,无法区分MPP左侧还是右侧;当光照突变时,( dP ) 符号可能误判,导致反向远离MPP! 二、电导增量法(INC)原理 1. 光伏功率对电压求导 2. 判断…

作者头像 李华
网站建设 2026/2/8 18:48:42

评论笔记 - Cordova 与 OpenHarmony 混合开发实战

欢迎大家加入开源鸿蒙跨平台开发者社区&#xff0c;一起共建开源鸿蒙跨平台生态。 &#x1f4cc; 模块概述 评论笔记模块是MovieTracker应用中用于记录和管理影片评论的功能。用户可以为影片添加详细的评论笔记&#xff0c;记录观影感受、剧情分析、演员表现等。评论笔记支持编…

作者头像 李华