【问题标题】:Why is my custom constraintValidator throwing null pointer?为什么我的自定义约束验证器会抛出空指针?
【发布时间】:2018-08-19 07:48:35
【问题描述】:

我正在创建一个自定义 ConstraintValidator,以验证我的 JodaTime 对象的小时数是否在从弹簧表单输入的特定窗口内。

我的注释:

@Target({ElementType.METHOD, ElementType.FIELD})
@Documented
@Constraint(validatedBy = InputHoursValidator.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface InputHoursConstraint {
String message() default "";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}

我的验证者

public class InputHoursValidator implements ConstraintValidator<InputHoursConstraint, DateTime> {
private static final DateTimeFormatter HOURS_TIME_FORMAT = DateTimeFormat.forPattern("hh:mma");
private static final String EARLIEST_START_TIME = "5:00pm";
private static final String LATEST_END_TIME = "4:00am";

@Override
public void initialize(InputHoursConstraint constraintAnnotation) {

}

@Override
public boolean isValid(DateTime value, ConstraintValidatorContext context) {
    return !value.isBefore(DateTime.parse(EARLIEST_START_TIME, HOURS_TIME_FORMAT))
            && !value.isAfter(DateTime.parse(LATEST_END_TIME, HOURS_TIME_FORMAT).plusDays(1));

}


}

还有我带有注释的魔力

public class HoursTrackingForm {

@NotNull(message = "Please enter a valid time in AM or PM")
@DateTimeFormat(pattern = "hh:mma")
@InputHoursConstraint(message = "Start time was before 5:00pm or after 4:00am")
private DateTime startTime;

@NotNull(message = "Please enter a valid time in AM or PM")
@DateTimeFormat(pattern = "hh:mma")
@InputHoursConstraint(message = "End time was before 5:00pm or after 4:00am")
private DateTime endTime;

//getters and setters
}

在我看来一切都很好,但是当我提交我的对象进行验证时,验证器中的 DateTime 始终为空。

【问题讨论】:

  • 找不到代码有什么问题。它应该工作得很好。相反,验证本身的逻辑似乎是错误的,并且总是返回 false。
  • @S.K.每次我从我的春季表单提交请求时,逻辑除外,我在 DateTime 中返回 null。在添加此自定义约束之前不会发生这种情况。

标签: java spring-mvc


【解决方案1】:

我的问题有两个方面。

1) 如果我正在测试一个空场景,我没有意识到即使发现错误,所有约束仍然得到验证。因此,虽然 not null 导致了验证错误,但我的自定义约束仍然会引发 NPE。解决方案是删除@NotNull 并在@InputHoursConstraint 中进行检查。

2) 在我的验证注释中,我在@Target 中添加了ElementType.TYPEElementType.LOCAL_VARIABLE,这似乎允许它工作。仍在研究原因,因为根据我的理解,我只需要 ElementType.FIELD

【讨论】:

  • ElementType.TYPE 是类级别注释所需要的全部
  • 通常,即使发现错误,评估所有约束也是框架的一种很好的默认行为。这样一来,人们可以一次提供所有违规信息,例如在评估他/她的输入时,一次性告诉用户所有现有的问题。自定义验证的特殊情况存在风险,即错过检查正在验证的对象是否可能为空。这样的空对象可能会导致空指针异常,在有用的评估过程中当然应该避免这些异常。在评估期间抛出的任何异常都可能是一个坏主意,因为它会阻止更正。
猜你喜欢
  • 2019-10-16
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 2018-01-29
相关资源
最近更新 更多