Spring Validation 使用笔记

3 篇文章 0 订阅

一、前言

  最早在传统Spring MVC项目里,因为前端对接数据都是后端程序员自己对接的,入参很明确,后端的参数校验自然可有可无,主要看项目的安全要求和工期要求。因此后端参数校验虽然很早就用,但是断断续续,不甚了了。
  这几年,项目基本都是前后端分离模式,后端必要的参数校验自然不可少。每次使用,总是要在网上查找相应注解;同时有些不常用用法或奇怪BUG在做完后没及时总结,再一次遇到才后悔莫及。
  因此,开一篇专门的笔记,来记录常用的注解和用法以供工作中查阅,希望能坚持逐渐完善吧。

二、常用注解

注解作用
@Null验证对象是否为 null
@NotNull验证对象是否不为 null, 无法查检长度为 0 的字符串
@NotBlank字符串不为null,并且字符串trim()以后length要大于0
@NotEmpty集合或字符串不为空
@AssertTrueBoolean 对象是否为 true
@AssertFalseBoolean 对象是否为 false
@Size(min=, max=)验证对象(Array, Collection , Map, String)长度是否在给定的范围之内
@Length(min=, max=)验证字符串长度介于 min 和 max 之间
@Past验证 Date 和 Calendar 对象是否在当前时间之前,验证成立的话被注释的元素一定是一个过去的日期
@PastOrPresent过去或者现在
@Future验证 Date 和 Calendar 对象是否在当前时间之后 ,验证成立的话被注释的元素一定是一个将来的日期
@FutureOrPresent将来或者现在
@Min验证 Number 对象是否大等于指定的值
@Max验证 Number 对象是否小等于指定的值
@DecimalMax被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过 BigDecimal定义的最大值的字符串表示 .小数 存在精度
@DecimalMin被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过 BigDecimal定义的最小值的字符串表示 .小数 存在精度
@Digits(integer=,fraction=)数字格式检查。integer指定整数部分的最大长度,fraction指定小数部分的最大长度
@Positive数字,正数
@PositiveOrZero数字,正数或0
@Negative数字,负数
@NegativeOrZero数字,负数或0
@Range(min=, max=)被指定的元素必须在合适的范围内
@Pattern(regex=)字符串必须匹配正则表达式
@Valid嵌套验证、级联验证,如对象属性

三、校验方式

  • 1、在Controller方法参数前加@Valid注解
    • a)此处,@Valid 可以换成 @Validated;这两个有一些细节差别,待后期使用中完善吧;
    • b) @Valid 位置也可以放置在方法上或类上,产生的验证范围会发生变化,习惯放于参数前,更灵活。
    • c) 在验证参数后面加 BindingResult bindingResult,bindingResult会自动接收错误信息。
  • 2、 手动校验
    • a) 如果我们的数据不是来自接口传值,没有通过Controller层,但是又希望验证 Bean的参数有效性,那么可以通过手动调用 ValidatorFactory 来进行校验;
    • b) 示例如下:
    // Bean 验证器
    ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
    Validator validator = vf.getValidator();
    // 校验的业务对象:demo,Bean 类型:Demo
    Set<ConstraintViolation<Demo>> checkSet = validator.validate(demo);
    if (CollectionUtils.isNotEmpty(checkSet)) {
        // Bean验证不通过
        throw new ServiceException(checkSet.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(",")));
    }
    

