SpringBoot Service层使用Validated注解做接口参数校验

6 篇文章 0 订阅
5 篇文章 0 订阅

背景

使用注解参数校验,可避免业务代码中无休止的参数校验判断,在分层的方面来说,参数校验都是在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
@Component
public 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注解,其它的基本参数注解则正常使用即可,如下:

@Validated
public 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中的注解需要写在接口上,实现类中写不写都可以,否则会出错,错误可自行研究。

2020-12-4日更:看到各位的评论,貌似本文写的不是很清楚,特地补充demo项目,供各位看官参考、指导~

https://github.com/yuxiao97/service-validator

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
`@Validated`注解Spring框架提供的一种参数校验注解。它可以用来替代Java标准库中的`@Valid`注解,并且支持分组校验等功能。 `@Validated`注解可以用在类、方法、构造函数、方法参数以及方法返回值上。它的作用是启用方法参数校验。当方法被调用时,如果参数上标注了`@Validated`注解,则会对该参数进行校验。如果校验失败,则会抛出`MethodArgumentNotValidException`异常。 除了支持Java标准库中的参数校验注解之外,`@Validated`注解还支持分组校验功能。即可以根据不同的校验场景,对同一个类中的不同属性进行不同的校验。例如: ```java public interface Update { } public interface Create { } public class User { @NotNull(groups = Update.class) private Long id; @NotBlank(groups = {Create.class, Update.class}) private String name; @Min(value = 18, message = "年龄不能小于18岁", groups = {Create.class, Update.class}) private Integer age; // 省略getter和setter方法 } ``` 在上面的代码中,定义了两个分组`Create`和`Update`,并在`User`类中使用了分组校验注解。其中,`id`属性只在更新用户信息时进行校验,`name`和`age`属性在创建和更新用户信息时都需要进行校验。当进行校验时,需要指定对应的分组,例如: ```java @RestController @RequestMapping("/user") @Validated public class UserController { @PostMapping("/create") public ResponseEntity createUser(@RequestBody @Validated(Create.class) User user) { // ... } @PostMapping("/update") public ResponseEntity updateUser(@RequestBody @Validated(Update.class) User user) { // ... } } ``` 在上面的代码中,`@Validated(Create.class)`注解表示对`User`对象中标注了`Create`分组的属性进行校验,`@Validated(Update.class)`注解表示对`User`对象中标注了`Update`分组的属性进行校验。 综上所述,`@Validated`注解可以用来替代Java标准库中的`@Valid`注解,并且支持分组校验等功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值