美文网首页
使用Hibernate-Validator优雅的参数验证

使用Hibernate-Validator优雅的参数验证

作者: 养一只tom猫 | 来源:发表于2022-01-04 16:39 被阅读0次

    在开发中,经常会有各种校验的代码,而这些代码与业务逻辑无关,我们可以通过自定义校验注解来简化这些代码。
    以下StringIn注解起到限制入参的作用,如我们数据库存储一个类型值只有"1"或者"2",对前端或者其余系统调用时传了约定以外的值进行校验。

    1. 添加 Hibernate-Validator 依赖
            <dependency>
                <groupId>org.hibernate.validator</groupId>
                <artifactId>hibernate-validator</artifactId>
            </dependency>
    
    1. 自定义注解
    /**
     * Created by Jie on 2021/12/31 上午9:14
     */
    @Documented
    @Retention(RUNTIME)
    @Repeatable(StringIn.List.class)
    @Constraint(validatedBy = {StringInValidator.class})
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    public @interface StringIn {
    
        String[] value() default {};
    
        Class<?>[] groups() default {};
    
        String message() default "";
    
        @SuppressWarnings("unused")
        Class<? extends Payload>[] payload() default {};
    
        @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
        @Retention(RUNTIME)
        @Documented
        @interface List {
            StringIn[] value();
        }
    }
    
    1. 编写校验类
    /**
     * Created by Jie on 2021/12/31 上午9:19
     */
    public class StringInValidator implements ConstraintValidator<StringIn, String> {
    
        private List<String> valueList;
    
        @Override
        public void initialize(StringIn constraintAnnotation) {
            valueList = Arrays.asList(constraintAnnotation.value());
        }
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            if (value == null) {
                return true;
            }
    
            return valueList.contains(value);
        }
    
    }
    

    由于该框架抛出异常格式令人吐槽,可编写全局异常处理器来解析并返回更合理的格式。

    /**
     * Created by Jie on 2021/12/31 上午10:02
     */
    @RestControllerAdvice
    public class ValidateExceptionHandler {
    
        @ExceptionHandler(value = MethodArgumentNotValidException.class)
        public Result methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
            String message = e.getBindingResult()
                    .getAllErrors()
                    .stream()
                    .map(DefaultMessageSourceResolvable::getDefaultMessage)
                    .collect(Collectors.joining(""));
            return new Result(200, message);
        }
    
    }
    

    测试:

    @Data
    public class TestEntity {
    
        private String id;
    
        @StringIn(value = {"1", "2"}, message = "name值不在给定范围内!", groups = AddGroup.class)
        private String name;
    }
    
    /**
     * Created by Jie on 2021/12/30 下午8:18
     */
    @RestController
    @RequestMapping("/test")
    public class TestController {
    
        @PostMapping("/testAdd")
        public Result testAdd(@RequestBody @Validated(value = AddGroup.class) TestEntity entity) {
            return new Result(200, "添加成功", null);
        }
    
    }
    

    该方式可自由扩展,甚至可用到Spel表达式进行校验,此种方法在service中能完全告别参数校验相关的代码。

    相关文章

      网友评论

          本文标题:使用Hibernate-Validator优雅的参数验证

          本文链接:https://www.haomeiwen.com/subject/uwcqcrtx.html