@Validated和@Valid的区别

在Controller中校验方法参数时,使用@Valid和@Validated并无特殊差异(若不需要分组校验的话): @Valid:标准JSR-303规范的标记型注解,用来标记验证属性和方法返回值,进行级联和递归校验 @Validated:Spring的注解,是标准JSR-303的一个变种(补充),提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制

方法级别: @Validated注解可以用于类级别,用于支持Spring进行方法级别的参数校验。@Valid可以用在属性级别约束,用来表示级联校验。 @Validated只能用在类、方法和参数上,而@Valid可用于方法、字段、构造器和参数上

校验参数、级联属性

1、校验参数 当入参为实体对象时,需要在方法上加@Valid或@Validated或者在参数前加@Valid或@Validated,或者在类上加@Validated

@Valid @GetMapping("/exam-info") public Boolean getInfo(User user){......}

@GetMapping("/exam-info") public Boolean getInfo(@Valid User user){......}

@Validated @GetMapping("/exam-info") public Boolean getInfo(User user){......}

@GetMapping("/exam-info") public Boolean getInfo(@Validated User user){......}

public Class User{ @NotNull("id不能为空") private Integer id; }

2、嵌套验证      @valid作用于属性上有嵌套验证作用,@validated不能作用于属性上,如下代码在User类的属性car上添加@valid注解,当传参id为空时会报错。

@GetMapping("/exam-info") public Boolean getInfo(@Valid User user){.....}

public class User{ @Valid @NotNull("car不能为空") private Car car; } public class Car{ @NotNull("id不能为空") private Integer id; }

校验List

@Valid只能校验JavaBean,而List<E>不是JavaBean所以校验会失败,介绍三种解决办法

方法1:对List进行Wrapper

既然List不是JavaBean,那我们就把它封装成JavaBean,我们定义一个ListWrapper类如下:

public class ListWrapper<E> { @Valid
@NotEmpty(message="列表不能为空!", groups = {Creation.class, Modification.class})private List<E> list;public ListWrapper() {list = new ArrayList<>();}public  ListWrapper(List<E> list) {this.list = list;}public setList(List<E> list){this.list = list;}public getList(){return list;}
}

同时修改一下controller对应的方法:

// 使用包装类对list进行验证
@PostMapping("/insert/all")
public ServerResponse<String> insertList(@Valid @RequestBody ListWrapper<UserEntity> listWrapper, BindingResult bindingResult) {if(bindingResult.hasErrors()) {log.error(bindingResult.getFieldError().toString());return ServerResponse.createByErrorMessage(bindingResult.getFieldError().getDefaultMessage());}userService.insertList(listWrapper.getList());return ServerResponse.createBySuccess();
}

这样就可以对list进行校验了

注意:

由于对list进行了包装,如果我们传参的时候

[{},{}..]要改为{“list”: [{},{}..]}

方法2:使用@Validated+@Valid

在controller类上面增加@Validated注解,并且删除方法参数中的BindingResult bindingResult(因为这个参数已经没有用了,异常统一有controller返回了) 

然后我们运行一下测试一下

可以看到可以对参数进行校验了,但还还有一个问题,那就是这个不是我们想要的返回格式,它controller自己返回的格式,所以我们需要做一个统一异常处理,代码如下:

import com.wyq.firstdemo.common.ServerResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;@Slf4j
@RestControllerAdvice
public class ControllerExceptionHandler {@ExceptionHandler
@ResponseBody
public ServerResponse<String> handle(ConstraintViolationException exception) {log.error(String.valueOf(exception));Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();StringBuilder builder = new StringBuilder();for (ConstraintViolation violation : violations) {builder.append(violation.getMessage());break;}return ServerResponse.createByErrorMessage(builder.toString());
}
}

}经过统一异常处理,我们这边的返回结果就是我们想要的格式了

方法3:自定义一个List

先上代码后说明,先定义一个ValidList

import javax.validation.Valid;
import java.util.*;public class ValidationList<E> implements List<E> {@Valid
@NotEmpty(message="列表不能为空!", groups = {Creation.class, Modification.class})private List<E> list;public ValidationList() {this.list = new ArrayList<>();}@Overridepublic int size() {return list.size();}@Overridepublic boolean isEmpty() {return list.isEmpty();}@Overridepublic boolean contains(Object o) {return list.contains(o);}@Overridepublic Iterator<E> iterator() {return list.iterator();}@Overridepublic Object[] toArray() {return list.toArray();}@Overridepublic <T> T[] toArray(T[] a) {return list.toArray(a);}@Overridepublic boolean add(E e) {return list.add(e);}@Overridepublic boolean remove(Object o) {return list.remove(o);}@Overridepublic boolean containsAll(Collection<?> c) {return list.containsAll(c);}@Overridepublic boolean addAll(Collection<? extends E> c) {return list.addAll(c);}@Overridepublic boolean addAll(int index, Collection<? extends E> c) {return list.addAll(index, c);}@Overridepublic boolean removeAll(Collection<?> c) {return list.removeAll(c);}@Overridepublic boolean retainAll(Collection<?> c) {return list.retainAll(c);}@Overridepublic void clear() {list.clear();}@Overridepublic E get(int index) {return list.get(index);}@Overridepublic E set(int index, E element) {return list.set(index, element);}@Overridepublic void add(int index, E element) {list.add(index, element);}@Overridepublic E remove(int index) {return list.remove(index);}@Overridepublic int indexOf(Object o) {return list.indexOf(o);}@Overridepublic int lastIndexOf(Object o) {return list.lastIndexOf(o);}@Overridepublic ListIterator<E> listIterator() {return list.listIterator();}@Overridepublic ListIterator<E> listIterator(int index) {return list.listIterator(index);}@Overridepublic List<E> subList(int fromIndex, int toIndex) {return list.subList(fromIndex, toIndex);}public List<E> getList() {return list;}public void setList(List<E> list) {this.list = list;}}

