SpringBoot整合Validation数据校验

前言

        Spring Boot 集成 Validation(数据校验)是一个常见的需求,尤其在处理前端提交的数据时。Spring 提供了对 JSR-303(即 Java Bean Validation)标准的支持,可以使用注解来声明数据校验规则。

1. 引入依赖

首先,确保你的 Spring Boot 项目已经包含了相关的依赖,特别是 spring-boot-starter-validation,它会自动引入 Hibernate Validator(JSR-303 实现)。

pom.xml 中加入以下依赖:

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

2. 创建实体类并使用校验注解

假设我们有一个用户注册的场景,我们需要对用户提交的注册信息进行校验,比如用户的姓名、邮箱、年龄等字段。

用户注册实体类:

import javax.validation.constraints.*;

public class User {

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

    @Email(message = "邮箱格式不正确")
    @NotBlank(message = "邮箱不能为空")
    private String email;

    @Min(value = 18, message = "年龄必须大于等于18岁")
    @Max(value = 100, message = "年龄必须小于等于100岁")
    private Integer age;

    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 20, message = "密码长度必须在6到20之间")
    private String password;

    // Getters and Setters
}

3. 在 Controller 中使用 @Valid 注解触发校验

在 Spring Boot 的 Controller 层,可以使用 @Valid 注解来触发数据校验。接收请求体中的数据时,Spring 会自动根据 User 类中的校验注解进行校验。

注册接口:

import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

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

    @PostMapping("/register")
    public ResponseEntity<String> register(@Valid @RequestBody User user) {
        // 如果数据校验成功,进入此方法
        return ResponseEntity.ok("用户注册成功");
    }
}
  • @RequestBody:表明请求体的内容会被映射到 User 对象。

  • @Valid:触发对 User 对象的校验。

4. 异常处理:捕获校验失败的异常

如果请求数据不符合校验规则,Spring Boot 会抛出 MethodArgumentNotValidException。我们可以通过自定义异常处理来返回更友好的错误信息。

全局异常处理:

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

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

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationException(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();

        ex.getBindingResult().getAllErrors().forEach(error -> {
            String fieldName = ((org.springframework.validation.FieldError) error).getField();
            String message = error.getDefaultMessage();
            errors.put(fieldName, message);
        });

        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}

在这个 GlobalExceptionHandler 类中,我们捕获了 MethodArgumentNotValidException 异常,并从异常中提取字段名和错误消息,最终将错误信息返回给客户端。

5. 测试

假设我们有以下数据作为请求体来测试注册接口:

有效请求体(JSON)

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

返回:

{
  "message": "用户注册成功"
}

无效请求体(JSON)

{
  "username": "",
  "email": "invalid-email",
  "age": 17,
  "password": "123"
}

返回:

{
  "username": "用户名不能为空",
  "email": "邮箱格式不正确",
  "age": "年龄必须大于等于18岁",
  "password": "密码长度必须在6到20之间"
}

6. 常见的校验注解

  • @NotNull:字段不能为 null。

  • @NotBlank:字符串不能为空,不仅检查 null 还会检查是否是空字符串。

  • @Size(min = , max = ):字符串长度的范围。

  • @Min 和 @Max:数字的最小和最大值。

  • @Email:验证是否是有效的电子邮件格式。

  • @Pattern:正则表达式验证。

  • @Positive:数字必须为正。

  • @Negative:数字必须为负。

7. 自定义校验注解

如果需要自定义复杂的校验逻辑,可以创建自己的校验注解和校验器。以下是一个简单的自定义校验注解示例。

创建自定义注解:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPassword {

    String message() default "密码必须包含至少一个字母和一个数字";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

创建校验器:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class PasswordValidator implements ConstraintValidator<ValidPassword, String> {

    @Override
    public void initialize(ValidPassword constraintAnnotation) {
    }

    @Override
    public boolean isValid(String password, ConstraintValidatorContext context) {
        if (password == null) {
            return false;
        }
        return password.matches(".*[a-zA-Z].*") && password.matches(".*[0-9].*");
    }
}

使用自定义注解:

public class User {

    @ValidPassword
    private String password;

    // Getters and Setters
}

总结

  1. Spring Boot 默认集成了 Hibernate Validator,支持使用 JSR-303 注解进行数据校验。

  2. 使用 @Valid 注解来触发校验,@RequestBody 注解用于接收请求体。

  3. @NotNull@Size@Min@Max 等是常用的校验注解,支持基本的字段校验。

  4. 自定义校验注解可以通过实现 ConstraintValidator 接口来完成。

  5. 异常处理可以通过 @RestControllerAdvice 捕获和处理校验异常,返回友好的错误信息。

这样,你就可以在 Spring Boot 中使用验证框架来轻松实现数据的校验,增强应用的健壮性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值