Web核心开发:拦截器、过滤器、跨域、统一返回
Web核心开发拦截器、过滤器、跨域、统一返回后端接口写多了就知道业务逻辑只占三成剩下七成是防呆设计——拦截没登录的、处理跨域的、统一返回格式的。这篇把Web层的基础设施一次搭好。一、SpringBoot Web开发全景1.1 DispatcherServlet流程所有请求进入SpringBoot第一站是DispatcherServlet前端控制器核心流程如下客户端请求 → DispatcherServlet → HandlerMapping找到对应的Controller方法 → HandlerInterceptor拦截器 preHandle → Controller执行业务逻辑 → HandlerInterceptor拦截器 postHandle → 视图渲染/结果处理 → HandlerInterceptor拦截器 afterCompletion → 返回响应注意过滤器Filter在DispatcherServlet之前就执行了这是拦截器和过滤器的关键区别。二、拦截器(Interceptor)2.1 HandlerInterceptor接口拦截器是Spring MVC提供的机制核心接口publicinterfaceHandlerInterceptor{// Controller执行前返回false则中断请求booleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler);// Controller执行后视图渲染前voidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView);// 整个请求完成后视图渲染后通常用于资源清理voidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex);}三个阶段的执行时机和用途方法执行时机典型用途preHandleController前登录校验、权限检查、日志记录postHandleController后统一修改返回数据afterCompletion请求结束资源清理、异常处理2.2 登录拦截器实战ComponentpublicclassLoginInterceptorimplementsHandlerInterceptor{OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{// 从请求头获取tokenStringtokenrequest.getHeader(Authorization);if(StringUtils.isBlank(token)){response.setStatus(401);response.setContentType(application/json;charsetUTF-8);response.getWriter().write({\code\:401,\message\:\未登录\});returnfalse;}// 校验token逻辑...returntrue;// 放行}}2.3 注册拦截器光写了拦截器不够得注册到Spring MVC里才能生效ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{AutowiredprivateLoginInterceptorloginInterceptor;OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(loginInterceptor).addPathPatterns(/api/**)// 拦截路径.excludePathPatterns(/api/login,// 排除登录接口/api/register,/api/captcha);// 排除验证码接口}}三、过滤器(Filter)3.1 Filter接口过滤器是Servlet规范中的机制在请求到达Spring MVC之前就执行ComponentWebFilter(urlPatterns/*,filterNamerequestLogFilter)publicclassRequestLogFilterimplementsFilter{OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletRequestreq(HttpServletRequest)request;longstartSystem.currentTimeMillis();log.info(请求开始: {} {},req.getMethod(),req.getRequestURI());chain.doFilter(request,response);// 放行到下一个过滤器或目标资源longcostSystem.currentTimeMillis()-start;log.info(请求结束, 耗时: {}ms,cost);}}3.2 过滤链执行顺序多个Filter组成一条链按顺序执行。可以用Order注解控制顺序ComponentOrder(1)// 数字越小越先执行publicclassFirstFilterimplementsFilter{...}ComponentOrder(2)publicclassSecondFilterimplementsFilter{...}四、拦截器 vs 过滤器对比对比项过滤器(Filter)拦截器(Interceptor)所属规范Servlet规范Spring MVC执行时机DispatcherServlet前DispatcherServlet内能否访问Spring Bean需额外处理直接注入能否获取Handler信息不能能知道哪个Controller方法典型场景编码设置、日志、安全过滤登录校验、权限控制简单记过滤器管请求进出拦截器管Controller前后。五、跨域问题解决5.1 什么是跨域浏览器同源策略协议、域名、端口任一不同就是跨域。前端localhost:5173调后端localhost:8080就跨域了浏览器会拦截响应。5.2 三种解决方案方案一CrossOrigin注解粒度最细单个接口RestControllerRequestMapping(/api)CrossOrigin(originshttp://localhost:5173)publicclassApiController{...}方案二WebMvcConfigurer全局配置ConfigurationpublicclassCorsConfigimplementsWebMvcConfigurer{OverridepublicvoidaddCorsMappings(CorsRegistryregistry){registry.addMapping(/api/**).allowedOrigins(http://localhost:5173).allowedMethods(GET,POST,PUT,DELETE,OPTIONS).allowedHeaders(*).allowCredentials(true)// 允许携带Cookie.maxAge(3600);// 预检缓存时间秒}}方案三CorsFilter全局过滤器推荐优先级最高BeanpublicCorsFiltercorsFilter(){CorsConfigurationconfignewCorsConfiguration();config.addAllowedOrigin(http://localhost:5173);config.addAllowedMethod(*);config.addAllowedHeader(*);config.setAllowCredentials(true);UrlBasedCorsConfigurationSourcesourcenewUrlBasedCorsConfigurationSource();source.registerCorsConfiguration(/**,config);returnnewCorsFilter(source);}5.3 跨域常见坑点坑一OPTIONS预检请求被拦截非简单请求如POSTJSON浏览器会先发OPTIONS请求探路。如果登录拦截器把OPTIONS请求拦了前端直接报跨域错误。解决拦截器中放行OPTIONSOverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler){if(OPTIONS.equals(request.getMethod())){returntrue;// 预检请求直接放行}// 正常校验逻辑...}坑二Cookie跨域跨域携带Cookie需要同时满足后端设置allowCredentials(true)allowedOrigins不能用*必须指定具体域名前端请求设置withCredentials: true六、统一返回封装6.1 Result类设计别让每个接口返回格式都不一样统一规范DataAllArgsConstructorNoArgsConstructorpublicclassResultT{privateintcode;privateStringmessage;privateTdata;publicstaticTResultTsuccess(Tdata){returnnewResult(200,操作成功,data);}publicstaticTResultTerror(intcode,Stringmessage){returnnewResult(code,message,null);}}6.2 ResponseAdvice全局统一返回用ResponseBodyAdvice实现全局自动包装Controller里直接返回业务数据框架自动包成ResultRestControllerAdvicepublicclassGlobalResponseAdviceimplementsResponseBodyAdviceObject{Overridepublicbooleansupports(MethodParameterreturnType,ClassconverterType){// 排除Result类型本身和String类型避免序列化问题return!returnType.getParameterType().equals(Result.class)!returnType.getParameterType().equals(String.class);}OverridepublicObjectbeforeBodyWrite(Objectbody,MethodParameterreturnType,MediaTypeselectedContentType,ClassselectedConverterType,ServerHttpRequestrequest,ServerHttpResponseresponse){returnResult.success(body);}}Controller代码变得极简RestControllerRequestMapping(/api/user)publicclassUserController{GetMapping(/{id})publicUsergetUser(PathVariableLongid){returnuserService.getById(id);// 直接返回User框架自动包装成Result}}返回结果统一是{code:200,message:操作成功,data:{id:1,name:张三}}6.3 String返回的坑ResponseBodyAdvice处理String返回值时会有序列化问题。因为Spring MVC对String类型默认用StringHttpMessageConverter而返回Result对象后会报类型转换异常。解决方案给String返回值单独处理手动转成JSONOverridepublicObjectbeforeBodyWrite(Objectbody,MethodParameterreturnType,MediaTypeselectedContentType,ClassselectedConverterType,ServerHttpRequestrequest,ServerHttpResponseresponse){if(bodyinstanceofString){response.getHeaders().setContentType(MediaType.APPLICATION_JSON);returnJSONUtil.toJsonStr(Result.success(body));}returnResult.success(body);}这样全局统一返回就稳了接口层只管业务逻辑返回格式交给框架兜底。

相关新闻

WinMD:3分钟掌握Windows访问Linux RAID的终极方案

WinMD:3分钟掌握Windows访问Linux RAID的终极方案

WinMD:3分钟掌握Windows访问Linux RAID的终极方案 【免费下载链接】winmd WinMD 项目地址: https://gitcode.com/gh_mirrors/wi/winmd WinMD 是一款革命性的驱动程序,它让 Windows 系统能够无缝访问由 Linux mdadm 创建的 MD RAID 设备。对于需要…

2026/10/18 4:13:28 阅读更多 →
3D模型文件预览终极指南:如何让Windows资源管理器显示3D缩略图?

3D模型文件预览终极指南:如何让Windows资源管理器显示3D缩略图?

3D模型文件预览终极指南:如何让Windows资源管理器显示3D缩略图? 【免费下载链接】space-thumbnails Generates preview thumbnails for 3D model files. Provide a Windows Explorer extensions that adds preview thumbnails for 3D model files. 项目…

2026/10/18 4:13:30 阅读更多 →
让RE引擎游戏获得新生:揭秘REFramework的三大魔法

让RE引擎游戏获得新生:揭秘REFramework的三大魔法

让RE引擎游戏获得新生:揭秘REFramework的三大魔法 【免费下载链接】REFramework Mod loader, scripting platform, and VR support for all RE Engine games 项目地址: https://gitcode.com/GitHub_Trending/re/REFramework 你是否曾想过为《生化危机》系列添…

2026/10/17 6:21:40 阅读更多 →

最新新闻

PFA算法:基于正交投影一致性的多模态特征空间隐式对齐

PFA算法:基于正交投影一致性的多模态特征空间隐式对齐

简介:本资源为数据挖掘领域Pattern Fusion(PFA)算法的完整实践套件,面向算法研究者、R/ MATLAB开发者及高年级本科生或研究生,聚焦于大规模频繁模式的精炼提取与融合优化问题。资源共23个文件,涵盖9个txt&a…

2026/10/18 10:47:51 阅读更多 →
Flex布局对齐三兄弟:justify-content、align-items、align-content详解

Flex布局对齐三兄弟:justify-content、align-items、align-content详解

Flex 布局这个系列写到第三篇,前面已经把容器的 display、flex-direction、flex-wrap 这些基础概念过了一遍。评论区不少读者留言说,最头疼的就是 justify-content、align-items、align-content 这三个属性,看起来都是“对齐”,但…

2026/10/18 10:47:51 阅读更多 →
基于深度学习的故障诊断模型代码与数据:从振动信号到故障分类的完整流程

基于深度学习的故障诊断模型代码与数据:从振动信号到故障分类的完整流程

简介:这份资源面向深度学习与工业故障诊断方向的研究者和工程师,提供一套可直接运行的故障诊断模型代码与配套数据,帮助读者跳过从零搭建系统的环节,快速进入模型训练与实验验证阶段。压缩包共63个文件,约57.74MB&…

2026/10/18 10:47:51 阅读更多 →
流量分析实战指南:从抓包到行为识别,揪出内网异常

流量分析实战指南:从抓包到行为识别,揪出内网异常

上个月在一家客户的内部网络做审计时,我盯着核心交换机的镜像口看了十分钟,注意到一台内网服务器每隔四十分钟就会产生一次几百KB的外联流量。连接数不多,时长不长,但雷打不动的周期让人很不舒服。顺着这条线往下查,最…

2026/10/18 10:47:51 阅读更多 →
知识付费v4.5.4源码解析:一套系统搞定PC、H5、小程序和APP

知识付费v4.5.4源码解析:一套系统搞定PC、H5、小程序和APP

简介:知识付费v4.5.4源码是面向在线教育与知识变现场景的一整套私有化部署方案,主要服务于培训机构、独立讲师和想搭建网校的站长。系统一套代码同时覆盖PC端、H5网页与微信小程序,支持直播、录播、图文、考试练习等多元教务形式,…

2026/10/18 10:47:50 阅读更多 →
KAN与六种神经网络架构结合实战:图像分类与时间序列预测对比

KAN与六种神经网络架构结合实战:图像分类与时间序列预测对比

最近一直在做时间序列预测和图像分类的实验,发现朋友圈里聊天总绕不开KAN(Kolmogorov-Arnold Network)这个词。有同学拿"KAN全面吊打MLP"的截图来问我是不是真能替换掉手头的模型,也有同学问KAN跟CNN、LSTM、TCN、Transformer这些经典结构组合之后到底效果怎么样、代…

2026/10/18 10:46:50 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →