关于Spring Validation的简单记录

  平时在使用SpringMVC的时候通常会对前端请求的参数进行验证,在不知道Validation前通常会在代码中直接验证参数合法性,这样做虽然也可以完成验证但,对业务代码的侵入性太强不利于代码维护,其实Spring 基于JSR 303(不了解JSR可以百度一下)规范提供能验证提供了参数验证功能,在这里记录一下Spring6中使用Validation验证参数。

1.新建Maven项目引入依赖(Spring略)

        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>8.0.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>jakarta.el</artifactId>
            <version>5.0.0-M1</version>
        </dependency>
1.1分析一下依赖关系,有助于理解Validation实现方式

在这里插入图片描述
  在jakata中规定了一个JSR 303的java规范,用于规范化Validation实现,jakata本身并没有去实现这个规范,Hibernate实现这个规范为我们提供了ValidatorImpl,从图中可以看出jakata通过Java SPI机制(spring boot的自动配置也使用了类似的机制,SPI是Java自身提供的一种更原始的插件式服务提供方式)加载了Hibernate中Validator的实现,并且提供能ValidationFactory,在Spring 中也定义了一个Validator接口,为了适配JSR 303的Validator使用,Spring它提供了ValidatorAdapter,基于ValidatorAdapter我们可以轻松使用第三方Validator,当然我们也可以直接实现Spring的Validator,向Spring容器中注入Bean进行使用。

2.使用Spring Validation完成验证(简单示例)

2.1 自定义验证(此处只做演示,代码可以抽象为一个自定义validator)
@Configuration
public class ValidationConfig {

//    @Bean
//    public MethodValidationPostProcessor methodValidationPostProcessor() {
//        return new MethodValidationPostProcessor();
//    }

    @Bean
    public CustomValidatorBean customValidatorBean() {
        CustomValidatorBean customValidatorBean = new CustomValidatorBean();
        customValidatorBean.setValidatorFactory(Validation.buildDefaultValidatorFactory());
        return customValidatorBean;
    }

}
@Data
public class User{

    @NotBlank
    private String name;

    @Max(100)
    private Integer age;

}
@Service
public class ValidationTest {

    @Autowired
    CustomValidatorBean customValidatorBean;

    public void userValidation(@Valid User user) throws BindException {
        BindException bindException = new BindException(user, "user");
        // 使用 ValidationUtils 调用验证
        ValidationUtils.invokeValidator(customValidatorBean, user, bindException);
        System.out.println(bindException.getErrorCount());
        if(bindException.getErrorCount()>0){
            throw bindException;
        }
    }
}
public class Main {

    public static void main(String[] args) throws BindException {

        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext("com.cobin");

        ValidationTest bean = context.getBean(ValidationTest.class);
        User user = new User(); // name,age都为空会出现异常
        bean.userValidation(user);
    }
}

执行结果:
在这里插入图片描述

2.2 @Validated注解验证
@Configuration
public class ValidationConfig {
    
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        // 方法验证增强器
        return new MethodValidationPostProcessor();
    }

//    @Bean
//    public CustomValidatorBean customValidatorBean() {
//        CustomValidatorBean customValidatorBean = new CustomValidatorBean();
//        customValidatorBean.setValidatorFactory(Validation.buildDefaultValidatorFactory());
//        return customValidatorBean;
//    }

}

  在需要提供验证的类上添加@Validated注解(也可以自定义注解,在Config中设置自定义的注解),需要验证的方法参数上添加@Valid,在Bean注入到容器中时,Spring会生成代理类实现验证逻辑。

@Service
@Validated
public class ValidationTest {

    @Autowired
    CustomValidatorBean customValidatorBean;

    public void userValidation(@Valid User user) throws BindException {
        BindException bindException = new BindException(user, "user");
        // 使用 ValidationUtils 调用验证
        ValidationUtils.invokeValidator(customValidatorBean, user, bindException);
        System.out.println(bindException.getErrorCount());
        if(bindException.getErrorCount()>0){
            throw bindException;
        }
    }
}

主函数同2.1
执行结果:
在这里插入图片描述
  在SpringMVC 控制层中为我们提供了更简单的使用方式,理解Spring 的Validation后我们可以不限于SpringMVC中使用,可以在Spring的环境中可以更灵活的使用Validation的校验功能,例如本人之前遇到过的RPC调用过程中的参数校验,由于但是没有充分了解这个细节,导致出现过一些问题,在Spring环境中使用Validation可以为我们减轻很多参数验证上的麻烦,不过上述也只是Validation使用方式的最简单部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值