SpringBoot 参数校验

valid 和validated

@Validation对@Valid进行了二次封装,在使用上并没有区别,但在分组、注解位置、嵌套验证等功能上有所不同,这里主要就这几种情况进行说明

在这里插入图片描述

嵌套属性校验

在嵌套对象上添加注解 valid,在请求对象前面添加注解 valid

@Data
public class User {
    @Min(value = 10,message = "年龄必须大于10岁")
    private Integer age;
}
@Data
public class UserClass {
    private String className;
    @Valid
    private User user;
}

@PostMapping("checkBodyMultilevelParam")
public String checkBodyMultilevelParam(@RequestBody @Valid UserClass userClass){
 return "ok";
}

校验get参数
在controller上加注解

@RestController
@RequestMapping("/paramTest")
@Validated
public class ParamTestController {
 @GetMapping("checkParam")
 public String checkParam(@RequestParam  @Max(value = 99, message = "不能大于99岁") Integer age) {
  return "ok";
 }

  @GetMapping("checkPath/{id}")
 public String checkPath(@PathVariable  @Pattern(regexp = "^[0-9]*$", message = "id参数值必须是正整数") String id)   {
  return "ok";
 }
}

参考链接:https://mp.weixin.qq.com/s/T_5KQEfbF4G-24-yLajJ4Q

校验post参数

添加用户时,不需要校验id是否为空,
修改用户时就需要校验id是否为空。

定义分组(分组也可以放到用户dto中)

public class ValidGroup {

    // 新增使用(配合spring的@Validated功能分组使用)
    public interface Insert{}

    // 更新使用(配合spring的@Validated功能分组使用)
    public interface Update{}

    // 删除使用(配合spring的@Validated功能分组使用)
    public interface Delete{}

    // 属性必须有这两个分组的才验证(配合spring的@Validated功能分组使用)
    public interface All{}
}

在实体类中将参数用分组进行标记


//只能引用Delete和Update分组的时候才能够进行生效.
@Min(value = 1,message = "ID不能小于1",groups = {ValidGroup.Delete.class,ValidGroup.Update.class})
private int id;

@NotBlank(message = "用户名不能为空",groups = {ValidGroup.Update.class,ValidGroup.Insert.class})
private String username;

@NotBlank(message = "密码不能为空",groups = {ValidGroup.Update.class,ValidGroup.Insert.class})
@Length(min = 6,max = 20,message = "密码长度在6-20之间")
private String password;

@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不合理")
private String email;

//一个参数分别放到了不同的分组中:默认分组和update分组
@NotBlank(message = "昵称不为空")
@Size(message = "昵称长度 [1-3] ", min = 1, max = 3,groups = ValidGroup.Update.class)
private String nickname;

使用分组:controller中@Validated指定需要的分组

//没有指定用哪个分组,只对提交过来的参数中的email和nickname进行校验
@RequestMapping("/saveUserInfo")
public UserInfo saveUserInfo(@Validated() UserInfo userInfo){
    return userInfo;
}

//使用了Update分组,所以回对Update分组中的id,username,password,nickname参数进行校验
@RequestMapping("/updateUserInfo")
public UserInfo updateUserInfo(@Validated({ValidGroup.Update.class}) UserInfo userInfo){
    return userInfo;
}

//使用了delete分组,所以回对delete分组中的id参数进行校验
@RequestMapping("/deleteUserInfo")
public UserInfo deleteUserInfo(@Validated({ValidGroup.Delete.class}) UserInfo userInfo){
    return userInfo;
}

组序列

默认情况下 不同级别的约束验证是无序的,但是在一些情况下,顺序验证却是很重要。
一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证

定义组序列:

@GroupSequence({Default.class, IGroupA.class, IGroupB.class})
public interface IGroup {
}

需要校验的Bean,分别定义IGroupA对age进行校验,IGroupB对className进行校验:

public class StudentBean implements Serializable{
    @Min(value = 18, message = "年龄不能小于18岁", groups = IGroupA.class)
    private Integer age;
    @notblank(message = "className不能为空",groups = IGroupB.class)
    private String className;

测试代码:

@RestController
public class CheckController {
    @PostMapping("stu")
    public String addStu(@Validated({IGroup.class}) @RequestBody StudentBean studentBean){
        return "add student success";
    }
}

如果age出错,那么对组序列在IGroupA后的IGroupB不进行校验,即例子中的className不进行校验

自定义校验器@AssertTrue

有时候,我们需要对多个字段进行复杂的逻辑校验,例如需要两个字段相互比较或执行自定义的校验逻辑。
在这种情况下,我们可以使用自定义的校验器(Validator)来实现。
@AssertTrue注解来标记自定义的校验方法 isEndDateAfterStartDate()。该方法检查 endDate是否晚于 startDate,如果校验失败,将返回指定的错误提示信息。

publicclassUserDto{
@NotNull(message = "起始日期不能为空")
private LocalDate startDate;

@NotNull(message = "结束日期不能为空")
private LocalDate endDate;

@AssertTrue(message = "结束日期必须晚于起始日期")
private boolean isEndDateAfterStartDate(){
if (startDate == null || endDate == null) {
returntrue;
        }
return endDate.isAfter(startDate);
    }
}

自定义校验注解

自定义注解:定义一个名为 Email的注解,并指定了它的校验器 EmailValidator。

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EmailValidator.class})
public @interface Email {
String message()default "邮箱格式不正确";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

自定义校验器

public class EmailValidator implements ConstraintValidator<Email, String> {
@Override
public void initialize(Email constraintAnnotation){
    }

@Override
public boolean isValid(String value, ConstraintValidatorContext context){
// 在这里编写自定义的校验逻辑
// 返回true表示校验通过,返回false表示校验失败
    }
}

使用自定义注解

publicclassUserDto{
@Email
private String email;
}

关于分组抛出的异常处理

参考链接:
https://mp.weixin.qq.com/s/x6_mNdtb6i2XmTiyz4kXrg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值