活到老学到老-Spring参数校验注解Validated /Valid

通过 @Validated 和 @Valid可以对请求的进行参数校验。

1.核心对比:

特性@Valid (JSR-303)@Validated (Spring)
来源Java标准规范Spring框架扩展
分组校验不支持支持(通过groups属性)
嵌套路径自动处理级联校验需配合@Valid生效
应用范围方法参数、属性、返回值类、方法、参数
List校验需放在集合声明处需配合@Valid生效

2.基础使用示例

 2.1 单对象校验

public class UserDTO {
    @NotBlank(message = "用户名不能为空")
    private String username;
    
    @Email(message = "邮箱格式错误")
    private String email;
}

// 使用@Valid
@PostMapping("/users")
public Result createUser(@RequestBody @Valid UserDTO user) {
    // ...
}

// 使用@Validated
@RestController
@Validated // 类级别启用校验
public class UserController {
    @PostMapping("/users")
    public Result createUser(@RequestBody @Validated UserDTO user) {
        // ...
    }
}

3. 级联属性校验

3.1 嵌套对象校验
public class OrderDTO {
    @NotNull
    private Long orderId;
    
    @Valid // 关键注解,启用嵌套校验
    private UserDTO user;
}

// 测试
@PostMapping("/orders")
public Result createOrder(@RequestBody @Valid OrderDTO order) {
    // 会自动校验order.user里的约束
}
3.2 集合元素校验
public class BatchRequest {
    @Size(min = 1, max = 10)
    private List<@Valid UserDTO> users; // 校验每个元素
}

@PostMapping("/batch")
public Result batchCreate(@RequestBody @Valid BatchRequest request) {
    // 会校验list内每个UserDTO
}

4. 分组校验(仅@Validated支持)

4.1 定义校验分组
public interface CreateCheck {}
public interface UpdateCheck {}

public class ProductDTO {
    @Null(groups = CreateCheck.class) // 创建时ID必须为空
    @NotNull(groups = UpdateCheck.class) // 更新时ID不能为空
    private Long id;
    
    @NotBlank(groups = {CreateCheck.class, UpdateCheck.class})
    private String name;
}
4.2 使用分组
@PostMapping("/products")
public Result create(@RequestBody @Validated(CreateCheck.class) ProductDTO product) {
    // 仅触发CreateCheck组的校验
}

@PutMapping("/products/{id}")
public Result update(@PathVariable Long id, 
                   @RequestBody @Validated(UpdateCheck.class) ProductDTO product) {
    // 仅触发UpdateCheck组的校验
}

5.统一异常处理

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    // 处理@Validated和@Valid抛出的异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValidException(MethodArgumentNotValidException e) {
        List<String> errors = e.getBindingResult()
            .getFieldErrors()
            .stream()
            .map(error -> error.getField() + ": " + error.getDefaultMessage())
            .collect(Collectors.toList());
        return Result.fail(400, "参数错误", errors);
    }
}

6.最佳实现

6.1 混合使用
类/方法级用 @Validated

参数/属性级用 @Valid
6.2 性能优化
// 避免在循环中校验
@Validated
@Service
public class UserService {
    public void batchProcess(@Valid List<UserDTO> users) {
        // 批量处理
    }
}
6.3 自定义校验
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {
    String message() default "手机号格式错误";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
6.4 复杂场景
// 级联校验+集合校验
public class DepartmentDTO {
    @Valid
    private List<@Valid EmployeeDTO> employees;
    
    @Valid
    private AddressDTO location;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zbqice007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值