列表字段中实体的百里香豆验证



我正在使用Springboot和Thyemleaf,尝试使用javax.validation.constraints注释验证我的表单数据。

在我的模板中,我使用的是Thyemleaf命令对象,它是我的模型类Quiz。在模型中,我有一些字段经过验证,比如so-

@NotBlank(message = "Title must not be blank")
private String title;
@NotBlank(message = "Text must not be blank")
private String text;
@NotNull
@Size(min = 2, max = 6, message = "Must be at least two, no more than six options")
private List<Option> options = new ArrayList<>(); // for Thymeleaf form

这是用于输入文本/标题的HTML-

<form th:action="@{/create}" th:object="${quiz}" method="post">
<div class="flex-column">
<label>Title</label>
<textarea type="text" class="form-control" th:field="*{title}" rows="1"></textarea>
<div class="error" th:if="${#fields.hasErrors('title')}" th:errors="*{title}">Error</div>
</div>
<div class="flex-column">
<label>Question</label>
<textarea type="text" class="form-control" th:field="*{text}" rows="2"></textarea>
<div class="error" th:if="${#fields.hasErrors('text')}" th:errors="*{text}">Error</div>
</div>

这是提交表单时端点的控制器-

@RequestMapping(value = "/create", params = {"save"})
public String saveQuizFromForm(@Valid final Quiz quiz, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
for (Option option : quiz.getOptions()) {
System.out.println("Option is empty? " + option.getOption().isEmpty());
}
bindingResult.getAllErrors().forEach(System.out::println);
log.info("Binding result error: {}", quiz);
return "create";
}
log.info("Quiz form submitted: {}", quiz); // todo save quiz to db
return "welcome"; // todo return form submitted result
}

在我的模板中,我可以提交表单,如果titletext为空,并且在消息中插入了一个新的div,则bindingResult将返回一个字段错误。

Field error in object 'quiz' on field 'text': rejected value []; codes [NotBlank.quiz.text,NotBlank.text,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [quiz.text,text]; arguments []; default message [text]]; default message [Text must not be blank]

我遇到字段List<Option> options的问题。该模型被注释为so-

@Entity(name = "options_table")
public class Option {
@NotEmpty(message = "Must enter an option")
private String option;

尽管输入为空,但bindingResult.getAllErrors()不会在该模型字段上返回错误,因为我在控制器中检查了option.getOption().isEmpty()返回true。

这是我用来尝试显示错误的HTML-

<div th:each="option, rowStat : *{options}">
<input type="text" th:field="*{options[__${rowStat.index}__].option}">
<ul th:if="${#fields.hasErrors('${quiz.options[__${rowStat.index}__].option}')}">
<li
class="error"
th:each="err : 
${#fields.errors('${quiz.options[__${rowStat.index}__].option}')}"
th:text="${err}">
Input is incorrect
</li>
</ul>
</div>

我也试过

th:if="${#fields.hasErrors('*{options[__${rowStat.index}__].option}')}"
th:each="err : ${#fields.errors('*{options[__${rowStat.index}__].option}')}"

我没有得到任何异常,但也没有创建任何错误li

我在这里检查了这个非常相似的问题,但它并没有解决问题。我的build.gradle文件中有Spring Boot启动器验证依赖项。implementation 'org.springframework.boot:spring-boot-starter-validation'

我在模型Quiz的字段中添加了@Valid注释。这递归地检查已验证的对象,并纠正了我的错误。

@NotNull
@OneToMany(mappedBy = "quiz", cascade = CascadeType.ALL)
@JsonManagedReference
@Valid
@Size(min = 2, max = 6, message = "Must be at least two, no more than six options")
private List<Option> options = new ArrayList<>();

最新更新