首页 > 其他分享 >统一校验

统一校验

时间:2022-09-03 11:22:13浏览次数:71  
标签:return String 校验 private 为空 message public 统一

此文代码托管地址: https://gitee.com/ZomiCC/code/tree/master/validate

我们平时都会碰到很多通用校验的场景:比如字段非空校验、字段长度校验等等。如下所示:

  • @Null:被注释的元素必须为null
  • @NotNull:被注释的元素不能为null
  • @AssertTrue:该字段只能为true
  • @AssertFalse:该字段的值只能为false
  • @Min(value):被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value):被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(“value”):被注释的元素必须是一个数字,验证小数的最小值
  • @DecimalMax(“value”):被注释的元素必须是一个数字,验证小数的最大值
  • @Size(max,min):查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等
  • @Past:被注释的元素必须是一个过去的日期
  • @Future:被注释的元素必须是一个将来的日期
  • @Pattern(regexp = “[abc]”):被注释的元素必须符合指定的正则表达式。
  • @Email:被注释的元素必须是电子邮件地址
  • @Length(max=5,min=1,message=“长度在1~5”):检查所属的字段的长度是否在min和max之间,只能用于字符串
  • @NotEmpty:被注释的字符串必须非空
  • @Range:被注释的元素必须在合适的范围内
  • @NotBlank:不能为空,检查时会将空格忽略
  • @NotEmpty:不能为空,这里的空是指空字符串
    具体是如何实现的呢,话不多说,直接看使用方式。

两种校验方式

一、@Validated + BindingResult controller校验

请求实体与BindingResult一一对应。
依赖的注解:

展开
        <!-- valid校验 -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <!-- 想要BindResult生效,这个依赖一定要有 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
实体类:
点击查看代码
@Data
@ToString
public class ReqDTO {
    @NotBlank(message = "param1不能为空")
    private String param1;
    @NotBlank(message = "param2不能为空")
    private String param2;
    @NotBlank(message = "param3不能为空")
    private String param3;
}
controller:
点击查看代码
    @PostMapping("/param1")
    public String param1(@Validated @RequestBody ReqDTO reqDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            assert fieldError != null;
            return fieldError.getDefaultMessage();
        }
        return "success";
    }
验证效果: 请求

响应

二、自定义Validator校验工具类

不局限于controller层,在任何地方都可以使用。
工具类:

点击查看代码
package com.example.validate.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Component
public class ParamCheckUtil {
    private static Validator validator;
    @Autowired
    private Validator injectValidator;

    @PostConstruct
    public void preInit() {
        validator = injectValidator;
    }

    public static <T> String checkByGroupsGetOneMessage(T t, Class<?>... groups) {
        if (t == null) {
            return null;
        }
        Set<ConstraintViolation<T>> validate = validator.validate(t, groups);
        if (validate.size() == 0) {
            return null;
        }
        return validate.stream().findFirst().get().getMessage();
    }

    public static <T> String checkByGroupsGetAllMessage(T t, Class<?>... groups) {
        if (t == null) {
            return null;
        }
        Set<ConstraintViolation<T>> validate = validator.validate(t, groups);
        if (validate.size() == 0) {
            return null;
        }
        List<String> msgList = new ArrayList<>();
        validate.forEach(cv -> msgList.add(cv.getMessage()));
        return String.join(";", msgList);
    }
}

应用举例:
点击查看代码
    @PostMapping("/param2")
    public String param2(@RequestBody ReqDTO reqDTO) {
        String message = ParamCheckUtil.checkByGroupsGetAllMessage(reqDTO);
        if (message != null) {
            return message;
        }
        return "success";
    }

其他扩展校验

一、分组校验

当一个实体类应用于多个场景的请求入参时,对入参要求又不一样,我们没必要每次都新建一个冗余的实体类。那怎么办呢,可以给校验属性添加上分组。默认分组是Default。
实体类:

点击查看代码
@Data
@ToString
public class GroupReqDTO {
    @NotBlank(message = "param1不能为空")
    private String param1;
    @NotBlank(message = "param2不能为空", groups = A.class)
    private String param2;
    @NotBlank(message = "param3不能为空", groups = B.class)
    private String param3;

    public interface A {}
    public interface B {}
}
controller:
点击查看代码
    @PostMapping("/param4")
    public String param4(@Validated({GroupReqDTO.A.class}) @RequestBody GroupReqDTO reqDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            assert fieldError != null;
            return fieldError.getDefaultMessage();
        }
        return "success";
    }

二、嵌套校验

当存在嵌套引用对象时,可以使用嵌套校验。嵌套类型需要使用@Valid注解标识。
实体类:

点击查看代码
@Data
public class NestedReqDTO {
    @NotBlank(message = "param1不能为空")
    private String param1;
    @NotBlank(message = "param2不能为空")
    private String param2;
    @NotBlank(message = "param3不能为空")
    private String param3;
    @Valid
    @NotNull(message = "param4不能为空")
    private OtherEntity param4;

    @Data
    class OtherEntity {
        @NotBlank(message = "属性1不能为空")
        private String property1;
    }
}
controller:
点击查看代码
    @PostMapping("/param5")
    public String param5(@Validated @RequestBody NestedReqDTO reqDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            assert fieldError != null;
            return fieldError.getDefaultMessage();
        }
        return "success";
    }

三、复杂关联校验

借助DefaultGroupSequenceProvider,可以实现属性间依赖关系的复杂校验。具体实现参考如下代码:
实体类:

点击查看代码
@Data
@ToString
@GroupSequenceProvider(MyGroupSequenceProvider.class)
public class MutiReqDTO {
    @NotBlank(message = "param1不能为空")
    private String param1;
    @NotBlank(message = "param2不能为空")
    private String param2;
    @NotBlank(message = "当param2为1时,param3不能为空", groups = Param2.class)
    private String param3;

    public interface Param2 {}
}

分组配置器:

点击查看代码
public class MyGroupSequenceProvider implements DefaultGroupSequenceProvider<MutiReqDTO> {
    @Override
    public List<Class<?>> getValidationGroups(MutiReqDTO mutiReqDTO) {
        List<Class<?>> classes = new ArrayList<>();
        classes.add(MutiReqDTO.class);
        if (mutiReqDTO == null) {
            return classes;
        }
        // 如果param2参数为“1”,则需要校验param3
        if ("1".equals(mutiReqDTO.getParam2())) {
            classes.add(MutiReqDTO.Param2.class);
        }
        return classes;
    }
}

controller测试:

点击查看代码
    @PostMapping("/param3")
    public String param3(@RequestBody MutiReqDTO reqDTO) {
        String message = ParamCheckUtil.checkByGroupsGetAllMessage(reqDTO);
        if (message != null) {
            return message;
        }
        return "success";
    }

验证效果:

标签:return,String,校验,private,为空,message,public,统一
From: https://www.cnblogs.com/zomicc/p/16652157.html

相关文章