〇×〇站

个人博客,佛系更新

Custom validation starter for Spring Boot

  • Pluto
  • 2026-03-03 17:48:52
  • 7
  • 发现一个参数校验的框架:

    vennarshulytz/validation-parent: Custom validation starter for Spring Boot

    pom.xml引入依赖:

    <dependency>
        <groupId>io.github.vennarshulytz</groupId>
        <artifactId>validation-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    </dependency>
    

    springboot启动类加注解:

    @EnableValidation
    

    controller类加注解:

    @ValidatedExt
    

    模拟使用:

    @RequestMapping("/getDetail")
    public R<GetDetailRes> getDetail(@RequestBody @ValidationRules({
    //            @ValidationRule(type = GetDetailReq.class, validators = {
    //                    @ValidateWith(validator = IdIsNotNullValidator.class, fields = @FieldConfig(names = {"id", "id2"}, message = "ID不能为空")),
    //            }),
            @ValidationRule(custom = TestCustomValidator.class)
    }) GetDetailReq req
    //             , @RequestParam @IdIsNotNullCheck(message = "学员ID不能为空") BigDecimal userId
    ) {
        return R.SUCCESS();
    }
    

    校验单个参数:

    import cn.hutool.core.util.StrUtil;
    import io.github.vennarshulytz.validation.validator.FieldValidator;
    import io.github.vennarshulytz.validation.validator.builtin.AbstractDecimalValidator;
    import java.lang.annotation.Annotation;
    import java.math.BigDecimal;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
    
    public class IdIsNotNullValidator extends AbstractDecimalValidator implements FieldValidator {
    
        @Override
        public String validate(String fieldName, Object value, Map<String, Object> params, boolean enableI18n) {
            return isValid(value) ? null : this.getErrorMessage(params);
        }
    
        @Override
        public Map<String, Object> parseParams(Annotation annotation) {
            if (annotation instanceof IdIsNotNullCheck) {
                IdIsNotNullCheck idIsNotNullCheck = (IdIsNotNullCheck) annotation;
                Map<String, Object> params = new HashMap<>();
                params.put("message", idIsNotNullCheck.message());
                return params;
            } else {
                return Collections.emptyMap();
            }
        }
    
        private String getErrorMessage(Map<String, Object> params) {
            String errorMessage = (String) params.get("message");
            if (StrUtil.isNotBlank(errorMessage)) {
                return errorMessage;
            } else {
                return this.getDefaultMessage();
            }
        }
    
        private boolean isValid(Object value) {
            BigDecimal id = this.toBigDecimal(value);
            return id != null && id.compareTo(BigDecimal.ZERO) > 0 && id.scale() == 0;
        }
    }
    

    行内参数校验:

    import io.github.vennarshulytz.validation.annotation.ValidateWith;
    import java.lang.annotation.*;
    
    @Documented
    @Target({ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @ValidateWith(validator = IdIsNotNullValidator.class)
    public @interface IdIsNotNullCheck {
        String message();
    }
    

    多个参数组合校验(或查库等复杂操作):

    import io.github.vennarshulytz.validation.validator.CustomValidator;
    import io.github.vennarshulytz.validation.validator.ValidationResult;
    
    public class TestCustomValidator implements CustomValidator<GetDetailReq> {
    
        @Override
        public void validate(GetDetailReq request, ValidationResult result) {
            if(DataUtil.idIsNull(request.getId()) && DataUtil.idIsNull(request.getId2())) {
                result.addError("id,id2", "id或id2不能为空", null);
            }
        }
    }
    

    统一处理校验失败的返回格式:

    import io.github.vennarshulytz.validation.exception.ValidationException;
    import io.github.vennarshulytz.validation.validator.ValidationResult;
    import org.springframework.core.annotation.Order;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    import java.util.stream.Collectors;
    
    @Order(-1) // 优先级最高
    @RestControllerAdvice
    public class ValidationExceptionHandler {
    
        @ExceptionHandler(ValidationException.class) // 只处理ValidationException异常
        public Object handleValidationException(ValidationException e) {
            String errors = e.getErrors().stream().map(ValidationResult.FieldError::getMessage).distinct().collect(Collectors.joining("; "));
            return R.ERROR(errors);
        }
    }
    
    分类:
  • 代码
  • 标签:
  • java