Thymelaf th:如果..th:在@PostMapping方法检查@Valid后,errors不会在页面中显示错误



我在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) {

谢谢德克。

最新更新