springboot情操陶冶-web配置(七)

 参数校验通常是OpenApi必做的操作,其会对不合法的输入做统一的校验以防止恶意的请求。本文则对参数校验这方面作下简单的分析

spring.factories

读者应该对此文件加以深刻的印象,很多springboot整合第三方插件的方式均是从此配置文件去读取的,本文关注下检验方面的东西。在相应的文件搜索validation关键字,最终定位至ValidationAutoConfiguration类,笔者这就针对此类作主要的分析

ValidationAutoConfiguration

优先看下其头上的注解

@Configuration @ConditionalOnClass(ExecutableValidator.class) @ConditionalOnResource(resources = "classpath:META-INF/services/javax.validation.spi.ValidationProvider") @Import(PrimaryDefaultValidatorPostProcessor.class)

使此类成功被注册的条件有两个,第一是当前环境下存在ExecutableValidator类,第二是当前类环境存在META-INF/services/javax.validation.spi.ValidationProvider文件。
通过查看maven依赖得知,其实springboot在引入starter-web板块便引入了hibernate-validator包,此包便满足了上述的两个要求。
笔者发现其也引入了PrimaryDefaultValidatorPostProcessor类,主要是判断当前的bean工厂是否已经包含了LocalValidatorFactoryBeanValidator对象,不影响大局。即使没有配置,下述的代码也是会注册的

    @Bean     @Role(BeanDefinition.ROLE_INFRASTRUCTURE)     @ConditionalOnMissingBean(Validator.class)     public static LocalValidatorFactoryBean defaultValidator() {         LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();         MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory();         factoryBean.setMessageInterpolator(interpolatorFactory.getObject());         return factoryBean;     }      @Bean     @ConditionalOnMissingBean     public static MethodValidationPostProcessor methodValidationPostProcessor(             Environment environment, @Lazy Validator validator) {         MethodValidationPostProcessor processor = new MethodValidationPostProcessor();         boolean proxyTargetClass = environment                 .getProperty("spring.aop.proxy-target-class", Boolean.class, true);         processor.setProxyTargetClass(proxyTargetClass);         processor.setValidator(validator);         return processor;     }

通过查阅代码得知,使用注解式的校验方式是通过添加@Validated注解来实现的,但是其作用于参数上还是类上是有不同的操作逻辑的。笔者将之区分开,方便后续查阅。先附上@Validated注解源码

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Validated {      /**      * Specify one or more validation groups to apply to the validation step      * kicked off by this annotation.      * <p>JSR-303 defines validation groups as custom annotations which an application declares      * for the sole purpose of using them as type-safe group arguments, as implemented in      * {@link org.springframework.validation.beanvalidation.SpringValidatorAdapter}.      * <p>Other {@link org.springframework.validation.SmartValidator} implementations may      * support class arguments in other ways as well.      */     Class<?>[] value() default {};  }

类级别的校验

@Validated作用于类上,其相关的处理逻辑便是由MethodValidationPostProcessor来实现的,笔者稍微看下关键源码方法afterPropertiesSet()

    @Override     public void afterPropertiesSet() {         // 查找对应的类以及祖先类上是否含有@Validated注解         Pointcut pointcut = new AnnotationMatchingPointcut(this.validatedAnnotationType, true);         // 创建MethodValidationInterceptor处理类来处理具体的逻辑         this.advisor = new DefaultPointcutAdvisor(pointcut, createMethodValidationAdvice(this.validator));     }

上述的配置表明只要某个类上使用了@Validated注解,其相应的方法就会被校验相关的参数。笔者紧接着看下MethodValidationInterceptor#invoke()方法

    @Over
                    
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信