当前位置: 首页 > 知识库问答 >
问题:

使用多字段的Spring自定义注释验证

戚鸿福
2023-03-14

这里有一个小问题,希望这个问题也能帮助其他想知道更多关于注释验证的人

我目前正在研究Spring,目前,我计划尝试定制注释验证。

我搜索了很多,现在我知道主要有两种验证,一种用于控制器,另一种是使用@Valid的注释方法

public class Subscriber {
    private String name;
    private String email;
    private Integer age;
    private String phone;
    private Gender gender;
    private Date birthday;
    private Date confirmBirthday;
    private String birthdayMessage;
    private Boolean receiveNewsletter;

    //Getter and Setter
}
public class Subscriber {
    private String name;
    private String email;
    private Integer age;
    private String phone;
    private Gender gender;

    @NotNullIf(fieldName="confirmBirthday")
    private Date birthday;

    @NotNullIf(fieldName="birthday")
    private Date confirmBirthday;

    private String birthdayMessage;
    private Boolean receiveNewsletter;

    //Getter and Setter
}
@Documented
@Constraint(validatedBy = NotNullIfConstraintValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD })
public @interface NotNullIf {

    String fieldName();

    String message() default "{NotNullIf.message}";
    Class<?>[] group() default {};
    Class<? extends Payload>[] payload() default {};
}

在此之后,我需要创建验证器本身:

public class NotNullIfConstraintValidator implements ConstraintValidator<NotNullIf, String>{

    private String fieldName;

    public void initialize(NotNullIf constraintAnnotation) {
        fieldName = constraintAnnotation.fieldName();
    }

    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(value == null) {
            return true;
        };
        //TODO Validation
        return false;
    }

}

另一个想法是使用同一个类作为一个例子,它说我想要生日,confirmBirthday和birthdayMessdage只能同时为null或反对。这次我可能需要使用类注释验证来进行跨字段验证。

下面是我对该类的注释:

@NotNullIf(fieldName={"birthday", "confirmBirthday", "birthdayMessage"})
public class Subscriber {
    //Those field same as the above one
}

共有1个答案

严亦
2023-03-14

为此,您只能使用类型级批注,因为字段级批注无法访问其他字段!

我做了一些类似的事情来允许选择验证(许多属性中的一个必须不为空)。在您的示例中,@allornone注释(或您喜欢的任何名称)需要一个字段名数组,您将向验证器获取带注释类型的整个对象:

@Target(ElementType.TYPE)
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = AllOrNoneValidator.class)
public @interface AllOrNone {
    String[] value();

    String message() default "{AllOrNone.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class AllOrNoneValidator implements ConstraintValidator<AllOrNone, Object> {
    private static final SpelExpressionParser PARSER = new SpelExpressionParser();
    private String[] fields;

    @Override
    public void initialize(AllOrNone constraintAnnotation) {
        fields = constraintAnnotation.value();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        long notNull = Stream.of(fields)
                .map(field -> PARSER.parseExpression(field).getValue(value))
                .filter(Objects::nonNull)
                .count();
        return notNull == 0 || notNull == fields.length;
    }
}

(正如您所说的使用Spring,我使用SpEL甚至允许嵌套字段访问)

@AllOrNone({"birthday", "confirmBirthday"})
public class Subscriber {
    private String name;
    private String email;
    private Integer age;
    private String phone;
    private Gender gender;
    private Date birthday;
    private Date confirmBirthday;
    private String birthdayMessage;
    private Boolean receiveNewsletter;
}
 类似资料:
  • 我正在开发一个java spring mvc应用程序。我已经实现了一个自定义的验证注释来验证某些字符串(例如)。这是我的注释体: 这是我的类:

  • 问题内容: 这里有一个贪婪的小问题,希望这个问题也可以帮助其他想更多地了解注释验证的人 我目前正在学习Spring,现在,我计划尝试自定义带注释的验证。 我已经进行了很多搜索,现在我知道主要有两种验证,一种用于控制器,另一种是使用@Valid的注释方法 所以这是我的情况:假设我有两个或多个字段,当它们均为ALL NULL时可以为null。但是,只有当这些字段之一包含空字符串以外的任何值时,才要求这

  • 我正在尝试使用Spring安全注释,如@PreAuthorize和@安全,但我希望评估用户不是在一个角色上,而是他们是否拥有对特定实体的权限,在这种情况下是一家公司。在我的控制器中,我收到一个超文本传输协议请求,其中包含一个firmId作为参数,我想确保这个用户被允许进入这家公司。是否可以使用当前的Spring安全注释?。我正在寻找一个优雅的解决方案,我一直在寻找自定义约束验证器作为jsr303规

  • 我发现了几个与此相关的(不是重复的)问题,但它们不能让我满意。 我无法理解在哪里以及为什么要使用? 我在一本书中读到了一个自定义注释的示例,但没有详细解释。 myMeth()内的输出与预期一致。 关于这个例子,我有几个问题。 1-如何在此程序中使用和?或

  • 我正在开发spring mvc应用程序,我应该在spring mvc validator的基础上应用验证。第一步,我为类和设置控制器添加了注释,效果很好。现在我需要实现自定义验证器来执行复杂的逻辑,但我想使用现有的注释并添加额外的检查。 我的用户类: 我的验证器: 我的控制器: 那么,有可能同时使用自定义验证器和注释吗?如果是,怎么做?

  • 我在网上搜索了一个关于如何使用Spring AOP调用自定义方法注释的清晰示例,但没有找到一个清晰的示例。 我正在构建一个框架,以便在调用任何POJO上的某些方法时在上下文中注入用户配置文件。 框架API应该通过自定义方法注释调用,例如。我可以构建注释部分和解析器,我的问题是在调用带注释的方法时调用我的解析器的最佳方式是什么。 我们正在使用Spring 3.0,想知道配置Spring框架以理解那些