2020-09-14

背景

使用注解参数校验,可避免业务代码中无休止的参数校验判断,在分层的方面来说,参数校验都是在Controller层完成的,那么Spring MVC中,可直接添加Validate相关的参数校验注解,即可快速完成而无需其它额外的配置,但是如果想在Service层的接口中添加参数校验,则需要额外的配置,否则,注解添加后是无效的。

实现

我们了解到参数校验是基于Validator来做的,首先需要添加hibernate-validator和validation-api依赖,由于spring-boot-starter-web依赖hibernate-validator,而hibernate-validate又依赖validation-api,所以项目中只需要添加spring-boot-starter-web依赖即可,如下:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<version>2.1.1.RELEASE</version>
</dependency>

此时,需要在切面中通过Validator完成接口调用时的参数校验,实现如下:

@Aspect@Componentpublic class ParamsCheckAspect {        private static Validator validator;    static {        validator = Validation.byDefaultProvider().configure()                .messageInterpolator(new ResourceBundleMessageInterpolator(				new PlatformResourceBundleLocator("validationMessages"))) //手动指定校验提示资源(默认在resource目录下ValidationMessages.properties)                .buildValidatorFactory().getValidator();    }     // 定义接口参数校验切入点    @Pointcut("@annotation(org.springframework.validation.annotation.Validated))")    private void validateMethod() {    }        @Before("validateMethod()")    public void before(JoinPoint joinPoint) throws CheckedException {        Object[] args = joinPoint.getArgs();        MethodSignature signature = (MethodSignature) joinPoint.getSignature();		// 执行方法参数的校验        Set<ConstraintViolation<Object>> constraintViolations = validator.forExecutables().validateParameters(joinPoint.getThis(), signature.getMethod(), args);        List<String> messages = Lists.newArrayList();        for (ConstraintViolation<Object> error : constraintViolations) {            messages.add(error.getMessage());        }        if(!messages.isEmpty()){            throw new CheckedException(JSONObject.toJSONString(messages));        }    }    }

代码解析:

  1. 在static块中,完成Validator的初始化;
  2. validateMethod是定义切点,通过PointCut注解可以看出,只有添加了Validated注解的方法被调用时,才会执行参数校验,此举是为了减少没有参数校验注解的方法也要执行校验的过程,避免性能浪费。
  3. 由于参数校验要先于方法的执行,所以,通过Before注解,执行前置执行,在该切面方法中完成参数的校验。

使用示例

在完成校验的逻辑后,接下来就是使用示例,使用时需要注册基本参数注解校验和POJO类型的参数校验,需要校验POJO时,需要添加Valid注解,其它的基本参数注解则正常使用即可,如下:

@Validatedpublic int saveUser(@Min(value=1, message="{a.b.c}") int operUserId, 					@NotNull(message = "{x.y.z}") @Valid User user);

 代码解析:

  1. 首先方法实现需要添加@Validated注解,否则,上一步中配置的切面不会被执行,从而也不会进行参数校验;
  2. 示例中分为基本参数校验和POJO校验,需要注意的是message注解属性的格式,这里硬编码也可以,但是使用占位符的方式更加方便配置和复用,此处a.b.c和x.y.z需要在上一步的validationMessages中定义好;
  3. 需要注意的是POJO需要额外添加@Valid注解,才能对POJO中的属性进行校验;
  4. 特别注意:1中的注解要写在实现类上,2、3中的注解需要写在接口上,实现类中写不写都可以,否则会出错,错误可自行研究。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值