我在Thymelaf上使用Spring Boot 2.4.1,在Ubuntu 20.10上使用OpenJDK 11.0.9.1。我已经用@NotNull和其他标记标记了实体,@Valid标记在控制器处理POST请求的方法中似乎工作得很好,因为出错时它会返回到原始页面。但是,Thymelaf模板中的th:if...th:errors
无法显示相应的错误消息。
胸腺素模板(/editor
(包括一种形式:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<body>
...
<form method="POST" th:object="${competence}">
<h3>Additional information</h3>
<label for="compname">Name:</label>
<input type="text" id="compname" th:field="*{name}" />
<span class="validationError"
th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Error</span><br/>
<label for="compdesc">Description:</label>
<textarea class="description" id="compdesc" th:field="*{description}" />
<button>Regístrala</button>
</div>
</form>
而控制器包括一种处理POST请求的方法:
@Slf4j
@Controller
@RequestMapping("/editor")
public class CompetenceEditorController {
...
@PostMapping
public String processCompetence(@Valid CompetenceEntity competence,
final BindingResult bindingResult, final Model model) {
// Checking for errors in constraints defined in the class CompetenceEntity.
if (bindingResult.hasErrors()) {
return "editor";
} else {
// Save the competence
log.info("Processing competence: " + competence);
CompetenceEntity saved = competenceRepository.save(competence);
return "redirect:/competence-saved";
}
}
如果我填写了名称和描述,该过程将继续,但如果我将名称留空,代码会将我发送回/editor
页面,但不会出现错误消息。span
元素在错误前后都会消失。
编辑
我认为@dirk deyne的建议是有效的,但只有在以下情况下才能做到:(1(我在以前的代码上运行Spring Boot,(2(我将名称留空(并且我返回到同一页面而没有错误消息(,(3(我关闭Boot;"修复";代码,然后再次运行它,(4(一次又一次地将名称留空。
但如果我离开页面,然后再回来,我会收到错误消息:
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/editor.html]")
...
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "editor" - line 51, col 46)
其中51行为
<input type="text" id="compname" th:field="*{name}" />
列46(包括空格(是th:field
的开始。顺便说一下,@GetMapping方法有以下行
model.addAttribute("competence", new CompetenceEntity());
这就是为什么我使用CCD_ 6而不是CCD_。
Dirk Deyne说,解决方案是。用@ModelAttribute("competence")
:将胸腺中的competence
与@PostMapping
方法中的competence
连接起来,解决了这一问题
@PostMapping
public String processCompetence(
@Valid @ModelAttribute("competence") CompetenceEntity competence,
final BindingResult bindingResult, final Model model) {
谢谢德克。