Spring MVC:装配、请求与校验
前置:Java类、接口、异常与集合,以及HTTP请求/响应。本篇用一个创建、查询和修改任务的教学应用解释分层;TaskController、TaskService、TaskRepository的完整定义见Spring完整项目源码(examples/java/p2-spring/src/main/java/notes/tasks)。示例未执行;命令与现象均为读者未来自行验证的步骤和预期,不能视为运行记录。
Spring的构造器注入解决什么问题
Spring的构造器注入解决什么问题?Spring容器保存对象定义和实例,构造器明确列出依赖,使TaskController依赖TaskService、TaskService依赖TaskRepository。单个构造器不需要@Autowired,组件扫描从TasksApplication所在包向下寻找@Service、@RestController等组件;把类放在父包之外会导致找不到Bean。构造器注入让缺失依赖在启动阶段暴露,也方便在纯单元测试中传入替身;它不自动消除循环依赖。
默认单例是每个容器一个实例,控制器可能同时处理多个请求。因此请求草稿只放方法局部变量,不把当前用户、当前Task或错误信息放在单例字段。Repository代理负责数据库访问,不能把HTTP请求对象塞进实体。@SpringBootApplication组合配置、组件扫描和自动配置;自动配置依据类路径、配置和已有Bean有条件生效,不能理解成无条件替你选择所有业务组件。
Spring MVC请求怎样经过控制器和异常处理
Spring MVC请求怎样经过控制器和异常处理?HTTP请求先由Servlet容器接收,DispatcherServlet依据映射选择控制器方法;转换器把JSON读为DTO,Bean Validation检查@Valid参数,再进入服务层。服务代理开启事务,Repository访问数据库;服务正常返回后,转换器把View输出为JSON。控制器是HTTP边界,服务是业务和事务边界,实体是持久化状态,三者职责不同。
请求体无法解析时尚未进入业务方法,缺少必填字段也不应写数据库。@RestControllerAdvice统一处理校验、已知业务错误和版本冲突,不把SQL、堆栈或异常类名返回给调用者。无法预期的异常记录服务端日志并返回通用500。本例只规定所列路径和方法;不把全站404、媒体类型协商或Servlet容器错误都宣称为同一业务契约。
Spring怎样区分JSON解析校验和业务校验
Spring怎样区分JSON解析校验和业务校验?JSON解析先判断形状和类型:请求体必须是对象,done必须是布尔值,字符串字段不接受数字/布尔值的隐式转换,未知字段被拒绝。DTO的@NotBlank/@Size检查标题,@NotNull检查done,Update版本还检查规范十进制格式;之后服务检查Long范围和当前版本。版本冲突不是输入语法错误,应返回409;任务不存在返回404;输入不可解析或不合法返回400。
前端校验用于及时反馈,服务端校验负责最终约束。@Size按Java UTF-16长度计算,不能等同用户看到的字形数量;JavaScript length也按UTF-16,但空白字符定义可能不同,因此服务端仍裁决。标题strip在保存前清首尾空白;实体@Column(nullable=false,length=120)提供数据库约束,但不能替代可解释的输入校验。
Spring教学项目为什么固定Boot和Java版本
Spring教学项目为什么固定Boot和Java版本?本例固定Spring Boot 3.5.7、Java21、Maven3.6.3+。3.5.7是官方已经发布的教学基线,不宣称是当前最新维护版本;Boot parent管理Spring Framework、Hibernate、Jackson、H2和测试依赖的兼容组合,读者不要随意覆盖单个核心组件版本。实际部署应另外检查支持周期和安全公告,本轮未安装或验证依赖解析。
Jakarta命名空间是本例前提:实体用jakarta.persistence,约束用jakarta.validation,不混用javax旧示例。项目无Spring Security、无登录和所有者模型,只绑定本机。学习前先理解Java对象、异常和集合,可回看Java基础。官方发布依据:Boot3.5.7公告,事务机制见声明式事务。
练习:边界分层判断
不运行项目,分别判断以下请求应在哪层失败及状态码:①创建title为数字12;②title为空白但done合法;③更新携带规范字符串版本但已过期;④请求未知属性extra。再说明能否在单例控制器字段保存当前请求的Task。
参考答案(推演,未执行)
①Jackson消息转换拒绝数字转字符串,400;②Bean Validation拒绝@NotBlank,400;③服务比较或数据库乐观锁报告409;④未知字段配置在转换阶段拒绝,400。前两类失败不能写入数据库。单例控制器处理并发请求,保存当前Task会交叉污染,必须使用局部变量/参数;构造器字段只保留服务依赖。
继续阅读
- 排错
- 排错
- 开发实践