当前位置: 首页 > 面试题库 >

具有多个字段的Spring自定义注释验证

丌官瀚
2023-03-14
问题内容

这里有一个贪婪的小问题,希望这个问题也可以帮助其他想更多地了解注释验证的人

我目前正在学习Spring,现在,我计划尝试使用定制的带注释的验证。

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

所以这是我的情况:假设我有两个或多个字段,当它们均为ALL
NULL时可以为null。但是,只有当这些字段之一包含空字符串以外的任何值时,才要求这些字段具有输入。我有两个想法,但不知道如何正确实施它们。

这是课程示例:

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
}

假设我希望Birthday和confirmBirthday字段都必须为null或相反,我可能想对它们每个使用一个注释来对其进行注释,如下所示:

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
}

因此,当该字段之一不为null时,还需要根据客户端大小输入其余字段。可能吗?

但是我仍然对上面列出的那些元素的注释验证如何工作感到困惑。也许我需要对该代码进行一些详细的说明,甚至更糟的是,我可能需要进行一些基本的概念检查。

请帮忙!


问题答案:

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

我做了类似的事情以允许选择验证(确切地说,多个属性之一必须不为null)。在您的情况下,@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甚至允许嵌套字段访问)

现在,您可以注释您的Subscriber类型:

@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;
}


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

  • 这里有一个小问题,希望这个问题也能帮助其他想知道更多关于注释验证的人 我目前正在研究Spring,目前,我计划尝试定制注释验证。 我搜索了很多,现在我知道主要有两种验证,一种用于控制器,另一种是使用@Valid的注释方法 在此之后,我需要创建验证器本身: 另一个想法是使用同一个类作为一个例子,它说我想要生日,confirmBirthday和birthdayMessdage只能同时为null或反对。

  • 我正在开发一个java spring mvc应用程序。我已经实现了一个自定义的验证注释来验证某些字符串(例如)。这是我的注释体: 这是我的类:

  • 问题内容: 我为我写了一个 对于每个我使用以下注释 因此,我决定定义自己的注释女巫,其中包含所有这样的注释 然后,我只用了一个注释 修改后,测试失败 为了使其再次工作,需要我将其添加到 我的问题是为什么我的注释包含注释时不起作用?注释有什么特别之处吗?还是我错过了什么? PS:我使用相同的方法,它们也很好用。 问题答案: 这种机制是Spring框架特有的,在这种机制中,您可以使用本身带有其他注释的

  • 我已经用自定义注释注释了Spring bean,但似乎Spring在创建bean后删除了我的自定义注释。 第二步不行,我的自定义注释丢失了。(可能是到期的代理文件) 我的豆子 我的一个自定义注释的示例 findAndDoStuffWithAnnotatedThings Bean中出错的内容被传递到一个类,在该类中,我的自定义注释得到验证,但我的验证程序找不到任何注释。(Util使用isAnnota

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

  • 我使用Spring MVC和Hibernate来开发一个Web应用程序。起初,我只使用标准的JSR303注释。然后,我决定使用一些自定义注释来验证一个新用户的用户名和电子邮件的唯一性,该用户希望创建一个帐户。 因此,我创建了两个注释,如下所示(一个用于电子邮件,另一个用于用户名):