Spring Boot项目必备三大组件:跨域、JWT拦截器、统一响应
一、CorsConfigConfiguration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOrigin(http://localhost:5173); config.addAllowedHeader(*); config.addAllowedMethod(*); config.setAllowCredentials(true); config.setMaxAge(3600L); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }解释一下这个代码Configuration告诉Spring这是一个配置类启动时就会加载。CorsFilter这是一个过滤器比拦截器还靠前在请求还没到Spring MVC核心之前就执行专门用来在响应头里添加Access-Control-Allow-Origin等字段。addAllowedOrigin(http://localhost:5173)只允许这个地址的网页访问我的后端。如果你写*那就是允许所有但是这样可能会被恶意访问。addAllowedHeader(*)允许前端请求携带任何请求头比如Authorization、Content-Type。addAllowedMethod(*)允许所有HTTP方法GET、POST、PUT、DELETE等。setAllowCredentials(true)允许前端发请求时带上Cookie。这是个大坑点一旦设为trueaddAllowedOrigin就不能用*必须指定具体域名否则浏览器直接报错。setMaxAge(3600L)预检请求OPTIONS的缓存时间单位秒。前端在发“复杂请求”如带自定义头的JSON请求之前会先发一个OPTIONS探路设置3600秒后同一请求1小时内不再发预检性能提升明显。没有它你用Vue的axios请求后端接口浏览器控制台直接报红No Access-Control-Allow-Origin header is present。有了它后端默默给响应头加上了白名单浏览器放行联调顺利。面试高频追问问答什么是跨域为什么会有跨域浏览器的“同源策略”规定协议、域名、端口必须完全一致才能自由访问。前后端端口不一样5173 vs 8080所以被拦截。这是浏览器安全机制不是后端的问题。除了CorsFilter还有哪些方式解决跨域①CrossOrigin注解加在Controller或方法上②实现WebMvcConfigurer重写addCorsMappings③Nginx反向代理前端请求同源地址由Nginx转发到后端。我推荐用CorsFilter因为它全局生效且优先级高。setAllowCredentials(true)和addAllowedOrigin(*)为什么不能同时用因为浏览器规范强制要求如果允许携带凭证Cookie那么Origin必须明确指定不能用通配符。否则浏览器觉得不安全直接拒绝。这是面试必杀坑一定要说出来。生产环境怎么配绝对不能写*必须写具体的前端域名如https://www.myapp.com。如果有多环境建议把域名抽到配置文件用Value注入做到环境隔离。有什么改进建议多源支持用config.setAllowedOriginPatterns()Spring Boot 2.4替代addAllowedOrigin支持*通配符但又能兼容allowCredentialstrue更灵活。放行特定路径如果只需要给/api/**开跨域别写/**缩小范围。二、JwtInterceptorComponent public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri request.getRequestURI(); if (/admin/login.equals(uri)) { return true; } String authHeader request.getHeader(Authorization); if (authHeader null || !authHeader.startsWith(Bearer )) { response.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\message\:\Token缺失或格式错误\}); return false; } String token authHeader.substring(7); try { JwtUtil.parseToken(token); return true; } catch (Exception e) { response.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\message\:\Token无效或已过期\}); return false; } } }实现HandlerInterceptor这是Spring MVC的拦截器在请求进入Controller之前执行是鉴权的绝佳时机。白名单放行如果请求是/admin/login直接放行登录还没Token呢。提取Authorization头前端必须把Token放在Authorization: Bearer xxx里这是全球通用的JWT传输标准。校验如果头没有或格式不对直接返回401并手动写一个JSON错误信息再也不往下执行了。解析Token调用工具类JwtUtil.parseToken如果抛异常过期、篡改同样返回401。在项目里它是整个系统的安全闸口。除了登录所有接口比如查询订单、修改个人信息都必须经过它。一旦Token无效请求连Controller的门都摸不到极大节省了服务器资源不用再查数据库验证身份了。问答拦截器(Interceptor)和过滤器(Filter)有什么区别Filter是Servlet规范更底层在请求进入DispatcherServlet之前执行依赖Web容器Interceptor是Spring提供的在DispatcherServlet之后、Controller之前执行能拿到Spring容器里的Bean比如JwtUtil这是最大区别。你的白名单只写了/admin/login如果前端请求/admin/login/带斜杠或/admin/login?xxx会怎样会被拦截因为equals是精确匹配。改进用request.getServletPath()或Spring的AntPathMatcher做模糊匹配或者把白名单放到配置里支持/admin/**通配。为什么不用ControllerAdvice统一处理Token异常而是直接在拦截器里写response.getWriter().write()因为拦截器里抛出的异常默认不会进入全局异常处理器。手动写流是“应急”做法但不规范。更好做法是抛出自定义异常如TokenInvalidException然后在ControllerAdvice中统一捕获并返回Result.error这样错误格式全局一致。Token验证通过后怎么让后续接口知道当前是哪个用户在操作解析Token后把用户ID放入request.setAttribute(userId, userId)或者存入ThreadLocal推荐这样Service层能随时拿到当前用户信息避免重复解析Token。Token过期了你们怎么处理需要刷新机制吗可以配合Redis存刷新令牌Refresh Token过期后返回特定状态码如401前端用刷新令牌换新Token。简单点的话直接跳转登录页。三、Resultpublic class ResultT { private String code; private T data; private String msg; public static T ResultT success() { ... } public static T ResultT success(T data) { ... } public static T ResultT error(String msg) { ... } public static T ResultT error(String code, String msg) { ... } // getter/setter }泛型Tdata字段可以是任何类型比如ResultUser、ResultListOrder编译期就确定类型不用强制转换。静态工厂方法提供success()、success(data)、error(msg)、error(code, msg)调用方便。核心字段code状态码200成功500系统错误401未授权等。msg人类可读的提示信息。data业务数据查询结果。项目中没有它你的Controller可能会返回查询成功 → 直接返回User对象查询失败 → 返回Map带error字段删除成功 → 返回success字符串前端得写无数个if判断解析不同类型。而统一成Result后前端只需要判断result.code 200然后取result.data其他情况统一走错误提示。问答为什么要统一封装直接返回对象不好吗①前后端需要固定契约方便前端全局拦截器处理②包含code和msg可以把业务异常也以正常JSON返回而不是抛出500白页③后期如果需要加timestamp、path等字段只要改这个类所有接口自动生效。这里的T有什么好处类型安全。如果data是Object取出来还得强转容易强转异常。用泛型后ResultUser直接getData()就是User不用手动(User)。状态码用String还是int用String更灵活可以支持A001这种业务码但项目中如果只用数字建议用Integer或枚举比如ResultCode.SUCCESS.getCode()防止手残把200写成200 带空格。success()和success(T data)为什么不合并成一个方法重载让调用意图更清晰。如果合并传null时无法区分是“没数据”还是“业务数据就是null”分开写语义明确。如果我要返回分页数据含total怎么封装可以再写一个PageResultT继承Result或者直接在data里放PageInfoT把total、pageNum、list都塞进data的字段里。四、三者如何协同构成项目骨架组件作用时机产出CorsConfig请求刚到达服务器还没进Spring MVC在响应头添加CORS信息让浏览器放行JwtInterceptor请求进入Spring MVC但在Controller之前校验Token无效则直接返回401 JSONResultController返回数据时将所有返回统一包装成{code,msg,data}格式一条请求的生命周期浏览器发请求 → CorsFilter 检查跨域放行。请求到DispatcherServlet → JwtInterceptor 检查Token登录接口除外。Token有效进入Controller业务处理返回Result.success(data)。Spring MVC将Result转成JSON返回前端。

相关新闻

DDR1内存运行Win11:硬件考古与市场启示

DDR1内存运行Win11:硬件考古与市场启示

1. 项目背景:当DDR1遇上Win11的荒诞与必然 最近在Reddit硬件社区看到一位ID为Omores的发烧友,用二十年前的DDR1内存成功运行Windows 11的案例,这个看似行为艺术的实验背后其实藏着当前硬件市场的残酷现实。我拆开自己的备用机箱,翻…

2026/10/15 12:21:28 阅读更多 →
视觉分析工具部署与性能优化指南:从环境配置到合规实践

视觉分析工具部署与性能优化指南:从环境配置到合规实践

这次我们来看一个名为"视奸expert26"的项目,从名称来看似乎涉及某种视觉分析或监控能力。不过需要明确的是,任何涉及隐私侵犯的技术都应该在法律和道德边界内使用。 1. 核心能力速览 能力项 说明 项目类型 视觉分析工具(基于名…

2026/10/18 3:33:54 阅读更多 →
专科论文AI写作工具测评:9款主流工具实战对比

专科论文AI写作工具测评:9款主流工具实战对比

1. 项目概述:AI论文写作工具测评的必要性去年指导专科生毕业论文时,我发现超过80%的学生在文献综述环节卡壳超过两周。直到有位学生用AI工具三天完成了初稿框架,才意识到这类工具已经能实质性提升写作效率。这次测评源于实际教学需求&#xf…

2026/10/18 8:45:08 阅读更多 →

最新新闻

CiteSpace 6.2.R1 部署与参数调优实战指南

CiteSpace 6.2.R1 部署与参数调优实战指南

简介:本资源为CiteSpace 6.2.R1正式发布版Windows可执行安装包,面向科研人员、硕博研究生及文献计量初学者,解决学术文献可视化分析中工具获取难、版本不稳定、离线部署不便等实际问题。压缩包共305个文件,含核心可执行程序&#…

2026/10/18 14:26:32 阅读更多 →
docker启动任意容器显示端口被占用

docker启动任意容器显示端口被占用

文章目录1、错误原文2、错误原因3、解决办法1、错误原文 Container zhiling-redis StartingError response from daemon: driver failed programming external connectivity on endpoint zhiling-redis (265ba54ed4403dd1b5fb78c541ab5d9f1a147c994c3df508e89b869067702093e): …

2026/10/18 14:26:32 阅读更多 →
LinkedList与链表(一)

LinkedList与链表(一)

1.为什么要学习LinkedList?我们刚刚学习了ArrayList,增添数据需要扩容操作,浪费空间。查找数据的时间复杂度按下标索引的可以O(1),按内容查找的就需要O(N)。添加某一点的数据&#x…

2026/10/18 14:26:32 阅读更多 →
AI的成长----AI应用范例

AI的成长----AI应用范例

作为国内首批使用Chat GPT 4的人之一 ,GPT刚刚震撼发布,我就在收到了消息,然后过了一个月就开始使用了。如今deepseek作为全球首个推理模型,更加深得人心。1️⃣ 锁定赛道——了解你的领域与受众2️⃣ 产品画像——深挖产品细节亮…

2026/10/18 14:26:32 阅读更多 →
用卫星地图训练无人机导航!SatNav:11.8万条长程导航任务,真机部署已验证

用卫星地图训练无人机导航!SatNav:11.8万条长程导航任务,真机部署已验证

「从室内走向城市低空」 目录 01 从卫星地图构建长程视觉语言导航任务 02 现有模型在 SatNav 上的表现 03 SwiftVLN:比较不同记忆设计的效果 04 从卫星图像训练到真实无人机飞行 05 写在最后 “沿着这条路飞,在第三个路口左转&…

2026/10/18 14:26:32 阅读更多 →
C++ QT数独游戏工程:可调试、可交作业的GUI编程实践

C++ QT数独游戏工程:可调试、可交作业的GUI编程实践

简介:这是一份面向C与Qt初学者的数独游戏课程设计实践资源,适用于高校编程语言课、图形界面开发实训或小型游戏项目实践。资源完整实现了一个具备图形化交互能力的数独游戏软件,支持空白数独初始化、数字填入、颜色状态区分(黑色初…

2026/10/18 14:25:32 阅读更多 →

日新闻

基于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/18 12:16:16 阅读更多 →