001package cn.sticki.validator.spel;
002
003import org.intellij.lang.annotations.Language;
004
005import javax.validation.Constraint;
006import java.lang.annotation.Documented;
007import java.lang.annotation.Retention;
008import java.lang.annotation.Target;
009
010import static java.lang.annotation.ElementType.*;
011import static java.lang.annotation.RetentionPolicy.RUNTIME;
012
013/**
014 * 标记开启spel约束注解的验证,其功能类似于 {@link javax.validation.Valid},用于开启 {@link cn.sticki.validator.spel.constrain} 包下定义的spel约束。
015 * <p>
016 * 注意:该注解需要配合 {@link javax.validation.Valid} 或 {@link org.springframework.validation.annotation.Validated} 注解一起使用。
017 * <p>
018 * 这种行为是非递归应用的,只对当前标记对象的属性生效,不会对其属性的下层属性进行验证。
019 * <p>
020 * 以下是一个简单的例子:
021 * <pre>
022 * &#064;PostMapping("/test")
023 * public void test(@RequestBody <u>@Valid</u> TestParamVo testParamVo) {
024 *    ...
025 * }
026 *
027 * &#064;Data
028 * <u>&#064;SpelValid</u>
029 * public class TestParamVo {
030 *
031 *     private Boolean switchVoice;
032 *
033 *     &#064;SpelNotNull(condition = "#this.switchVoice == true")
034 *     private Object voiceContent;
035 *
036 *     <u>@Valid</u>
037 *     <u>&#064;SpelValid</u>
038 *     private TestParamVo2 testParamVo2;
039 *
040 * }
041 *
042 * &#064;Data
043 * public class TestParamVo2 {
044 *
045 *    &#064;SpelNotNull(condition = "true")
046 *    private Object object;
047 *
048 * }
049 * </pre>
050 * <p>
051 * 在上面的例子中,{@code TestParamVo} 和 {@code TestParamVo2} 都成功开启了spel校验。
052 *
053 * @author 阿杆
054 * @version 1.0
055 * @since 2024/4/11
056 */
057@Documented
058@Retention(RUNTIME)
059@Target({METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE})
060@Constraint(validatedBy = {SpelValidator.class})
061public @interface SpelValid {
062
063        String message() default "";
064
065        Class<?>[] groups() default {};
066
067        Class<?>[] payload() default {};
068
069        /**
070         * 开启校验的前置条件,值必须为合法的 spel 表达式
071         * <p>
072         * 当 表达式为空 或 计算结果为true 时,表示开启校验
073         */
074        @Language("SpEL")
075        String condition() default "";
076
077        /**
078         * 分组功能,值必须为合法的 spel 表达式
079         * <p>
080         * 当分组信息为空时,表示不开启分组校验
081         */
082        @Language("SpEL")
083        String[] spelGroups() default {};
084
085}