Spring Boot学习——Valid注解使用

1 篇文章 0 订阅
1 篇文章 0 订阅

在日常业务开发过程中会涉及到很多业务参数的校验,其中空值判断又是其中最多的内容。但在每个业务方法中都进行校验,即便将业务要素相近的校验进行合并,仍然有些繁琐。于是想利用@Valid进行简单校验,减少简单重复代码。
Valid注解的使用有几个不同的方法,其中一个是直接修饰入参对象,这种方法可以参考@Valid注解是什么
这次是直接修饰具体方法的使用示例

相关包依赖

		<dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

其中jakarta.validation-api是相关校验类型定义包;hibernate-validator是具体实现包,可以单独使用,搭配使用时建议不要降低其版本,否则会出现某些校验类型不可使用的问题

具体代码

Valid注解捕获切面
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.Validator;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@Aspect
public class ValidAspectInterceptor {

    @Autowired
    private Validator validator;

    @Before(value = "@annotation(valid)")
    public void validateArgs(JoinPoint joinPoint, Valid valid) {
        Object[] objects = joinPoint.getArgs();
        Set<ConstraintViolation<Object>> set = validator.validate(objects[0]);
        if (set.size() > 0) {
            String errorInfo = set.stream().map(x -> x.getMessage())
                    .collect(Collectors.toSet()).stream()
                    .collect(Collectors.joining(","));
            throw new ValidationException(errorInfo);
        }
    }
}
测试实体类
import lombok.Data;
import javax.validation.constraints.NotBlank;

@Data
public class TestEntity {
    @NotBlank(message = "value1值为空")
    private String value1;
    private String value2;
    private String value3;
}

测试请求类
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;

@RestController
@RequestMapping("/Valid")
public class TestController {

    @RequestMapping("/test")
    @Valid
    public String newEntity(@RequestBody TestEntity testEntity) {
        System.out.println(JSON.toJSONString(testEntity));
        return "success";
    }
}

此时向测试接口post json :{“value2”: “2”},后台报错:在这里插入图片描述
此时添加异常捕获方法,则可以实现统一的错误信息返回,示例代码如下:

import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ValidationException;
import java.util.List;

@ControllerAdvice
public class BadRequestExceptionHandler {
    /**
     * 校验错误拦截处理
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public String validationBodyException(Exception exception) {
        return exception.getMessage();
    }
}

此时响应如下:
在这里插入图片描述

自定义验证类型

除了使用包里面提供的验证类型外,还可以自定义验证类型,满足相对复杂的校验场景。
自定义类型主要包括两个类

1.注解定义
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {NotZeroValidator.class})
public @interface NotZero {
    String message();

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
2.验证类型实现
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;

public class NotZeroValidator implements ConstraintValidator<NotZero, Object> {
    @Override
    public void initialize(NotZero constraintAnnotation) {
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        if (Objects.isNull(o)) {
            return false;
        }
        if (o instanceof Double) {
            return (Double) o != 0D;
        } else if (o instanceof Long) {
            return (Long) o != 0L;
        } else if (o instanceof Float) {
            return (Float) o != 0F;
        } else if (o instanceof Integer) {
            return (Integer) o != 0;
        }
        return false;
    }
}

此时实体类修改如下:

import lombok.Data;
import javax.validation.constraints.NotBlank;

@Data
public class TestEntity {
    @NotBlank(message = "value1值为空")
    private String value1;
    private String value2;
    private String value3;
    @NotZero(message = "value4不可为零")
    private Integer value4;
    @NotZero(message = "value5不可为零")
    private Float value5;
    @NotZero(message = "value6不可为零")
    private Double value6;
}

验证请求如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值