四、问题记录

  • 1、 级联验证
    • a) 在Bean中存在对象属性或集合属性,需要级联验证对象中的属性时,需在属性上加“@Valid”注解,之前犯过傻,记录一下;
    • b) 示例如下:
    public class DemoDto {
    
    @Size(min = 1, message = "集合为空")
    @Valid
    private List<Detail> list;
    
  • 2、 List 集合参数验证
    • a) 可能遇到如下情况,保存一组数据,所以入参是对象集合,示例如下:
    • b) 这种情况,想要验证集合非空及对象的属性有效性,常规方式是无效的;
    • c) 参照网上的解决方式,既然集合在对象里可以级联验证,那么我们自定义一个集合类,实现List接口,示例如下:
    // 定义校验集合类
    public class ValidatorList<E> implements List<E> {          
    	@NotEmpty(message = "数据为空")
        @Valid
        private List<E> list;
    
        public List<E> getList() {
            return list;
        }
    
        public void setList(List<E> list) {
            this.list = list;
        }
    
        public ValidatorList() {
            this.list = new ArrayList<E>();
        }
    
        public ValidatorList(List<E> list) {
            this.list = list;
        }
    
        @Override
        public int size() {
            return list.size();
        }
    
        @Override
        public boolean isEmpty() {
            return list.isEmpty();
        }
    
        @Override
        public boolean contains(Object o) {
            return list.contains(o);
        }
    
        @Override
        public Iterator<E> iterator() {
            return list.iterator();
        }
    
        @Override
        public Object[] toArray() {
            return list.toArray();
        }
    
        @Override
        public <T> T[] toArray(T[] a) {
            return list.toArray(a);
        }
    
        @Override
        public boolean add(E e) {
            return list.add(e);
        }
    
        @Override
        public boolean remove(Object o) {
            return list.remove(o);
        }
    
        @Override
        public boolean containsAll(Collection<?> c) {
            return list.containsAll(c);
        }
    
        @Override
        public boolean addAll(Collection<? extends E> c) {
            return list.addAll(c);
        }
    
        @Override
        public boolean addAll(int index, Collection<? extends E> c) {
            return list.addAll(index, c);
        }
    
        @Override
        public boolean removeAll(Collection<?> c) {
            return list.removeAll(c);
        }
    
        @Override
        public boolean retainAll(Collection<?> c) {
            return list.retainAll(c);
        }
    
        @Override
        public void clear() {
            list.clear();
        }
    
        @Override
        public E get(int index) {
            return list.get(index);
        }
    
        @Override
        public E set(int index, E element) {
            return list.set(index, element);
        }
    
        @Override
        public void add(int index, E element) {
            list.add(index, element);
        }
    
        @Override
        public E remove(int index) {
            return list.remove(index);
        }
    
        @Override
        public int indexOf(Object o) {
            return list.indexOf(o);
        }
    
        @Override
        public int lastIndexOf(Object o) {
            return list.lastIndexOf(o);
        }
    
        @Override
        public ListIterator<E> listIterator() {
            return list.listIterator();
        }
    
        @Override
        public ListIterator<E> listIterator(int index) {
            return list.listIterator(index);
        }
    
        @Override
        public List<E> subList(int fromIndex, int toIndex) {
            return list.subList(fromIndex, toIndex);
        }
    }
    
    // 使用新集合类接收参数
    // 控制器
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ResponseBody
    public int save(@RequestBody @Valid ValidList<SaveDto> list, BindingResult bindingResult) {
        // 省略业务代码
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring ValidationSpring 框架提供的一种数据验证机制,用于验证用户输入的数据是否符合预期的规则。它基于 Java Bean Validation (JSR 380) 规范,并提供了一些额外的功能。 使用 Spring Validation,你可以在表单提交或者 API 请求处理过程中,对传入的数据进行验证。它可以用于验证各种类型的数据,比如表单字段、请求参数、Java 对象等。 要使用 Spring Validation,你需要定义一个验证器(Validator),实现 Validator 接口,并实现其中的 `validate` 方法。在 `validate` 方法中,你可以针对不同的字段进行验证,并通过添加错误信息到 `Errors` 对象来指示验证的结果。 作为一个示例,假设我们要验证一个用户注册表单中的用户名和密码字段。你可以创建一个相应的验证器,实现 Validator 接口,并在 `validate` 方法中添加适当的验证逻辑。例如: ```java public class UserFormValidator implements Validator { @Override public boolean supports(Class<?> clazz) { return UserForm.class.isAssignableFrom(clazz); } @Override public void validate(Object target, Errors errors) { UserForm userForm = (UserForm) target; if (userForm.getUsername().isEmpty()) { errors.rejectValue("username", "field.required", "Username is required"); } if (userForm.getPassword().length() < 8) { errors.rejectValue("password", "field.minlength", "Password must be at least 8 characters long"); } } } ``` 在上面的示例中,`supports` 方法指定了该验证器支持的目标对象类型,这里是 `UserForm` 类型。`validate` 方法中,我们分别验证了用户名和密码字段,如果验证失败,则使用 `errors.rejectValue` 方法添加相应的错误信息。 然后,你可以在控制器方法中使用该验证器进行数据验证。例如: ```java @PostMapping("/register") public String registerUser(@Validated UserForm userForm, BindingResult bindingResult) { if (bindingResult.hasErrors()) { // 处理验证错误 return "register"; } // 验证通过,继续处理注册逻辑 return "redirect:/login"; } ``` 在上面的示例中,我们使用 `@Validated` 注解标记了 `UserForm` 参数,告诉 Spring 在处理请求时要对该对象进行数据验证。验证结果会存储在 `BindingResult` 对象中,你可以根据需要进行处理。 这只是 Spring Validation 的一个简单示例,实际上它提供了丰富的验证功能和扩展点,包括自定义的验证注解、国际化支持等。你可以根据具体的需求来选择和配置合适的验证器和验证规则。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值