简介
说明
本文介绍如何使用validator进行手动校验。
validator可以进行自动校验,也可以进行手动校验,结果是一模一样的。自动校验见下方“自动校验”。
自动校验
自动校验的方法:项目中我们经常在请求类上加@NotNull,@NotBlank之类的注解,结合@Valid或者@Validated,即可自动对字段进行校验。自动校验的用法见:SpringBoot-@Valid与@Validated的区别 – 自学精灵
效果展示1:基础功能
代码
Controller
package com.knife.example.business.user.controller; import com.knife.example.business.user.bo.UserAddBO; import com.knife.example.business.user.dto.UserDTO; import com.knife.example.business.user.vo.UserVO; import com.knife.example.common.group.ValidGroup; import com.knife.example.common.util.ValidateUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; @Api(tags = "手动校验") @RequestMapping("manualValidate") @RestController public class ManualController { @ApiOperation("添加") @PostMapping("/add") public UserVO add(@RequestBody UserAddBO userAddBO) { UserDTO userDTO = new UserDTO(); BeanUtils.copyProperties(userAddBO, userDTO); // ValidUtil.validate(userDTO); ValidateUtil.validate(userDTO, ValidGroup.Add.class); // 将数据写到数据库 userDTO.setId(1L); userDTO.setCreateTime(LocalDateTime.now()); userDTO.setUpdateTime(LocalDateTime.now()); UserVO userVO = new UserVO(); BeanUtils.copyProperties(userDTO, userVO); return userVO; } }
BO
package com.knife.example.business.user.bo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel("添加用户") public class UserAddBO { @ApiModelProperty(value = "用户名", required = true) private String userName; @ApiModelProperty("昵称") private String nickName; @ApiModelProperty("邮箱") private String email; }
DTO
package com.knife.example.business.user.dto; import com.knife.example.common.group.ValidGroup; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null; import java.time.LocalDateTime; @Data public class UserDTO { /** * 用户id */ @Null(groups = ValidGroup.Add.class, message = "用户id必须为空") @NotNull(groups = ValidGroup.Edit.class, message = "用户id不能为空") private Long id; /** * 用户名 */ @NotBlank(groups = {ValidGroup.Add.class, ValidGroup.Edit.class}, message = "用户名不能为空") private String userName; /** * 昵称 */ private String nickName; /** * 邮箱 */ @NotBlank(message = "邮箱不能为空") private String email; /** * 创建时间 */ @Null(message = "创建时间必须为空") private LocalDateTime createTime; /** * 修改时间 */ @NotNull(message = "更新时间不能为空") private LocalDateTime updateTime; }
测试
测试添加接口缺少字段的场景
访问:
请求体为:
{ "email": "", "nickName": "", "userName": "" }
效果展示2:数据嵌套
代码
Controller
package com.knife.example.business.nested.controller; import com.knife.example.business.nested.bo.UserBO; import com.knife.example.business.nested.group.IGroupA; import com.knife.example.business.nested.group.IGroupAll; import com.knife.example.business.nested.group.IGroupB; import com.knife.example.common.util.ValidateUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Api(tags = "手动校验嵌套") @RestController @RequestMapping("nested") public class ValidatedWithGroupController { @ApiOperation("不使用组") @PostMapping("withoutGroup") public UserBO withoutGroup(@RequestBody UserBO userBO) { ValidateUtil.validate(userBO); return userBO; } @ApiOperation("使用组:GroupA") @PostMapping("groupA") public UserBO groupA(@RequestBody UserBO userBO) { ValidateUtil.validate(userBO, IGroupA.class); return userBO; } @ApiOperation("使用组:GroupB") @PostMapping("groupB") public UserBO groupB(@RequestBody UserBO userBO) { ValidateUtil.validate(userBO, IGroupB.class); return userBO; } @ApiOperation("使用组:GroupAll") @PostMapping("groupAll") public UserBO groupAll(@Validated({IGroupAll.class}) @RequestBody UserBO userBO) { ValidateUtil.validate(userBO, IGroupAll.class); return userBO; } }
BO
package com.knife.example.business.nested.bo; import com.knife.example.business.nested.group.IGroupA; import com.knife.example.business.nested.group.IGroupB; import lombok.Data; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; @Data public class UserBO { @NotBlank(message = "名字不能为空") private String name; @NotNull(message = "年龄不能为空", groups = {IGroupA.class}) private Integer age; @NotEmpty(message = "密码不能为空", groups = {IGroupB.class}) private String password; @NotEmpty(message = "分数不能为空", groups = {IGroupA.class, IGroupB.class}) private List<Integer> scoreArray; @Valid @NotNull(message = "账户不能为空") private AccountBO accountBO; @Valid @NotEmpty(message = "账户列表不能为空") private List<AccountBO> accountBOList; }
package com.knife.example.business.nested.bo; import com.knife.example.business.nested.group.IGroupA; import com.knife.example.business.nested.group.IGroupB; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @Data public class AccountBO { @NotNull(message = "账户ID不能为空", groups = {IGroupA.class} ) private Long id; @NotBlank(message = "电话号码不能为空") private String phoneNumber; private String[] emails; }
测试
测试1:缺参数测试不分组
可以发现:校验生效了(列表形式的包装类字段也生效了)。这样不加Group时,只校验没有Group的字段。(跟自动校验的结果一样)。
请求体:
{ "accountBO": { "emails": [], "id": 2, "phoneNumber": "" }, "accountBOList": [ { "emails": [], "id": null, "phoneNumber": "" } ], "age": 0, "name": "", "password": "", "scoreArray": [] }
测试2:缺字段测试GroupA
可以发现:GroupA的校验生效了(列表形式的包装类字段也生效了)。跟使用注解自动校验的结果一模一样,见:这里
请求体:
{ "accountBO": { "emails": [], "id": 2, "phoneNumber": "" }, "accountBOList": [ { "emails": [], "id": null, "phoneNumber": "" } ], "age": 0, "name": "", "password": "", "scoreArray": [] }
测试3:缺字段测试GroupAll
可以发现:可以看到:走的校验逻辑是除了IGroupA和IGroupB注解的字段的逻辑。
核心代码
此内容仅限VIP查看,请先登录
请先
!