Spring Boot (31) 数据验证

曾经参数的验证是这样的:

    public String test(User user){
        if(user == null){
            throw new NullPointerException("user 不能为空");
        }

        if(user.getUserName() == null){
            throw new NullPointerException("userName 不能为空");
        }

        if(user.getUserName().length() < 4 || user.getUserName().length()>10){
            throw new RuntimeException("userName 长度小于4位或大于10位");
        }

        return "success";
    }

随着参数的增加,格式的变化,校验数据有效性的代码愈发繁琐。

通过Spring boot来完成参数数据校验。

JSR-303注解介绍

这里只列举了javax.validation包下的注解,同理在spring-boot-starter-web包种也存在hibernate-validator验证包,里面包含了一些javax.validation没有的注解。

注解 说明
@NotNull 限制必须不为null
@NotEmpty 验证注解的元素值不为 null 且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在 min 到 max 之间(也可以用在集合上)
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Null 限制只能为null(很少用)
@AssertFalse 限制必须为false (很少用)
@AssertTrue 限制必须为true (很少用)
@Past 限制必须是一个过去的日期
@Future 限制必须是一个将来的日期
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过 integer,小数部分的位数不能超过 fraction (很少用)

实体类

public class Book implements Serializable {

    private Integer id;

    @NotBlank(message = "name 不能为空")
    @Length(min = 2, max = 10, message = "name 长度必须在{min}-{max}之间")
    private String name;

    @NotNull(message = "price 不能为空")
    @DecimalMin(value = "0.1", message = "价格不能低于 {value}")
    private BigDecimal price;

    ...
}

控制层

这些验证注解不仅仅可以放在controller上,也可以加在service层上。

//todo 开启数据有效性校验,添加在类上即为验证方法,添加在方法参数中即为验证参数对象。(添加在方法上无效)
@Validated
@RequestMapping("/books")
@RestController
public class BookController { @GetMapping("/test1") public String test1(@NotBlank(message = "name不能为空") @Length(min = 2, max = 10 , message="name 长度必须在{min}-{max}之间") String name){ return "test1"; } @GetMapping("test2") public String test2(@Validated Book book){ return "test2"; } }

这样就可以了,在浏览器中输入 /books/test1/ 不输入参数会抛异常 /books/test1?name=sdf 则可以通过验证

/books/test2/ 异常 /books/test2?name=sdf&price=0.5就ok了

Spring Boot 还允许我们自定义Validatior

自定义注解

package com.spring.boot.utils;


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;

//@Target定义范围 在字段 参数上使用
@Target({ElementType.FIELD, ElementType.PARAMETER})
//定义可见范围 RUNTIME整个运行阶段都可见
@Retention(RetentionPolicy.RUNTIME)
//Constraint指定具体校验器类
@Constraint(validatedBy = DateTimeValidator.class)
//@interface 定义注解
public @interface DateTime {
    String message() default "格式错误";

    String format() default "yyyy-MM-dd";

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

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

具体的校验器

package com.spring.boot.utils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;

/**
 * 日期格式验证
 */
public class DateTimeValidator implements ConstraintValidator<DateTime, String> {

    private DateTime dateTime;

    @Override
    //初始化,它可以获得当前注解的所有属性
    public void initialize(DateTime constraintAnnotation) {
        this.dateTime = constraintAnnotation;
    }

    @Override
    //约束验证的主体方法,其中s就是验证参数的具体事例,context代表约束执行的上下文
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        //如果为空不用验证, 为空验证可以用@NotBlank、@NotNull等参数进行控制
        if (s == null) {
            return true;
        }

        String format = dateTime.format();
        if (s.length() != format.length()) {
            return false;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            simpleDateFormat.parse(s);
        } catch (ParseException e) {
            return false;
        }
        return true;
    }
}

然后在控制层使用他

    @GetMapping("/test3")
    public String test3(@NotBlank(message = "date 不能为空") @DateTime(message = "您如的格式错误,正确的格式为:{format}",format = "yyyy-MM-dd HH:mm") String date){
        return "test3";
    }

测试

猜你喜欢

转载自www.cnblogs.com/baidawei/p/9187453.html
今日推荐