【详解】SpringBootValidator校验相关的注解信息

时间:2025-01-11 18:53:07

Spring Boot Validator校验相关的注解信息

在开发Web应用时,数据校验是一个非常重要的环节。Spring Boot 提供了强大的校验机制,帮助开发者轻松实现对请求参数的校验。本文将详细介绍Spring Boot中常用的校验注解及其用法。

1. 基础环境配置

在开始之前,确保你的Spring Boot项目中已经添加了spring-boot-starter-validation依赖。如果你使用的是Maven,可以在pom.xml文件中添加如下依赖:

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

2. 常用校验注解

2.1 @NotNull

  • 作用:验证对象是否不为空。
  • 示例
@NotNull(message = "name cannot be null")
private String name;

2.2 @NotEmpty

  • 作用:验证集合、数组、字符串等是否不为空且长度大于0。
  • 示例
@NotEmpty(message = "list cannot be empty")
private List<String> items;

2.3 @NotBlank

  • 作用:验证字符串是否不为空且去掉首尾空格后长度大于0。
  • 示例
@NotBlank(message = "description cannot be blank")
private String description;

2.4 @Size

  • 作用:验证字符串、集合、数组等的大小是否在指定范围内。
  • 示例
@Size(min = 5, max = 10, message = "name size must between 5 and 10")
private String name;

2.5 @Min 和 @Max

  • 作用:验证数值是否在指定范围内。
  • 示例
@Min(value = 18, message = "age must be at least 18")
@Max(value = 100, message = "age must be at most 100")
private int age;

2.6 @DecimalMin 和 @DecimalMax

  • 作用:验证小数是否在指定范围内。
  • 示例
@DecimalMin(value = "0.0", message = "price must be at least 0.0")
@DecimalMax(value = "1000.0", message = "price must be at most 1000.0")
private double price;

2.7 @Pattern

  • 作用:验证字符串是否符合正则表达式。
  • 示例
@Pattern(regexp = "^[a-zA-Z0-9]+$", message = "username must contain only letters and numbers")
private String username;

2.8 @Email

  • 作用:验证字符串是否为有效的电子邮件地址。
  • 示例
@Email(message = "email is not valid")
private String email;

2.9 @AssertTrue 和 @AssertFalse

  • 作用:验证布尔值是否为真或假。
  • 示例
@AssertTrue(message = "terms must be accepted")
private boolean termsAccepted;

@AssertFalse(message = "isDeleted must be false")
private boolean isDeleted;

2.10 @Future 和 @Past

  • 作用:验证日期是否在未来或过去。
  • 示例
@Future(message = "event date must be in the future")
private Date eventDate;

@Past(message = "birth date must be in the past")
private Date birthDate;

3. 自定义校验注解

除了上述内置的校验注解外,Spring Boot还支持自定义校验注解。通过实现ConstraintValidator接口,可以创建自己的校验逻辑。

3.1 创建自定义注解

@Constraint(validatedBy = MyCustomValidator.class)
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
    String message() default "custom validation failed";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

3.2 实现校验逻辑

public class MyCustomValidator implements ConstraintValidator<MyCustomAnnotation, String> {

    @Override
    public void initialize(MyCustomAnnotation constraintAnnotation) {
        // 初始化逻辑
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 校验逻辑
        return value != null && value.startsWith("custom");
    }
}

3.3 使用自定义注解

public class User {
    @MyCustomAnnotation(message = "username must start with 'custom'")
    private String username;
}

4. 校验控制器参数

在Spring Boot中,可以通过@Valid@Validated注解来校验控制器参数。

4.1 使用@Valid

@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
    // 处理逻辑
    return ResponseEntity.ok(user);
}

4.2 使用@Validated

@RestController
@RequestMapping("/users")
@Validated
public class UserController {

    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
        // 处理逻辑
        return ResponseEntity.ok(user);
    }
}

5. 处理校验错误

当校验失败时,Spring Boot会抛出MethodArgumentNotValidException异常。你可以通过全局异常处理器来处理这些异常,并返回友好的错误信息。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return ResponseEntity.badRequest().body(errors);
    }
}


Spring Boot提供的校验机制非常强大且易于使用。通过合理的使用内置注解和自定义注解,可以有效提升应用的数据校验能力,减少潜在的错误。希望本文能帮助你在实际项目中更好地应用这些校验注解。



在Spring Boot中,@Valid@Validated 注解用于数据校验,而 javax.validation 包中的注解(如 @NotNull, @NotEmpty, @Size 等)则用于具体的字段校验。下面是一个实际的应用场景示例,展示如何在Spring Boot中使用这些注解进行数据校验。

示例场景

