Springboot中的Validation参数校验详解

 更新时间:2023年10月08日 09:47:35   作者:__如风__  
这篇文章主要介绍了Springboot中的Validation参数校验详解,Springboot参数校验是一种常用的验证机制,在传递参数时进行校验,以确保参数的有效性和正确性,该机制可以帮助开发者在代码实现前就避免一些常见的错误,需要的朋友可以参考下

Springboot 参数校验

参考文档

Springboot项目中,引入依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

基本的使用网上有很多教程,就不介绍了。

关于使用

  • 校验@RequestParam、@PathVariable等,只需在controller类上加@Validated注解
  • 校验JavaBean,在controlle上注解@Validated且在参数前加@Validated

下面以该类为例

@Data
public class TestParam {
    /**
     * insert时要求为null
     */
    @Null(groups = Insert.class)
    /**
     * update时要求不为空
     */
    @NotEmpty(groups = Update.class)
    private List<@NotNull Long> ids;
    @EnumValue(value = Gender.class)
    private String gender;
    @Valid
    private List<@NotNull Pet> pets;
    /**
     * 默认分组为default,若不继承
     * Validated指定分组后,非指定分组将失效
     */
    public interface Insert extends Default {
    }
    public interface Update extends Default {
    }
}
@Data
public class Pet {
    @Size(min = 1, max = 5)
    private String name;
}

分组校验

分组校验有点类似Jackson序列化的JsonView,不同的情况下采取不同的策略,例如,注册时账户名必须在数据库中唯一,而登录时账户必须在数据库中存在,这个时候就需要为校验设置分组了。 情况一

@PostMapping("/insert")
public TestParam insert(@RequestBody @Validated(TestParam.Insert.class) TestParam param) {
	return param;
}

insert.png

情况二

@PostMapping("/update")
public TestParam update(@RequestBody @Validated(TestParam.Update.class) TestParam param) {
        return param;
}

update.png

自定义校验

如下为自定义枚举值校验,用于解决属性定义不是enum类型,但想约束其值为枚举类型,例如上面的gender,假如定义为Gender,那么默认只能MALE或者FEMALE,想要男、女也通过校验,可以使用该注解

@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValidator.class})
public @interface EnumValue {
    String message() default "错误的枚举值";
    EnumValidateBy by() default EnumValidateBy.TOSTRING;
    Class<? extends Enum<?>> targetEnum();
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
public enum EnumValidateBy {
    /**
     * 使用枚举类的哪个值校验
     * 如MAEL("男"), FEMALE("女")
     * NAME 值必须为MAEL或者FEMALE
     * TOSTRING 重写toString方法返回男或者女, 值必须为男或者女
     * BOTH 以上值均可
     */
    BOTH, NAME, TOSTRING
}

实现ConstraintValidator接口校验

public class EnumValidator implements ConstraintValidator<EnumValue, String> {
    private final Set<String> set = new HashSet<>(8);
    @Override
    public void initialize(EnumValue constraintAnnotation) {
        Class<? extends Enum<?>> enumCls = constraintAnnotation.targetEnum();
        EnumValidateBy by = constraintAnnotation.by();
        Enum<?>[] constants = enumCls.getEnumConstants();
        if (by == EnumValidateBy.NAME) {
            set.addAll(Arrays.stream(constants).map(Enum::name).collect(Collectors.toSet()));
        } else if (by == EnumValidateBy.TOSTRING) {
            set.addAll(Arrays.stream(constants).map(Enum::toString).collect(Collectors.toSet()));
        } else {
            set.addAll(Arrays.stream(constants).map(Enum::name).collect(Collectors.toSet()));
            set.addAll(Arrays.stream(constants).map(Enum::toString).collect(Collectors.toSet()));
        }
    }
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return set.contains(value);
    }
}

枚举.png

null不在set中,校验不通过

集合元素校验

基本类型

直接在泛型参数上加上需要的注解即可

泛型基本类型.png

JavaBean类型

  • 如仅对整个JavaBean进行校验,例如@NotNull注解,直接将注解写在泛型参数即可
  • 如需对集合中每个JavaBean的属性进行校验,还需加上@Valid注解,如上面的pets

泛型JavaBean.png

快速失败模式

