Java 303 / 349 开始日期早于结束日期验证
Java 303 / 349 start date before end date validation
是否有更好的方法来编写 Java 验证器,以确保开始日期在结束日期之前,而不是通过以下方式编写 class 级别的 ConstraintValidator:
// VALIDATOR IMPLEMENTATION
public class StartBeforeEndDateValidator implements ConstraintValidator<StartBeforeEndDateValid, Object> {
// cannot use LocalDate here...
private String start;
private String end;
@Override
public void initialize(final StartBeforeEndDateValid annotation) {
start = annotation.start();
end = annotation.end();
}
@Override
public boolean isValid(final Object bean, final ConstraintValidatorContext context) {
try {
final String startDateStr = BeanUtils.getProperty(bean, start);
final String endDateStr = BeanUtils.getProperty(bean, end);
final LocalDate startDate = new LocalDate(startDateStr);
final LocalDate endDate = new LocalDate(endDateStr);
return !startDate.isAfter(endDate);
} catch (final Exception e) {
return false;
}
}
}
// USAGE
@StartBeforeEndDateValid(start = "startDate", end = "endDate")
@Entity
public class MyBean {
@NotNull
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate startDate;
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate endDate;
...
}
我不太喜欢必须使用反射从 bean 中提取 2 个日期对象这一事实。不幸的是,afaik 验证规范没有指定一种方法来仅设置您想要从 bean 验证的值。
一种方法是向 MyBean
添加一个接口
public interface StartEndDateable {
public LocalDate getStartDate();
public LocalDate getEndDate();
}
public class MyBean implements StartEndDatable {
...
然后您可以将 ConstraintValidator
上的通用类型设置为新接口而不是 Object。
public class StartBeforeEndDateValidator implements ConstraintValidator<StartBeforeEndDateValid, StartEndDatable> {
@Override
public void initialize(StartBeforeEndDateValid annotation) {
}
@Override
public boolean isValid(StartEndDatable bean, ConstraintValidatorContext context) {
final LocalDate startDate = bean.getStartDate();
final LocalDate endDate = bean.getEndDate();
return !startDate.isAfter(endDate);
}
}
显然任何 class 然后你想要验证开始和结束日期将必须实施 StartEndDateable
(不是我知道的最好的名字,我相信你能想到一些东西更好)并定义 getStartDate
和 getEndDate
方法。
是否有更好的方法来编写 Java 验证器,以确保开始日期在结束日期之前,而不是通过以下方式编写 class 级别的 ConstraintValidator:
// VALIDATOR IMPLEMENTATION
public class StartBeforeEndDateValidator implements ConstraintValidator<StartBeforeEndDateValid, Object> {
// cannot use LocalDate here...
private String start;
private String end;
@Override
public void initialize(final StartBeforeEndDateValid annotation) {
start = annotation.start();
end = annotation.end();
}
@Override
public boolean isValid(final Object bean, final ConstraintValidatorContext context) {
try {
final String startDateStr = BeanUtils.getProperty(bean, start);
final String endDateStr = BeanUtils.getProperty(bean, end);
final LocalDate startDate = new LocalDate(startDateStr);
final LocalDate endDate = new LocalDate(endDateStr);
return !startDate.isAfter(endDate);
} catch (final Exception e) {
return false;
}
}
}
// USAGE
@StartBeforeEndDateValid(start = "startDate", end = "endDate")
@Entity
public class MyBean {
@NotNull
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate startDate;
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate endDate;
...
}
我不太喜欢必须使用反射从 bean 中提取 2 个日期对象这一事实。不幸的是,afaik 验证规范没有指定一种方法来仅设置您想要从 bean 验证的值。
一种方法是向 MyBean
public interface StartEndDateable {
public LocalDate getStartDate();
public LocalDate getEndDate();
}
public class MyBean implements StartEndDatable {
...
然后您可以将 ConstraintValidator
上的通用类型设置为新接口而不是 Object。
public class StartBeforeEndDateValidator implements ConstraintValidator<StartBeforeEndDateValid, StartEndDatable> {
@Override
public void initialize(StartBeforeEndDateValid annotation) {
}
@Override
public boolean isValid(StartEndDatable bean, ConstraintValidatorContext context) {
final LocalDate startDate = bean.getStartDate();
final LocalDate endDate = bean.getEndDate();
return !startDate.isAfter(endDate);
}
}
显然任何 class 然后你想要验证开始和结束日期将必须实施 StartEndDateable
(不是我知道的最好的名字,我相信你能想到一些东西更好)并定义 getStartDate
和 getEndDate
方法。