一个用户注册功能,需要对用户的输入进行校验。具体要求如下:

  • 用户名不能为空,且长度在3到20个字符之间。
  • 邮箱地址必须是有效的邮箱格式。
  • 密码不能为空,且长度至少为8个字符。

实体类

首先,定义一个用户实体类 User,并在字段上添加校验注解:

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;

public class User {

    @NotEmpty(message = "用户名不能为空")
    @Size(min = 3, max = 20, message = "用户名长度必须在3到20个字符之间")
    private String username;

    @Email(message = "邮箱地址格式不正确")
    private String email;

    @NotEmpty(message = "密码不能为空")
    @Size(min = 8, message = "密码长度至少为8个字符")
    private String password;

    // Getters and Setters
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

控制器

接下来,在控制器中使用 @Valid 注解来校验请求参数,并处理校验错误:

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;

@RestController
public class UserController {

    @PostMapping("/register")
    public String register(@Valid @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return bindingResult.getAllErrors().stream()
                    .map(ObjectError::getDefaultMessage)
                    .collect(Collectors.joining(", "));
        }
        // 处理注册逻辑
        return "注册成功";
    }
}

配置类

为了使校验消息更加友好,可以配置一个全局异常处理器来统一处理校验错误:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return errors;
    }
}

测试

启动应用后,可以通过POST请求测试注册功能。例如,使用Postman发送以下请求:

{
    "username": "john",
    "email": "john@example.com",
    "password": "password123"
}

如果输入不符合校验规则,将返回相应的错误信息,例如:

{
    "username": "用户名长度必须在3到20个字符之间",
    "password": "密码长度至少为8个字符"
}

通过这种方式,你可以轻松地在Spring Boot应用中实现数据校验,确保输入数据的有效性和完整性。在Spring Boot中,使用@Valid@Validated等注解可以对控制器方法的参数进行数据校验。这些校验通常通过JSR 380(Bean Validation 2.0)标准来实现,Spring Boot默认集成了Hibernate Validator作为其实现。

下面是一些常用的校验注解及其用法:

常用的校验注解

  1. @NotNull
  • 确保字段不为null。
  • 示例:@NotNull private String name;
  1. @NotEmpty
  • 确保字段不为null且不为空字符串(对于集合类型,确保集合不为空)。
  • 示例:@NotEmpty private String name;
  1. @NotBlank
  • 确保字段不为null且不为空字符串(去除前后空格后)。
  • 示例:@NotBlank private String name;
  1. @Size(min=, max=)
  • 确保字段的长度在指定范围内。
  • 示例:@Size(min=5, max=10) private String name;
  1. @Min(value)
  • 确保字段的值大于或等于指定的最小值。
  • 示例:@Min(18) private int age;
  1. @Max(value)
  • 确保字段的值小于或等于指定的最大值。
  • 示例:@Max(100) private int age;
  1. @DecimalMin(value)
  • 确保字段的值大于或等于指定的最小值(适用于浮点数)。
  • 示例:@DecimalMin("18.5") private double height;
  1. @DecimalMax(value)
  • 确保字段的值小于或等于指定的最大值(适用于浮点数)。
  • 示例:@DecimalMax("190.5") private double height;
  1. @Pattern(regexp)
  • 确保字段的值符合指定的正则表达式。
  • 示例:@Pattern(regexp="^[a-zA-Z0-9]+$") private String username;
  1. @Email
  • 确保字段的值是一个有效的电子邮件地址。
  • 示例:@Email private String email;

示例代码

假设我们有一个用户注册的接口,需要对用户的姓名、年龄和邮箱进行校验。

实体类
import javax.validation.constraints.*;

public class User {

    @NotBlank(message = "Name must not be blank")
    private String name;

    @Min(value = 18, message = "Age must be at least 18")
    @Max(value = 100, message = "Age must be at most 100")
    private int age;

    @Email(message = "Email must be valid")
    private String email;

    // Getters and Setters
}
控制器
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping
    public String createUser(@Valid @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return bindingResult.getAllErrors().stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.joining(", "));
        }
        // 处理用户创建逻辑
        return "User created successfully";
    }
}

解释

  1. 实体类 User:
  • @NotBlank 确保 name 字段不为空且不只包含空格。
  • @Min@Max 确保 age 字段在18到100之间。
  • @Email 确保 email 字段是一个有效的电子邮件地址。
  1. 控制器 UserController:
  • @Valid 注解用于触发对 User 对象的校验。
  • BindingResult 对象用于捕获校验错误,并返回给客户端。

通过这种方式,你可以在Spring Boot应用中轻松地实现输入参数的校验,提高应用的健壮性和用户体验。