Springboot3实体属性校验
3

1.使用 Jakarta Validation (原 javax.validation) 注解进行验证:

// 实体类
import jakarta.validation.constraints.*;

@Data
public class UserDTO {
    @NotNull(message = "用户名不能为空")
    @Size(min = 2, max = 20, message = "用户名长度必须在2-20之间")
    private String username;
  
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, message = "密码长度不能小于6位")
    private String password;
  
    @Email(message = "邮箱格式不正确")
    private String email;
}

2.在 Controller 中使用 @Valid 或 @Validated 注解:

@RestController
@RequestMapping("/api")
public class UserController {
  
    @PostMapping("/user")
    public ResponseEntity<?> createUser(@Valid @RequestBody UserDTO userDTO) {
        // 处理业务逻辑
        return ResponseEntity.ok().build();
    }
}

3.修改全局异常处理器,添加参数验证异常处理:

@ControllerAdvice
public class GlobalExceptionHandler {

    // 处理自定义异常
    @ExceptionHandler(CustomException.class)
    public ResponseEntity<Object> handleCustomException(CustomException ex) {
        Map<String, Object> body = new HashMap<>();
        body.put("status", 4001);
        body.put("message", ex.getMessage());
        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
    }

    // 处理参数验证异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, Object> body = new HashMap<>();
        List<String> errors = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toList());
    
        body.put("status", 4002);
        body.put("message", "参数验证失败");
        body.put("errors", errors);
    
        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
    }
}

4.在 pom.xml 中添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

5.常用的验证注解:

@NotNull        // 不能为null
@NotEmpty       // 不能为空,用于集合
@NotBlank       // 不能为空,用于String,会去除前后空格
@Size           // 长度或大小范围
@Min            // 最小值
@Max            // 最大值
@Email          // 邮箱格式
@Pattern        // 正则表达式
@Past           // 必须是过去的日期
@Future         // 必须是将来的日期
@Positive       // 正数
@Negative       // 负数

6.如果需要分组验证,可以这样做:

// 定义验证组
public interface Create {}
public interface Update {}

// 在实体类中使用组
public class UserDTO {
    @NotNull(groups = {Create.class, Update.class})
    private String username;
  
    @NotNull(groups = Create.class)
    private String password;
}

// 在Controller中指定组
@PostMapping("/user")
public ResponseEntity<?> createUser(@Validated(Create.class) @RequestBody UserDTO userDTO) {
    // ...
}

使用这种方式的优点是:

  1. 代码简洁,易于维护
  2. 验证逻辑与业务逻辑分离
  3. 可以自定义错误消息
  4. 支持分组验证
  5. 可以通过全局异常处理统一处理验证错误

注意事项:

  1. 确保添加了validation依赖
  2. 记得在Controller方法参数上添加@Valid或@Validated注解
  3. 可以根据需要自定义错误消息
  4. 可以组合使用多个注解
  5. 对于复杂的验证逻辑,可以自定义验证注解

我来详细分类说明这些验证注解:

字符串相关的验证注解:

  1. @NotBlank
  • 只能用于String类型
  • 判断字符串不能为null,并且去除首尾空格后长度必须大于0
@NotBlank(message = "名称不能为空")
private String name;
  1. @Size
  • 可用于String、Collection、Map、数组
  • 检查字符串长度或集合大小是否在指定范围内
@Size(min = 2, max = 30, message = "名称长度必须在2-30之间")
private String name;
  1. @Email
  • 只能用于String类型
  • 验证是否是合法的邮箱格式
@Email(message = "邮箱格式不正确")
private String email;
  1. @Pattern
  • 只能用于String类型
  • 使用正则表达式进行验证
@Pattern(regexp = "^[0-9]{11}$", message = "手机号格式不正确")
private String phone;

数字相关的验证注解:

  1. @Min
  • 用于数字类型(整数或小数)
  • 验证数字是否大于或等于指定的最小值
@Min(value = 0, message = "年龄不能小于0")
private Integer age;
  1. @Max
  • 用于数字类型(整数或小数)
  • 验证数字是否小于或等于指定的最大值
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
  1. @Positive
  • 用于数字类型
  • 验证数字是否为正数(大于0)
@Positive(message = "数量必须为正数")
private Integer quantity;
  1. @PositiveOrZero
  • 用于数字类型
  • 验证数字是否为正数或0
@PositiveOrZero(message = "数量必须大于或等于0")
private Integer quantity;
  1. @Negative
  • 用于数字类型
  • 验证数字是否为负数(小于0)
@Negative(message = "温度必须为负数")
private Integer temperature;
  1. @NegativeOrZero
  • 用于数字类型
  • 验证数字是否为负数或0
@NegativeOrZero(message = "温度必须小于或等于0")
private Integer temperature;
  1. @DecimalMin
  • 用于数字类型
  • 验证数字是否大于或等于指定的最小值(可以指定是否包含边界值)
@DecimalMin(value = "0.1", message = "比例必须大于0.1")
private BigDecimal ratio;
  1. @DecimalMax
  • 用于数字类型
  • 验证数字是否小于或等于指定的最大值(可以指定是否包含边界值)
@DecimalMax(value = "1.0", message = "比例必须小于1.0")
private BigDecimal ratio;

通用的验证注解:

  1. @NotNull
  • 可用于任何类型
  • 验证属性值不能为null
@NotNull(message = "对象不能为null")
private Object obj;
  1. @NotEmpty
  • 可用于String、Collection、Map、数组
  • 验证对象不能为null且不能为空(长度或大小必须大于0)
@NotEmpty(message = "列表不能为空")
private List<String> items;

实际使用示例:

@Data
public class UserDTO {
    // 字符串验证
    @NotBlank(message = "用户名不能为空")
    @Size(min = 2, max = 20, message = "用户名长度必须在2-20之间")
    private String username;
  
    // 数字验证
    @Min(value = 0, message = "年龄不能小于0")
    @Max(value = 150, message = "年龄不能大于150")
    private Integer age;
  
    // 邮箱验证
    @Email(message = "邮箱格式不正确")
    private String email;
  
    // 手机号验证
    @Pattern(regexp = "^[0-9]{11}$", message = "手机号格式不正确")
    private String phone;
  
    // 金额验证
    @PositiveOrZero(message = "金额必须大于或等于0")
    private BigDecimal amount;
}

这些注解可以组合使用,以实现更复杂的验证需求。同时,你也可以自定义错误消息,使用占位符来实现更灵活的提示信息。

Springboot3实体属性校验
http://38.58.177.234:9908/archives/springboot3shi-ti-shu-xing-xiao-yan
作者
Administrator
发布于
更新于
许可