hibernate官网的配置如下:

ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
        .configure()
        .addProperty( "hibernate.validator.fail_fast", "true" )
        .buildValidatorFactory();
Validator validator = validatorFactory.getValidator();

只要往容器中注入Validator对象就行了。 因为spring自动配置好了,但没有开启快速失败模式,最后,参照Springboot自动配置的ValidationAutoConfiguration,只添加了快速失败部分,其余未做改动。

@Configuration
public class ValidationConfig {
    @Bean
    public Validator validatorFactory(ApplicationContext context) {
        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean() {
            @Override
            protected void postProcessConfiguration(javax.validation.Configuration<?> configuration) {
                configuration.addProperty("hibernate.validator.fail_fast", "true");
            }
        };
        MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory(context);
        factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
        return factoryBean;
    }
}

总结

Springboot 参数校验是一种有效的验证机制,可以避免常见的错误,并提高程序的健壮性和稳定性。它的实现方式基于Java Bean验证框架,通过添加注解的方式,对属性值进行校验。开发者只需要在程序中加入相关注解即可完成参数的校验,从而提高了程序的开发效率和稳定性。

  • 在controller层使用
  • 分组时记得继承Default接口
  • 集合嵌套校验
  • 快速失败模式

到此这篇关于Springboot中的Validation参数校验详解的文章就介绍到这了,更多相关Validation参数校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java堆空间爆满导致宕机的问题分析及解决

    Java堆空间爆满导致宕机的问题分析及解决

    团队有一个服务,一直运行的好好的,突然访问异常了,先是请求超时,然后直接无法访问,本文将给大家介绍Java堆空间爆满导致宕机的问题分析及解决,需要的朋友可以参考下
    2024-02-02
  • 解析Java8 Stream原理

    解析Java8 Stream原理

    说起 Java 8,我们知道 Java 8 大改动之一就是增加函数式编程,而 Stream API 便是函数编程的主角,Stream API 是一种流式的处理数据风格,也就是将要处理的数据当作流,在管道中进行传输,并在管道中的每个节点对数据进行处理,如过滤、排序、转换等
    2021-06-06
  • java时间 java.util.Calendar深入分析

    java时间 java.util.Calendar深入分析

    这篇文章主要介绍了java时间 java.util.Calendar深入分析的相关资料,需要的朋友可以参考下
    2017-02-02
  • 图解Spring容器中实例化bean的四种方式

    图解Spring容器中实例化bean的四种方式

    这篇文章主要介绍了图解Spring容器中实例化bean的四种方式,传统应用程序可以通过new和反射方式进行实例化Bean,而Spring IOC容器则需要根据 Bean 定义里的配置元数据,使用反射机制来创建Bean,需要的朋友可以参考下
    2023-11-11
  • eclipse 安装lombok插件

    eclipse 安装lombok插件

    这篇文章主要介绍了eclipse 安装lombok插件的详细步骤,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07
  • mybatis写xml时数字类型千万别用 !=‘‘(不为空串)进行判断的示例详解

    mybatis写xml时数字类型千万别用 !=‘‘(不为空串)进行判断的示例详解

    这篇文章主要介绍了mybatis写xml时数字类型千万别用 !=‘‘(不为空串)进行判断的示例详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Java实现学生管理系统详解流程

    Java实现学生管理系统详解流程

    这篇文章主要为大家详细介绍了如何利用Java语言实现学生管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • Java利用POI读写Excel文件工具类

    Java利用POI读写Excel文件工具类

    这篇文章主要为大家详细介绍了Java利用POI读写Excel文件的工具类,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • SpringBoot远程访问redis服务器问题剖析

    SpringBoot远程访问redis服务器问题剖析

    使用了SpringBoot的项目,在远程连接Redis服务器时,会遇倒一些小问题,下面通过本文给大家全面解析SpringBoot远程访问redis服务器问题,需要的朋友参考下吧
    2017-04-04
  • MyBatis 动态拼接Sql字符串的问题

    MyBatis 动态拼接Sql字符串的问题

    MyBatis的动态SQL,解决了SQL字符串拼接的痛苦。下文分步骤给大家详细介绍了MyBatis 动态拼接Sql字符串的问题,非常不错,感兴趣的朋友一起看下吧
    2016-08-08

最新评论