You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot整合Thymeleaf验证失效:空字段无错误提示

Spring Boot + Thymeleaf表单验证不生效问题修复

问题现象

在Spring Boot 3.3.5项目中,使用Thymeleaf作为模板引擎,DTO字段添加了@NotEmpty校验注解,Controller用@Valid和BindingResult处理验证,但提交空字段表单时,页面不显示错误提示,且BindingResult.getErrorCount()返回0。

相关代码

Thymeleaf表单页面

<form method="post" th:action="@{/add-client}" th:object="${clientRequestDto}">
<div th:if="${param.success}">
   <div class="alert alert-success" role="alert">
         Client successfully added
    </div>
</div>
<div class="mb-3">
   <label class="form-label">Код</label>
   <input  class="form-control"  th:field="*{codeClient}" placeholder="160103650">
  <span class="validationError" th:if="${#fields.hasErrors('codeClient')}"
th:errors="*{codeClient}">Name error</span>
</div>
<div class="mb-3">
    <label class="form-label">Название торговой точки</label>
    <input  class="form-control" th:field="*{name}" placeholder="Ашан">
     <span class="validationError" th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">Name error</span>
</div>

<input type="submit" value="Сохранить" class="btn btn-success">
<input type="reset" name="clearFilter" value="Очистить" class="btn btn-danger">
</form>

DTO类

import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Data
public class ClientRequestDto {
    @NotEmpty(message = "Вводите код")
    private String codeClient; 
    @NotEmpty(message = "Вводите название")
    private String name; 
}

Controller代码

@Controller
public class ClientController {

 @GetMapping("/clients")
    public String showClients(Model model){
     model.addAttribute("clientRequestDto", new ClientRequestDto());
     return "client";
 }

 @PostMapping("/add-client")
    public String addProduct(@ModelAttribute("clientRequestDto") @Valid ClientRequestDto clientRequestDto, BindingResult errors){
       
     if(errors.hasErrors()){
         return "client";
     }

     return "redirect:/clients?success";
 }
}

pom.xml依赖(原问题版本)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.project</groupId>
    <artifactId>wms</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>wms</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>21</java.version>
        <org.mapstruct.version>1.6.0.Beta1</org.mapstruct.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 问题根源:手动引入了不兼容的hibernate-validator版本 -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.2.0.Final</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

问题根源

Spring Boot 3.x基于Jakarta EE 9+,对应的Jakarta Validation规范是3.x版本,而手动引入的hibernate-validator:6.2.0.Final仅支持Jakarta Validation 2.x,版本不兼容导致验证框架无法正常工作,因此@Valid注解没有触发校验,BindingResult也捕获不到错误。

修复步骤

  1. 移除不兼容的依赖:删除pom.xml中手动添加的hibernate-validator依赖,因为spring-boot-starter-validation已经包含了与Spring Boot版本适配的hibernate-validator(Spring Boot 3.3.5对应的版本是8.x,兼容Jakarta Validation 3.x)。
  2. 清理并重建依赖:执行mvn clean install命令,清理旧依赖并重新下载适配版本的依赖包。
  3. 验证修复效果:重启项目,提交空字段表单,此时BindingResult会正确捕获验证错误,页面也会显示对应的错误提示信息。

额外注意点

  • 确保BindingResult参数紧跟在被@Valid注解标注的参数之后,否则Spring会将验证错误抛出为异常,而不会存入BindingResult中。
  • 确认spring-boot-starter-validation依赖已正确引入,这是Spring Boot中启用Jakarta Validation的必要依赖。

内容的提问来源于stack exchange,提问作者MPF PMF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:35:58