@Valid和@Validated

@Valid和@Validated

实际开发中,往往用户的输入是不可信的,不管是GRPC还是前端接口, 都需要对参数进行校验。

  1. 对数据本身的校验

                比如:正则校验、非空校验、取值范围、指定的枚举等

  1. 数据校验

                比如:数据唯一性,业务上的限制等

@Valid和@Validated区别

        @Valid和@Validated是用于Spring框架中进行数据校验的注解。

从原码分析:

1.来源

  • @Validated:Spring框架的注解,JSR-303的javax.validation的变体。设计用于方便使用Spring的JSR-303的支持,但不是JSR-303特有的。
  • @Valid:Java EE提供的标准注解,它是JSR 303规范的一部分,主要用于Hibernate Validation等场景。

2.注解位置

  • @Validated:用在类、方法和方法参数
  • @Valid:用在方法、构造函数、方法参数和成员属性(字段)

3.分组验证

  • @Validated:支持
  • @Valid:不支持

4.嵌套验证

  • @Validated:不支持
  • @Valid:支持

示例

1.分组验证

        分组校验是为了在不同场景下对成员属性进行灵活校验。一般在新增/编辑时, 会使用同一个dto作为入参。那么在两个场景下,id的校验就不同了。

1. 在dto中新增接口作为分组, 字段添加分组注解

package com.donico.demo.domain.dto;

import lombok.Data;
import lombok.experimental.Accessors;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;

@Data
@Accessors(chain = true)
public class UserDto {

    public interface AddGroup {
    }

    public interface EditGroup {
    }

    @Min(value = 1, message = "不合法", groups = {EditGroup.class})
    private Long id;

    /**
     * 用户名
     */
    @NotBlank(message = "不能为空")
    private String username;

    /**
     * 密码
     */
    @NotBlank(message = "不能为空")
    private String password;
}

2.controller增加参数注解, 指定启用分组

package com.donico.demo.controller;

import com.donico.demo.domain.dto.UserDto;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/demo")
public class DemoController {
    /**
     * 添加用户
     */
    @PostMapping("/user-add")
    public void userAdd(@RequestBody() @Validated UserDto userDto) {
        // todo
    }

    /**
     * 编辑用户
     */
    @PostMapping("/user-edit")
    public void userEdit(@RequestBody() @Validated({UserDto.EditGroup.class}) UserDto userDto) {
        // todo
    }
}

 在控制器中的方法指定了校验分组,DTO中标注了校验注解的属性,如果未指定分组则针对该方法,校验不会生效。

未显示指定groups的字段,默认归于javax.validation.groups包下的Default.class(默认组)

@Validated的value不指定组时,只校验Default组的字段

@Validated的value指定组时,只校验属于指定组的字段,属于Default组的字段不会被校验

如现在的示例, userEdit想指定组和默认组都被校验,有两种方式:

1. @Validated的value中加入默认组,如下:

import javax.validation.groups.Default;

@PostMapping("/user-edit")
public void userEdit(@RequestBody() @Validated({UserDto.AddGroup.class, Default.class}) UserDto userDto) {
    // todo
}

2.EditGroup接口继承Default接口,如下:

public class UserDto {

    public interface AddGroup {
    }

    public interface EditGroup extends Default {
    }
}

2.嵌套验证

        嵌套校验(Nested Validation) 指的是在验证Bean对象时,需要校验的属性是一个Bean对象, 而这个子对象也有需要校验的属性。

示例:

UserDto的team属性是一个对象

package com.donico.demo.domain.dto;

import lombok.Data;
import lombok.experimental.Accessors;

import javax.validation.Valid;

@Data
@Accessors(chain = true)
public class UserDto {

    @Valid
    private TeamDto team;
}

TeamDto

package com.donico.demo.domain.dto;

import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
public class TeamDto {
    /**
     * 团队名称
     */
    @NotBlank(message = "不能为空")
    private String teamName;

    /**
     * 加入时间
     */
    @NotNull(message = "不能为空")
    private Long joinTime;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值