@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不是JavaBean所以校验会失败,介绍三种解决办法

方法1:对List进行Wrapper

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

import lombok.Getter;

import lombok.Setter;

import javax.validation.Valid;

import java.util.ArrayList;

import java.util.List;

@Setter

@Getter

public class ListWrapper {

@Valid

private List list;

public ListWrapper() {
list = new ArrayList<>();
} public ListWrapper(List<E> list) {
this.list = 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 ValidList implements List {

@Valid
private List<E> list; public ValidList() {
this.list = new ArrayList<>();
} public ValidList(List<E> list) {
this.list = list;
} public List<E> getList() {
return list;
} public void setList(List<E> list) {
this.list = list;
} @Override
public int size() {
return list.size();
} @Override
public boolean isEmpty() {
return list.isEmpty();
} ...

}

对比方法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

本文由博客一文多发平台 OpenWrite 发布!

@Validated和@Valid校验参数、级联属性、List的更多相关文章

  1. @Validated和@Valid的区别?校验级联属性(内部类)

    每篇一句 NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术 相关阅读 [小家Java]深入了解数据校验:Java Bean Validation 2.0(JSR303.JSR349.JSR380) ...

  2. 参数验证 @Validated 和 @Valid 的区别

    来源:blog.csdn.net/qq_27680317/article/details/79970590 整编:Java技术栈(公众号ID:javastack) Spring Validation验 ...

  3. @Validated和@Valid区别:Spring validation验证框架对入参实体进行嵌套验证必须在相应属性(字段)加上@Valid而不是@Validated

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

  4. valid 校验方式

    校验参数方法:1.最简单的方式是,使用Java bean注解校验(如 @NotEmpty...)2.适合复杂点的自定义校验(推荐) 2.1 先定义一个校验接口: public interface Va ...

  5. 使用Spring Validation优雅地校验参数

    写得好的没我写得全,写得全的没我写得好 引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断? public String add(Use ...

  6. Spring 捕捉校验参数异常并统一处理

    使用 @Validated ,@Valid ,@NotBlank 之类的,请自行百度,本文着重与捕捉校验失败信息并封装返回出去 参考: https://mp.weixin.qq.com/s/EaZxY ...

  7. @Validated和@Valid区别

    注解地方 @Validated:可以用在类型.方法和方法参数上.但是不能用在成员属性(字段)上 @Valid:可以用在方法.构造函数.方法参数和成员属性(字段)上 两者是否能用于成员属性(字段)上直接 ...

  8. Hibernate 集合映射 一对多多对一 inverse属性 + cascade级联属性 多对多 一对一 关系映射

    1 . 集合映射 需求:购物商城,用户有多个地址. // javabean设计 // javabean设计 public class User { private int userId; privat ...

  9. 前端请求参数MD5加密校验,参数串解密

    首先引入MD5加密库:=>https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js; 步骤:=>1.请求前对参数进行字典升序排序,排 ...

随机推荐

  1. 解决mysql提示服务无法启动问题

    1.管理员权限打开命令,进入mysql下bin文件夹 删除根目录下data文件夹没有不用管,重新安装 2. ---------------------------------------------- ...

  2. Oracle之:查询锁表,删除锁表

    -- 查询当前哪个表被锁 select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo. ...

  3. hdu 6049 Sdjpx Is Happy

    题: OwO http://acm.hdu.edu.cn/showproblem.php?pid=6049 (2017 Multi-University Training Contest - Team ...

  4. 【winfrom-多语言】实现多语言切换:使用资源文件

    使用资源文件实现多语言切换. 1. 新建一个Form,名为FrmMain. 在界面添加一个MenuStrip和一个Button. 并设置好控件的文本和位置.(Language=(Default)) 2 ...

  5. removeProp(name)

    removeProp(name) 概述 用来删除由.prop()方法设置的属性集 随着一些内置属性的DOM元素或window对象,如果试图将删除该属性,浏览器可能会产生错误.jQuery第一次分配un ...

  6. 如何理解JS内的Truthy值和Falsy值

    跟据MDN的术语表解释如下: 在 JavaScript 中,Truthy (真值)指的是在 布尔值 上下文中转换后的值为真的值.所有值都是真值,除非它们被定义为 falsy (即除了 false,0, ...

  7. BZOJ 3782: 上学路 Lucas+ExCRT+容斥+dp

    其实呢,扩展中国剩余定理还有一种理解方式:就是你有一坨东西,形如:$A[i]\equiv B[i](mod$ $P[i])$. 对于这个东西,你可以这么思考:如果最后能求出一个解,那么这个解的增量一定 ...

  8. mongodb Sort排序能够支持的最大内存限制为32M Plan executor error during find: FAILURE

    1.一个比较老的游戏服维护,关服维护后启动时报错 2.看到关于mongodb的报错,于是去查一下mongodb的日志 Plan executor error during find: FAILURE, ...

  9. Java web 公文流转系统 完成结果

    河北金力集团公文流转系统 1.项目需求: 河北金力集团是我省机械加工的龙头企业,主要从事矿山机械制造及各种机械零部件加工.企业有3个厂区,主厂区位于省高新技术开发区,3个分厂分别在保定.邢台和唐山.为 ...

  10. [CSP-S模拟测试]:装饰(数学)

    题目传送门(内部题147) 输入格式 每个测试点第一行一个正整数$T$,表示该测试点内的数据组数. 接下来$T$行,每行三个非负整数$a,b,c$,含义如题目中所示. 输出格式 对每组数据输出一行一个 ...