Javax Validation校验架构详解

你还在用if…else…校验前端传来的参数吗?还在用代码校验参数吗?如果是的话那么你们项目校验这块不是很完美。

小编这里分享通过注解校验参数,告别if…else…的时代来了!!!
本篇主要讲解Javax ValidationI注解校验架构,简单、方便、入门快,方便扩展且扩展简单,适合第一次使用注解校验的小伙伴。

如果是Spring项目那么这个架构依赖会自动引用,如果是非Spring项目得手动引用一下依赖。本文以Spring项目为主:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.16.Final</version>
    <scope>compile</scope>
</dependency>

这是注解包里面元素:
在这里插入图片描述

  • @AssertFalse 被注释的元素必须为 false
  • @AssertTrue 被注释的元素必须为 true
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
  • @Email 被注释的元素必须是电子邮箱地址
  • @Future 被注释的元素必须是一个将来的日期
  • @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @NotBlank 验证注解的元素值不为空(不为null并去除首尾位空格)
  • @NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
  • @NotNull 不为null
  • @Null 为null
  • @Past 限制必须是一个过去的日期
  • @Pattern(value) 限制必须符合指定的正则表达式
  • @Size(max,min) `B限制字符长度必须在min到max之间

验证规则

  • 在Spring项目中定义一个需要验证的model内容如下:
@Data
public class ValidatorModel {

    @NotBlank(message = "姓名不能为空")
    private String name;

    @Size(min = 3, max = 6)
    private List<String> friendNames;

    @Min(value = 18, message = "年龄未满18岁")
    @Max(value = 60, message = "年龄必须在60岁以下")
    private Integer age;

    private String tel;

    @DecimalMin(value = "30", message = "金钱不能小于30")
    private BigDecimal money;
}
  • service接口内容如下:
    因为是javax的验证构架所以在没有Spring时候也可以进行验证,注解得写在接口上,如果写在实现类将无效!!!
//开启验证注解
@Validated
public interface ValidatorService {
    void validator(@Valid ValidatorModel model, @NotNull String param);
}

service实现类就是正常逻辑处理这里不在演示了。

  • controller内容如下:
    controller接收参数传递给service,在service接口进行参数验证,如果失败将抛出异常。
@RestController
public class ValidatorController {

    @Autowired
    private ValidatorService validatorService;

    @GetMapping
    public void validator() {
        ValidatorModel model = new ValidatorModel();
        model.setName("张三");
        model.setFriendNames(Arrays.asList("李四", "王五"));
        model.setAge(20);
        model.setTel("188888888881");
        model.setMoney(new BigDecimal(100));
        validatorService.validator(model,"也可以在参数上做验证");
    }
}

异常截图:
在这里插入图片描述


以上是Javax Validation校验常用方法,可以满足多数情况,但是项目中遇到的都是少数情况,例如:

  • 添加时候需要对所有参数进行验证,更新时候只需要对某个几参数或有值的参数进行验证(分组验证)。

  • 可不可以自定义验证规则,我要验证性别,只能是男或女(自定义验证规则)。

分组验证

添加时候需要验证friendNames字段,更新时候需要验证name字段,这时得引用分组验证,修改ValidatorModel如下:

@Data
public class ValidatorModel {

    /**
     * 添加分组
     */
    public interface Create {
    }

    /**
     * 更新分组
     */
    public interface Update {
    }
    
    /**
     * 分组可以指定多个,用{}表示
     * 分组为:默认分组、更新分组
     */
    @NotBlank(message = "姓名不能为空", groups = {Default.class, Update.class})
    private String name;

    /**
     * 分组为添加分组
     */
    @Size(min = 3, max = 6, groups = {Create.class})
    private List<String> friendNames;

    @Min(value = 18, message = "年龄未满18岁")
    @Max(value = 60, message = "年龄必须在60岁以下")
    private Integer age;

    private String tel;

    @DecimalMin(value = "30", message = "金钱不能小于30")
    private Integer money;
}

把校验参数注解写在Controller上,别忘了在Controller上加@Validated注解哈!!!

@Validated
@RestController
public class ValidatorController {

    @Autowired
    private ValidatorService validatorService;

    @GetMapping
    public void validator() {
        ValidatorModel model = new ValidatorModel();
        model.setName("张三");
        model.setFriendNames(Arrays.asList("李四", "王五"));
        model.setAge(2);
        model.setTel("188888888881");
        model.setMoney(100);
        model.setEmail("a");
        validatorService.validator(model, "也可以在参数上做验证");
    }

    @GetMapping("/group")
    public void validatorGroup(@Validated({ValidatorModel.Create.class}) ValidatorModel model) {
        validatorService.validatorGroup(model, "也可以在参数上做验证");
    }
}

这样就可以实现分组验证了。
注意:model里有一个默认分组,如果指定分组就按分组来验证参数,而没有指定的分组属于默认分组,上图的Controller不会对默认分组进行验证,写成@Validated({ValidatorModel.Create.class, Default.class})把默认分组加进去就可以验证了。如下:

	@GetMapping("/group")
    public void validatorGroup(@Validated({ValidatorModel.Create.class, Default.class}) ValidatorModel model) {
        validatorService.validatorGroup(model, "也可以在参数上做验证");
    }

自定义验证规则

那如果我想验证手机怎么办呢?它里面没有提供,不要慌小朋友,使用自定义注解验证就可以了,它提供了接口我们只需要实现一下就好了。

首先需要我们自定义一个验证手机号的注解(MonkeyTel),并指定其实现类,在实现写验证的逻辑就可以了。注解如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
// 指定真正实现校验规则的类
@Constraint(validatedBy = MonkeyJavaTelImpl.class)
public @interface MonkeyJavaTel {
    String message() default "手机号必须是11位";

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

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

实现类如下:

/**
 * @Author: LailaiMonkey
 * @Description:
 * String:参数类型
 * @Date:Created in 2020-04-17 15:19
 * @Modified By:
 */
public class MonkeyJavaTelImpl implements ConstraintValidator<MonkeyJavaTel, String> {

    /**
     * 手机号是十一位为ture
     * @param value 值
     * @param context
     * @return
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return  value.length() == 11;
    }
}
  • 项目结构如下:
    忽略monkeyValidator包,自定义注解校验规则,有兴趣的小伙伴可以看下一篇博客:自定义校验注解框架自定义校验注解框架
    在这里插入图片描述

自定义验证规则

  • 缺点:
    此注解只能写有接口或Controller上才管用,如果写在实现类上是无效的。而且逻辑都写在实现类上,不知道哪些参数进行验证,还得返回到接口或Controller上查询才可以。
    不支持List集合验证,实现起来困难,只支持简单model验证。
    分组验证只能写在Controller上,写在接口不起作用(坑)。
    如果一个接口有多个实现类这个注解就不能再用了。

  • 优点:
    自定义注解实现简单,上手快。

综上所述小编利用Spring AOP自己开发了一套自定义注解,扩展性好,底层已经写好,我们只需要和上面一样定义注解并实现,再指定指定类中注入一下注解这三步操作即可。

GitHub源码地址:https://github.com/Lailaimonkey/MonkeyValidator.git

CSDN源码地址:https://download.csdn.net/download/h273979586/12338106

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值