对比方法3和方法1,有没有觉得代码有点相似,新建一个类,并且让他实现List接口,使这个类即具有了JavaBean的特性,又具有了List的特性,比方法1简单优雅很多。

只需要把List换成ValidList就可以了,还不需要多统一异常处理。

参考:https://my.oschina.net/fangshixiang/blog/3081366

https://stackoverflow.com/questions/28150405/validation-of-a-list-of-objects-in-spring/36313615#36313615

https://my.oschina.net/fangshixiang/blog/3081366

转自https://my.oschina.net/u/3635618/blog/3119870

@Validated和@Valid校验参数、级联属性、List相关推荐

  1. @Validated和@Valid校验参数

    @Validated和@Valid校验参数 参考: @Validated和@Valid校验参数.级联属性.List java valid payload_Spring Validation最佳实践及其 ...

  2. @Validated与@Valid校验

    痛点:开发接口的时候,对于请求参数,往往需要进行校验,这个时候可以采用如下方式校验请求参数id和number,显然这种方式难以维护,即便封装成方法,依旧麻烦. @PostMapping("/ ...

  3. validated 验证数组_@Validated和@Valid的区别?校验级联属性(内部类)

    NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以 ...

  4. springMVC 优雅的校验参数(@Valid和@Validated)

    很痛苦遇到大量的参数进行校验,在业务中还要抛出异常或者不断的返回异常时的校验信息,在代码中相当冗长, 充满了if-else这种校验代码,今天我们就来学习spring的javax.validation ...

  5. notnull注解_参数校验注解Validated和Valid的区别,这次终于有人说清楚了

    Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR- ...

  6. @valid 校验_一文带你快速入手 Spring Boot 参数校验

    点击上方"Java专栏",选择"置顶或者星标" 第一时间阅读精彩文章! ☞ 程序员进阶必备资源免费送「21种技术方向!」 点击查看☜ 作者:狂乱的贵公子 来源: ...

  7. 面试:说说参数验证 @Validated 和 @Valid 的区别?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | blog.csdn.net/qq_276803 ...

  8. 参数验证 @Validated 和 @Valid 的区别,Java Web 开发必备。

    Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303 规范,是标准 JSR-303 的一个变种),javax提供了@Valid(标准J ...

  9. Spring Validation验证框架参数验证 @Validated 和 @Valid 的区别

    参数验证 @Validated 和 @Valid 的区别 Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303 规范,是标准 JSR- ...

最新文章

  1. 这10道Java面试题!95%的人回答不出来!
  2. python爬虫如何从一个页面进入另一个页面-爬虫入门(一)——如何打开一个网页...
  3. 关于《设计模式》这本书(三)——Proxy模式
  4. Python爬虫,通过特定的函数来筛选标签
  5. STM32 SPI NSS 引脚为不能拉高问题
  6. 现代密码学1.4--现代密码的三大原则
  7. 【学习笔记】17、函数(Function)的定义和调用
  8. docker desktop 镜像_Spring Boot实战工具4 - Docker
  9. 【杂项】原来有两种单引号(单引号和反引号)
  10. 天津2021年高考成绩查询入口,2021年天津高考成绩查询时间安排 什么时候出分
  11. 数据库-优化-每个字段的说明
  12. GB28181开放流媒体服务平台LiveGBS实际测试时问题排查
  13. 微博关注者数量在计算中的作用
  14. 如何支撑企业快速构建数字孪生体
  15. CUDA——调试“ImportError: libcudart.so.9.2: cannot open shared object file: No such file or directory”
  16. GDB中打印pthread_internal_t的方法
  17. Adobe产品序列号
  18. 计算机一级插入页眉,计算机一级考试,设置页眉为“汉字的交换码”
  19. MTK-EngineeMode-Hardware Testing
  20. 1800 Flying to the Mars 大数 最多不上升序列 简化题意

热门文章

  1. Lock-step 锁步核有哪些
  2. linux库怎么安装路径设置,Linux libtins 库安装教程
  3. python复制文件夹shutil.copytree
  4. java获取当前月和周的第一天和最后一天
  5. DASCTF Oct X 吉林工师 欢迎来到魔法世界~ WriteUp
  6. Linux UART接口调试技巧
  7. git设置master权限_Gitlab权限管理
  8. Servlet转发和重定向的异同
  9. 《O2P卸甲笔记》附录:Oracle XE快速安装
  10. Catalan number卡特兰数