Validation Vaadin 14-如何在表单验证中允许空值
我正在编写的应用程序的一部分是任务的“编辑器”表单。某些任务实体字段可以为空,例如:date completed 我正在使用Validation Vaadin 14-如何在表单验证中允许空值,validation,vaadin,Validation,Vaadin,我正在编写的应用程序的一部分是任务的“编辑器”表单。某些任务实体字段可以为空,例如:date completed 我正在使用活页夹将实体字段绑定到编辑器字段,并执行验证。我遇到了一个验证失败的问题,因为项目(如完成日期)为空。这个值可以为空。但是,该字段被标记为“value null”,实体不保存 有没有一种方法可以标记哪些基本上是可选字段,以便允许空值?当然,如果输入了值,则需要对其进行验证 Task.java(实体) EditTaskForm.java public class EditTa
活页夹
将实体字段绑定到编辑器字段,并执行验证。我遇到了一个验证失败的问题,因为项目(如完成日期)为空。这个值可以为空。但是,该字段被标记为“value null”,实体不保存
有没有一种方法可以标记哪些基本上是可选字段,以便允许空值?当然,如果输入了值,则需要对其进行验证
Task.java(实体)
EditTaskForm.java
public class EditTaskForm extends VerticalLayout {
private DatePicker dateDue;
private DatePicker dateStarted;
private DatePicker dateCompleted;
...
private void bindData() {
binder = new Binder<>(Task.class);
...
binder.forField(dateDue)
.withConverter(new LocalDateToLongConverter())
.bind("dateDue");
binder.forField(dateStarted)
.withConverter(new LocalDateToLongConverter())
.bind("dateStarted");
binder.forField(dateCompleted)
.withConverter(new LocalDateToLongConverter())
.bind("dateCompleted");
binder.withValidator(new TaskValidator());
}
private void validateAndSave() {
try {
binder.writeBean(task);
fireEvent(new SaveEvent(this, task));
} catch (ValidationException e) {
logger.error("field validation errors:");
e.getFieldValidationErrors().forEach(er -> {
logger.error("status: {}", er.getStatus());
logger.error("message: {}", er.getMessage().get());
logger.error("field: {}", er.getField().getValue());
});
logger.error("bean validation errors:");
e.getBeanValidationErrors().forEach(er -> {
logger.error(er.getErrorMessage());
});
}
}
...
}
虽然描述有点不清楚,代码示例也不够全面,我无法尝试,但我仍然对会发生什么有强烈的怀疑
文本“value null”既不是来自活页夹本身,也不是来自Vaadin的任何其他部分。相反,它很可能是由定制的
LocalDateToLongConverter
实现生成的。因此,我建议您检查它的实现,看看这是否是导致字段被标记为无效的原因。虽然描述有点不清楚,代码示例不够全面,我无法尝试,但我仍然对发生的情况有强烈的怀疑
文本“value null”既不是来自活页夹本身,也不是来自Vaadin的任何其他部分。相反,它很可能是由定制的
LocalDateToLongConverter
实现生成的。因此,我建议您检查它的实现,看看这是否是导致字段被标记为无效的原因。请添加您尝试过的代码以及失败的原因(例如错误、堆栈跟踪、日志等),以便我们对其进行改进。请添加您尝试过的代码以及失败的原因(例如错误、堆栈跟踪、日志等)所以我们可以改进它。你是对的。我已经用我的发现更新了帖子。你说得对。我已经用我的发现更新了帖子。
public class EditTaskForm extends VerticalLayout {
private DatePicker dateDue;
private DatePicker dateStarted;
private DatePicker dateCompleted;
...
private void bindData() {
binder = new Binder<>(Task.class);
...
binder.forField(dateDue)
.withConverter(new LocalDateToLongConverter())
.bind("dateDue");
binder.forField(dateStarted)
.withConverter(new LocalDateToLongConverter())
.bind("dateStarted");
binder.forField(dateCompleted)
.withConverter(new LocalDateToLongConverter())
.bind("dateCompleted");
binder.withValidator(new TaskValidator());
}
private void validateAndSave() {
try {
binder.writeBean(task);
fireEvent(new SaveEvent(this, task));
} catch (ValidationException e) {
logger.error("field validation errors:");
e.getFieldValidationErrors().forEach(er -> {
logger.error("status: {}", er.getStatus());
logger.error("message: {}", er.getMessage().get());
logger.error("field: {}", er.getField().getValue());
});
logger.error("bean validation errors:");
e.getBeanValidationErrors().forEach(er -> {
logger.error(er.getErrorMessage());
});
}
}
...
}
public class LocalDateToLongConverter implements Converter<LocalDate, Long> {
private ZoneId zoneId;
public LocalDateToLongConverter(ZoneId zoneId) {
this.zoneId = Objects.requireNonNull(zoneId, "Zone id cannot be null");
}
public LocalDateToLongConverter() {
this(ZoneId.systemDefault());
}
@Override
public Result<Long> convertToModel(LocalDate value, ValueContext context) {
if (value != null) {
return Result.ok(Date.from(value.atStartOfDay(zoneId).toInstant()).getTime());
} else {
return Result.ok(null);
// return Result.error("value null");
}
}
@Override
public LocalDate convertToPresentation(Long value, ValueContext context) {
if (value != null) {
return Instant.ofEpochMilli(value).atZone(zoneId).toLocalDate();
} else {
return null;
}
}
}