001package cn.sticki.validator.spel; 002 003import cn.sticki.validator.spel.parse.SpelParser; 004import cn.sticki.validator.spel.result.FieldError; 005import cn.sticki.validator.spel.result.ObjectValidResult; 006import lombok.extern.slf4j.Slf4j; 007 008import javax.validation.ConstraintValidator; 009import javax.validation.ConstraintValidatorContext; 010import java.util.Arrays; 011import java.util.Set; 012import java.util.stream.Collectors; 013 014/** 015 * {@link SpelValid} 的实际校验器 016 * 017 * @author 阿杆 018 * @version 1.0 019 * @since 2024/4/11 020 */ 021@Slf4j 022public class SpelValidator implements ConstraintValidator<SpelValid, Object> { 023 024 private SpelValid spelValid; 025 026 @Override 027 public void initialize(SpelValid constraintAnnotation) { 028 this.spelValid = constraintAnnotation; 029 } 030 031 @Override 032 public boolean isValid(Object value, ConstraintValidatorContext context) { 033 if (value == null) { 034 return true; 035 } 036 037 // 表达式不为空且计算结果为 false,跳过校验 038 if (!spelValid.condition().isEmpty() && !SpelParser.parse(spelValid.condition(), value, Boolean.class)) { 039 log.debug("SpelValid condition is not satisfied, skip validation, condition: {}", spelValid.condition()); 040 return true; 041 } 042 043 // 获取分组信息 044 Set<Object> groups = Arrays.stream(spelValid.spelGroups()) 045 .map(it -> SpelParser.parse(it, value, Object.class)) 046 .collect(Collectors.toSet()); 047 048 // 校验对象 049 ObjectValidResult validateObjectResult = SpelValidExecutor.validateObject(value, groups); 050 051 // 构建错误信息 052 buildConstraintViolation(validateObjectResult, context); 053 return validateObjectResult.noneError(); 054 } 055 056 /** 057 * 生成错误信息并将其添加到验证上下文 058 */ 059 private void buildConstraintViolation(ObjectValidResult validateObjectResult, ConstraintValidatorContext context) { 060 if (validateObjectResult.noneError()) { 061 return; 062 } 063 context.disableDefaultConstraintViolation(); 064 for (FieldError error : validateObjectResult.getErrors()) { 065 context.buildConstraintViolationWithTemplate(error.getErrorMessage()) 066 .addPropertyNode(error.getFieldName()) 067 .addConstraintViolation(); 068 } 069 } 070 071}