spring-boot-starter-validation数据校验

发布时间 2023-06-07 22:16:48作者: TestRookie

依赖

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

 

bean

import boot.annotation.Status;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class RegistryUser {
    @NotBlank(message = "用户名不能为空")
    private String userName;

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

    @Min(value = 0, message = "年龄最小为0")
    @Max(value = 100, message = "年龄最大为100")
    private Integer age;

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

    private Boolean admin;

    @Pattern(regexp = "^1[0-9]{10}$", message = "手机号码格式错误")
    @NotBlank(message = "手机号不能为空")
    private String phone;

    @Status(statusType = {"1","2"})//自定义的注解校验
    private Integer status;

}

自定义注解@Status

import boot.config.StatusValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {StatusValidator.class})//约束条件
public @interface Status {
    String[] statusType() default {};

    String  message() default "状态传递有误";

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

    Class<? extends Payload>[] payload() default {};
}
/**
 * 注解内的 Class<?>[] groups() default {};
 * Class<? extends Payload>[] payload() default  {}; 不要忘记,且名称固定,否则使用时报错
 *javax.validation.ConstraintDefinitionException: HV000074: com.yoona.MyAnnotation contains Constraint annotation, but does not contain a payload(或者为groups) parameter.
 *
 */

StatusValidator类自定义校验逻辑

import boot.annotation.Status;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;

public class StatusValidator implements ConstraintValidator<Status,Integer> {

    private List<String> typeStatus;

    @Override
    public void initialize(Status constraintAnnotation) {
        typeStatus = Arrays.asList(constraintAnnotation.statusType());
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
        if(value != null){
            if(!typeStatus.contains(String.valueOf(value))){
                return false;
            }
        }
        return true;
    }
}

使用全局捕获参数校验异常

import boot.utils.Result;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


@RestControllerAdvice
public class GlobalExceptionHandler {
    //全局异常处理
    @ExceptionHandler(Exception.class)
    public Result error(Exception e){
        e.printStackTrace();
        //return Result.fail("系统出现异常啦");
        return Result.fail(e.getMessage());
    }

    //添加参数校验异常处理
    @ExceptionHandler(MethodArgumentNotValidException.class) //BindException
    public Result bindExceptionHandler(MethodArgumentNotValidException e){
        e.printStackTrace();
        return Result.fail(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

}

 

测试代码controller

import boot.controller.beans.RegistryUser;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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;
import javax.validation.constraints.NotBlank;

@RestController
@Validated//在此处添加注解,则里面的get请求无需再添加Valid注解
public class RegistryController {

    //Controller中必须加上@Valid注解校验才生效
    @PostMapping("registryUser")
    public String registryUser(@RequestBody @Valid RegistryUser registryUser){
        System.out.println(registryUser.getUserName());
        return "注册成功";
    }

    @GetMapping("login")
    public String login(@NotBlank(message = "姓名不能为空") String name){
        System.out.println(name);
        return "登录成功";
    }
}

 

post请求

 

 

 

get请求