美文网首页spring 整合使用
Validation验证框架—动态的返回所有字段的异常信息

Validation验证框架—动态的返回所有字段的异常信息

作者: 小胖学编程 | 来源:发表于2021-07-27 17:46 被阅读0次

    Validation验证框架实现自定义注解时,我们想动态的返回异常信息,那么如何实现?

    一般Validation注解,存在一个message属性,当校验异常时,会将message的信息抛出。

    1. 需求背景

    需求:一个实体类中多个字段使用@ValidationXXX注解来校验多个字段的合法性。到出现异常时:

    1. 动态的输出异常信息;
    2. 将多个字段信息合并输出(且需要按照文档描述输出)。

    2. 实现方案

    采用的是SpringMVC框架下的@Valid+自定义注解+全局异常处理器实现。

    2.1 自定义校验注解

    存在message属性,当字段出现异常时,会抛出message配置的信息。

    @Target({METHOD, FIELD, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Constraint(validatedBy = ValidateWordValidator.class)
    @Documented
    public  @interface ValidateWord {
    
    
        String message() default "请求参数错误!";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    

    2.2 注解处理器—关闭默认消息,设置动态消息

    import com.alibaba.fastjson.JSON;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.util.CollectionUtils;
    
    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    import java.util.Set;
    
    @Slf4j
    public class ValidateWordValidator implements ConstraintValidator<ValidateWord, Object> {
    
        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            // 校验是否存在敏感词
            Set<String> hitSensitiveWords = WordUtil.hit(JSON.toJSONString(value));
    
            if (CollectionUtils.isEmpty(hitSensitiveWords)) {
                return true;
            } else {
                //敏感词使用,分割
                String word = String.join(",", hitSensitiveWords);
                //禁止默认消息返回
                context.disableDefaultConstraintViolation();
                //输出设置的信息
                context.buildConstraintViolationWithTemplate(word).addBeanNode().addConstraintViolation();
                return false;
            }
        }
    }
    

    关键点:

    1. 禁止默认的message属性输出。
    2. buildConstraintViolationWithTemplate设置个性化消息。

    2.3 全局异常处理器—解析异常类,汇总异常描述

    @Slf4j
    @ControllerAdvice
    public class GlobalExceptionHandler {
       @ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class})
        @ResponseBody
        public String validErrorHandler(MethodArgumentNotValidException e) {
            List<ObjectError> errors = e.getBindingResult().getAllErrors();
            List<String> results = new ArrayList<>();
            Set<String> sensitiveSets = new HashSet<>();
            //遍历
            if (!CollectionUtils.isEmpty(errors)) {
                for (ObjectError error : errors) {
                    ConstraintViolationImpl constraintViolation = error.unwrap(ConstraintViolationImpl.class);
                    ConstraintDescriptor constraintDescriptor = constraintViolation.getConstraintDescriptor();
                    constraintDescriptor.getAnnotation().annotationType();
                    //特定注解
                    if (ValidateWord.class.isAssignableFrom(constraintDescriptor.getAnnotation().annotationType())) {
                        String[] split = Objects.requireNonNull(error.getDefaultMessage()).split(",");
                        sensitiveSets.addAll(Arrays.asList(split));
                    } else {
                        //其他异常
                        results.add(error.getDefaultMessage());
                    }
                }
                if (!CollectionUtils.isEmpty(sensitiveSets)) {
                    results.add(0, String.format("您所输入的内容中包含敏感词,请重新输入,敏感词:%s", String.join(" ", sensitiveSets)));
                }
            }
            return results.get(0);
        }
    }
    

    详细代码实现:项目实战—@Valid+自定义校验注解+全局异常处理器实现敏感词过滤

    相关文章:

    JAVA基础篇(4)-Validation验证框架
    SpringBoot2.x—方法参数/返回值的注解版校验
    JAVA基础篇(15)—自定义“通用型枚举参数”校验注解
    SpringBoot2.x—方法参数/返回值的注解版校验(解决方法内事务不生效)
    SpringBoot项目启动时校验@ConfigurationProperties注解(对于内部类的支持)
    Spring进阶篇(9)- MethodValidationPostProcessor 后置处理器的运用

    相关文章

      网友评论

        本文标题:Validation验证框架—动态的返回所有字段的异常信息

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