Spring MVC 常用注解

Spring MVC 常用注解:企业级全场景用法与实战指南 🤔 1. 问题切入:一个订单查询接口 假设你在开发一个电商系统的订单查询接口,需要实现以下需求: 通过订单 ID 查询订单详情 支持按状态、时间范围过滤订单列表 接收 JSON 请求体来创建订单 处理参数校验失败时的错误返回 统一处理各类异常 以下是一个典型的 Spring MVC Controller 初版实现: @RestController @RequestMapping("/api/orders") public class OrderController { @GetMapping("/{id}") public Result<Order> getOrder(@PathVariable Long id) { // 查询订单 } @GetMapping public Result<Page<Order>> listOrders( @RequestParam(required = false) String status, @RequestParam(required = false) @DateTimeFormat(iso = DATE) LocalDate startDate, @RequestParam(required = false) @DateTimeFormat(iso = DATE) LocalDate endDate, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int size) { // 分页查询 } @PostMapping @ResponseStatus(HttpStatus.CREATED) public Result<Order> createOrder(@Validated @RequestBody CreateOrderRequest request) { // 创建订单 } } 短短几行代码用到了 10+ 个注解。这些注解各自承担什么职责?组合使用时有什么坑?在企业级项目中应该如何规范使用?这篇博客将系统性地回答这些问题。 ...

九月 24, 2022 · 12 分钟 · 2520 字 · yaomingye

OAuth 2.0 + JWT 单点登录

OAuth 2.0 + JWT 单点登录实战 一、从一个登录按钮说起 你在商家后台(merchant.shop.com)点了"登录",页面跳转到了一个统一的登录页,你输入账号密码,然后又跳回了商家后台——你已经在系统里了。然后你打开运营后台(ops.shop.com),不用再输密码,直接进去了。 这就是单点登录(SSO)。背后有三个角色在协作: sequenceDiagram participant Browser as 浏览器 participant Biz as 业务系统\nmerchant.shop.com participant SSO as 认证中心\nsso.company.com Browser->>Biz: 1. 访问商家后台 Biz-->>Browser: 2. 302: 去认证中心登录 Browser->>SSO: 3. 跳转到登录页 SSO-->>Browser: 4. 返回登录页面 Browser->>SSO: 5. 提交用户名密码 SSO-->>Browser: 6. 302: 登录成功,回业务系统 Browser->>Biz: 7. 带着凭证回商家后台 Biz->>SSO: 8. 后端验证凭证 SSO-->>Biz: 9. 返回用户身份 Biz-->>Browser: 10. 登录成功,进入系统 这里面有两个关键问题: 第 5 步中,用户的密码交给了谁? 答案:只交给了认证中心。业务系统从头到尾都没见过用户的密码。 第 7 步中,浏览器带回的"凭证"是什么? 答案:是一个一次性的授权码(code),不是用户名密码,也不是最终的身份令牌。 这就是 OAuth 2.0 授权码模式的核心思路:用户密码只给认证中心,业务系统通过一个间接的"授权码"来确认用户身份。 二、逐帧拆解:一次登录的完整交互 下面以一个真实场景走一遍完整流程。三个参与者: 参与者 对应系统 职责 浏览器 用户正在用的 Chrome / Edge 用户操作的入口,负责跳转和提交凭据 业务系统 CRM 应用(crm.company.com:8080) 用户真正想用的系统,需要确认"你是谁" 认证中心 SSO 服务器(sso.company.com:9000) 唯一能验证用户名密码的地方,签发身份令牌 下面是完整的交互流程——请重点关注每个角色在每一步做了什么: ...

九月 22, 2022 · 13 分钟 · 2617 字 · yaomingye

SSO 与 JWT+Redis 的定位差异

SSO 与 JWT+Redis 的定位差异:Token格式、管理策略、认证架构三个层次 🤔 一、一个常见的学习困惑 很多开发者在学习鉴权体系时会遇到这样的困惑: 已经理解了 JWT 的三段式结构,知道它是无状态的 Token 格式 也理解了 JWT + Redis 混合方案,知道它能解决 Token 主动撤销的问题 然后听到"微服务用 SSO(单点登录)",去查资料后发现 SSO 也用 JWT 于是产生疑问:JWT + Redis 方案和 SSO 是什么关系?是不是同一个东西的不同叫法?如果不是,区别在哪? 这三个概念确实容易混淆,因为它们都围绕"鉴权"这个话题,但它们解决问题的层次完全不同。下面用三个明确的定义开篇: 概念 本质 解决什么问题 JWT Token 数据格式 Token 如何编码用户信息、如何防篡改 JWT + Redis Token 管理策略(单服务内部) 单个服务如何签发、验证、撤销 Token SSO(单点登录) 认证架构模式(跨服务) 多个服务之间如何共享登录状态 💼 二、从一个具体的业务场景理解差异 假设你所在的公司有三个系统: OA 办公系统(oa.company.com)—— 审批、考勤 CRM 客户系统(crm.company.com)—— 客户管理 BI 报表系统(bi.company.com)—— 数据分析 🏝️ 2.1 没有 SSO 时:每个系统各自鉴权 sequenceDiagram participant U as 用户 participant OA as OA系统 participant CRM as CRM系统 participant BI as BI系统 Note over U,BI: 用户需要分别登录3个系统 U->>OA: 打开OA → 输入用户名密码 OA-->>U: 登录成功 (OA的Token) U->>CRM: 打开CRM → 再次输入用户名密码 CRM-->>U: 登录成功 (CRM的Token) U->>BI: 打开BI → 第三次输入用户名密码 BI-->>U: 登录成功 (BI的Token) 每个系统都有自己独立的用户表、独立的登录接口、独立签发 Token。用户需要在三个系统之间各登录一次。这里的每个系统内部,可能各自使用了 JWT + Redis 管理自己的 Token——但这和"用户只需登录一次"是两个不同的问题。 ...

九月 21, 2022 · 9 分钟 · 1755 字 · yaomingye

JWT 与双令牌机制详解

JWT 与双令牌机制详解:从结构原理到 Java 代码实现 🤔 一、一个登录请求背后的困境 你写完了一个登录接口,用户提交用户名密码,服务端验证通过后创建 Session,把用户信息存进去,返回一个 JSESSIONID 的 Cookie。后续请求自动带上这个 Cookie,服务端从 Session 中取出用户信息——这是最传统的 Session 认证方式。 @PostMapping("/login") public String login(HttpSession session, @RequestBody LoginRequest req) { User user = userService.verify(req.getUsername(), req.getPassword()); if (user == null) { return "用户名或密码错误"; } session.setAttribute("currentUser", user); // 存入Session return "登录成功"; } @GetMapping("/info") public User info(HttpSession session) { return (User) session.getAttribute("currentUser"); // 从Session取 } 这段代码在单机部署时没有问题。但当你部署到 3 台服务器、前面挂了一个 Nginx 负载均衡时,问题就出现了: ...

九月 20, 2022 · 12 分钟 · 2361 字 · yaomingye

JWT + Redis 双令牌鉴权实战

JWT + Redis 双令牌鉴权实战:生产环境下的 Token 主动失效与过期管理方案 🔥 一、一个真实的生产事故 先看一段在中小项目中常见的鉴权代码: // 登录:生成JWT,返回给客户端 public String login(String username, String password) { User user = userService.verify(username, password); return Jwts.builder() .setSubject(user.getId().toString()) .setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000)) .signWith(SECRET_KEY) .compact(); } // 拦截器:验证JWT签名和过期时间 public boolean preHandle(HttpServletRequest request, ...) { String token = request.getHeader("Authorization"); Claims claims = Jwts.parserBuilder() .setSigningKey(SECRET_KEY).build() .parseClaimsJws(token).getBody(); // Token签名正确且未过期 → 放行 return true; } 这段代码能跑吗?能。有安全隐患吗?有,而且很严重。 ...

九月 19, 2022 · 19 分钟 · 3916 字 · yaomingye

Spring Security + JWT 企业级鉴权实战

Spring Security + JWT 企业级鉴权实战:从零概念到完整代码实现 阅读前提:本文假设你已经会使用 Spring Boot 写基本的 CRUD 接口。如果你从未接触过 Spring Security,从这篇开始即可。 本文按照"先搞懂概念 → 教程版完整实现 → 生产版逐项升级 → 验证排错“的顺序组织。如果你只想快速跑通一个能用的版本,读完 Part 1 后直接看 Part 2 即可;如果你想理解企业级项目的真实做法,需要完整读完。 Part 1:先搞懂要做什么 在写任何代码之前,先把三个问题搞清楚:认证和授权到底是什么?Spring Security 怎么运作的?JWT 是什么? 一、从一个没有防护的接口说起 假设你用 Spring Boot 写了一个用户管理接口: @RestController @RequestMapping("/api/admin") public class AdminController { @GetMapping("/users") public List<User> listAllUsers() { // 返回系统中所有用户信息 return userService.findAll(); } @DeleteMapping("/users/{id}") public String deleteUser(@PathVariable Long id) { userService.deleteById(id); return "删除成功"; } } 启动项目后,任何人只要知道 URL,就能直接访问这些接口——不需要登录,不需要权限。这在企业生产环境中是不可接受的。 ...

九月 18, 2022 · 23 分钟 · 4761 字 · yaomingye

Spring Boot企业开发高频注解完全指南

Spring Boot企业开发高频注解完全指南:从IoC容器到数据访问全覆盖 🤔 一、为什么需要这份注解清单 初学 Spring Boot 时,打开官方文档会看到上百个注解。但实际企业开发中,真正高频使用的注解只有其中一部分。很多注解你可能工作三五年也用不到一次。 本文筛选出企业开发中使用频率最高的 Spring 注解(不含 SpringMVC 和 SpringSecurity),每个注解都配有可运行的示例代码和一句话说明它的用途。不解释底层原理,只告诉你"这是什么、怎么用、什么时候用"。 注解来源范围:Spring Framework + Spring Boot + Spring Data JPA + Spring AOP + Spring Cache + Spring Scheduling + Spring Retry。 约定:下文所有示例均基于 Spring Boot 项目,包路径省略。示例中 @Service、@Repository 等注解未重复展示之处,默认已配合 @ComponentScan 自动扫描。 🗺️ 二、注解分类全景图 在实际进入每个注解之前,先用一张分类图建立全局认知: flowchart LR classDef root fill:#0f172a,stroke:#3b82f6,stroke-width:2px,color:#bfdbfe,font-weight:bold; classDef branch fill:#2d1a05,stroke:#f59e0b,stroke-width:2px,color:#fde68a,font-weight:bold; classDef leaf fill:#1e1e24,stroke:#6b7280,stroke-width:1.5px,color:#e5e7eb; ROOT[Spring注解体系] ROOT --> B1[1.IoC容器核心] ROOT --> B2[2.Boot启动配置] ROOT --> B3[3.AOP切面] ROOT --> B4[4.事务管理] ROOT --> B5[5.异步与定时] ROOT --> B6[6.缓存管理] ROOT --> B7[7.数据校验] ROOT --> B8[8.JPA数据访问] ROOT --> B9[9.事件监听] ROOT --> B10[10.测试支持] ROOT --> B11[11.条件装配] ROOT --> B12[12.重试机制] class ROOT root; class B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12 branch; 📦 三、Spring IoC 容器核心注解 IoC(控制反转)和 DI(依赖注入)是 Spring 的根基。以下是日常开发中必用的注解。 ...

九月 17, 2022 · 17 分钟 · 3415 字 · yaomingye
Cat Radio