ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

统一校验

2022-09-03 11:33:36  阅读:198  来源: 互联网

标签: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,统一
来源: https://www.cnblogs.com/zomicc/p/16652157.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有