springboot~@Valid注解对嵌套类型的校验

@Valid注解可以实现数据的验证,你可以定义实体,在实体的属性上添加校验规则,而在API接收数据时添加@valid关键字,这时你的实体将会开启一个校验的功能,具体的代码如下,是最基本的应用:

实体:

复制代码
public class DepartmentDto {

  @ApiModelProperty("id")
  private String id;

  @ApiModelProperty("上级Id")
  private String parentId;

  @ApiModelProperty("编号")
  @NotBlank(message = "部门编号不能为空。")
  private String code;

  @ApiModelProperty("名称")
  @NotBlank(message = "部门名称不能为空。")
  private String name;
 @ApiModelProperty("员工集合")
@Builder.Default
private List<Employee> employees = new ArrayList<>();
}
复制代码

Restful接口:

复制代码
  @PostMapping()
  public Response<ClientAccount> initialAccount(
      @ApiParam("客户编号") @PathVariable String code,
      @ApiParam("账期") @PathVariable YearMonth accountPeriod,
      @ApiParam("请求体") @Valid @RequestBody Request<DepartmentDto> request) {
    ClientAccount result = clientAccountService.initialAccount(
        code,
        accountPeriod,
        request.getOperator(),
        request.getBody());{}
复制代码

上面代码中,我们为请求体Request<DepartmentDto>添加了校验,在测试时,如果你的DepartmnetDto.name为空字符时,当出现400的异常,丽时异常消息是『部门名称不能为空』,这对于我们来说是没有问题的,也是符合我们要求的,下面看另一个场景。

需要验证的实体是另一个实休的属性

这种方式我们也需要会看到,一个大对象,如被封装的其它小对象组成,比如部门下面有员工,这时如果需要验证员工的有效性,需要如何实现呢?如果我们不修改源代码,执行结果是否定的,它并不会校验员工这个对象,而只针对第一层对象的属性

我们将实体的员工属性添加上@Valid即可实现对这个属性的校验

复制代码
public class DepartmentDto {

  @ApiModelProperty("id")
  private String id;

  @ApiModelProperty("上级Id")
  private String parentId;

  @ApiModelProperty("编号")
  @NotBlank(message = "部门编号不能为空。")
  private String code;

  @ApiModelProperty("名称")
  @NotBlank(message = "部门名称不能为空。")
  private String name;

 @Valid
 @ApiModelProperty("员工集合")
 @Builder.Default
 private List<Employee> employees = new ArrayList<>();
}
复制代码

下面看一下验证结果,我们的400错误就可以在单元测试下面正常输出了!

复制代码
 @Test
  public void initialAccount_employee_name_empty() {
    List<Employee> employees = new ArrayList<>();
    employees.add(Employee.builder()
        .name("")
        .email("zzl@sina.com")
        .idNumber("110111198203182012")
        .build());
    List<DepartmentDto> departments = new ArrayList<>();
    departments.add(DepartmentDto.builder()
        .name("部门")
        .description("技术部")
        .salaryType(SalaryType.ResearchAndDevelopmentCosts)
        .employees(employees)
        .build());
    ClientAccountDto clientAccountDto = ClientAccountDto.builder()
        .name("客户")
        .departments(departments)
        .build();
    Request<ClientAccountDto> request = buildRequest(clientAccountDto);
    api.post()
        .uri("/v1/12345/2018-03")
        .body(BodyInserters.fromObject(request))
        .exchange()
        .expectStatus().isEqualTo(400)
        .expectBody()
        .jsonPath("$.errors[0].message").isEqualTo("姓名不能为空");
  }
复制代码

结果如下,测试通过

如果是测试它是IsOk的话,由于用户名为空,所以会出现错误提示

 api.post()
        .uri("/v1/12345/2018-03")
        .body(BodyInserters.fromObject(request))
        .exchange()
        .expectStatus().isOk();

可以看一下结果的提示信息

感谢各位阅读!

今天主要介绍 @Valid在项目中的使用!

 

posted @   张占岭  阅读(17956)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
历史上的今天:
2017-05-25 EF架构~TransactionScope与SaveChanges的关系
2017-05-25 LindAgile.Modules模块化的设计
2012-05-25 Linq To Sql模式中自动生成T-SQL增删改操作系列~PropertyChanged事件实现在子类中记录属性的变化,在基类中进行统一处理
2011-05-25 说说面向对象的故事,主人是人类!(二)
点击右上角即可分享
微信分享提示