Spring in action @valid验证不生效问题解决

在尝试按照书上示例使用Spring的@Valid进行数据校验时,发现校验并未生效。问题源于缺少Hibernate Validator的实现包,通过Maven导入相关依赖后,仍无法正常工作。进一步排查发现,可能由于Tomcat的类加载问题导致NoClassDefFoundError。在Stack Overflow上找到解决方案,需要引入缺失的validation-api和hibernate-validator依赖,但问题仍未解决。最终,将这些jar包直接放入Tomcat的lib目录下,成功解决了校验不生效的问题。此外,还分享了解决Maven导入jar包在运行时找不到类的通用方法。

按照书上的示例代码来实现但是,添加了验证但是没有生效。
Spring提供了校验Api是使用但是没有提供实现,所以需要自己导入实现包。
所以导入实现包:

<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.1.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>

但是还是没有解决问题,程序正常运行,校验不生效。
想到之前用Maven来导入一些jar报的时候,还是会提示找不到(不知道是不是因为使用的Xampp自带的tomcat的原因)。之前的解决办法就是把Jar包丢到Tomcat的lib文件夹下。于是就把上面Maven下载下来的两个jar包丢了进去,果然发生了一些变化,这次出现了报错,程序不能正常运行。报错:

Hibernate Validator java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl

然后查找解决办法,在Stack Overflow上找到了解决办法,缺少org.jboss.loggingcom.fasterxml classmate包,所以在Maven中加入

  <dependency>
 	  <groupId>org.jboss.logging</groupId>
      <artifactId>jboss-logging</artifactId>
      <version>3.3.2.Final</version>
  </dependency>
  <dependency>
      <groupId>com.fasterxml</groupId>
      <artifactId>classmate</artifactId>
      <version>1.3.4</version>
  </dependency>

但是还是没有解决问题,使用老办法,把这两个Jar包丢到Tomcat的lib文件夹下,问题解决。

最近遇到好多Maven导入的包在运行的时候不生效的问题,就是不报错,但是运行的时候nodefClass错误。找到解决办法:
IDEA maven项目部署到tomcat的jar包找不到问题

Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/  :: Spring Boot ::   (v3.5.3) 07-28 17:36:29 INFO StartupInfoLogger.java:53 Starting Mb3Application using Java 21.0.7 with PID 16460 (D:\Eclipse\mb3\target\classes started by Administrator in D:\Eclipse\mb3) 07-28 17:36:29 INFO SpringApplication.java:652 No active profile set, falling back to 1 default profile: "default" 07-28 17:36:30 INFO TomcatWebServer.java:111 Tomcat initialized with port 80 (http) 07-28 17:36:30 INFO DirectJDKLog.java:168 Starting service [Tomcat] 07-28 17:36:30 INFO DirectJDKLog.java:168 Starting Servlet engine: [Apache Tomcat/10.1.42] 07-28 17:36:30 INFO DirectJDKLog.java:168 Initializing Spring embedded WebApplicationContext 07-28 17:36:30 INFO ServletWebServerApplicationContext.java:301 Root WebApplicationContext: initialization completed in 798 ms Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts 07-28 17:36:31 INFO DruidDataSource.java:1002 {dataSource-1} inited 07-28 17:36:31 INFO AbstractImageCaptchaGenerator.java:67 图片验证码[SpringMultiImageCaptchaGenerator]初始化... 07-28 17:36:31 INFO OptionalValidatorFactoryBean.java:48 Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath. 07-28 17:36:31 WARN ThymeleafAutoConfiguration.java:102 Cannot find template location: classpath:/templates/page/ (please add some templates, check your Thymeleaf configuration, or set spring.thymeleaf.check-template-location=false) 07-28 17:36:31 INFO TomcatWebServer.java:243 Tomcat started on port 80 (http) with context path '/' 07-28 17:36:31 INFO StartupInfoLogger.java:59 Started Mb3Application in 1.924 seconds (process running for 2.431)
07-29
<think>我们有两个问题需要解决: 1. 日志冲突:Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts. 2. Bean Validation提供者缺失:Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. 我们分别解决这两个问题问题1:日志冲突 Spring Boot使用spring-jcl(Spring的Commons Logging桥接)作为日志门面。当类路径中存在commons-logging.jar时,可能会导致冲突,因为spring-jcl已经包含了必要的桥接功能。 解决方案: 1. 检查并排除commons-logging依赖。 在Maven项目中,可以通过以下方式排除: ```xml <dependency> <groupId>...</groupId> <artifactId>...</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> ``` 2. 如果不知道是哪个依赖引入了commons-logging,可以使用Maven命令分析依赖树: ```bash mvn dependency:tree ``` 然后找到引入commons-logging的依赖,并排除它。 问题2:Bean Validation提供者缺失 Spring Boot的spring-boot-starter-validation已经包含了Hibernate Validator(Jakarta Bean Validation的实现)。但是,如果项目中有包含这个starter,或者版本不兼容,就会出现该问题解决方案: 1. 添加spring-boot-starter-validation依赖(适用于Spring Boot项目): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> ``` 2. 如果不想使用starter,也可以手动添加依赖: ```xml <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>7.0.1.Final</version> </dependency> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <version>3.0.1</version> </dependency> ``` 注意:Spring Boot的父POM已经管理了这些依赖的版本,所以如果有使用Spring Boot的版本管理,需要指定版本。 结合用户提供的日志,我们看到应用在启动时出现了多个错误,包括Filter启动失败和Context启动失败。这些错误可能与Bean Validation的缺失有关,因为Bean Validation可能在Filter初始化时被使用(例如,在Spring Security或Spring MVC的验证中)。 因此,我们建议先解决Bean Validation提供者缺失的问题,然后再解决日志冲突问题。因为日志冲突通常不会导致应用启动失败,但Bean Validation缺失会导致启动失败。 步骤总结: 1. 在pom.xml中添加spring-boot-starter-validation依赖(或者手动添加Hibernate Validator和Jakarta Validation API)。 2. 排除commons-logging依赖(如果存在)。 3. 清理并重新构建项目(执行`mvn clean package`),然后重新启动应用。 如果问题仍然存在,请检查依赖树,确保有其他依赖引入旧版本的Bean Validation API(例如javax.validation)或者排除了Hibernate Validator。 下面是一个完整的pom.xml示例片段(假设是Spring Boot项目): ```xml <dependencies> <!-- 其他依赖 ... --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!-- 排除其他依赖中的commons-logging --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> </dependencies> ``` 注意:Spring Boot的spring-core已经排除了commons-logging,但其他依赖可能引入,所以需要检查依赖树。 最后,如果应用启动时仍然报错,请检查日志中是否有其他错误信息,这有助于进一步诊断问题。 相关问题: 1. 如何在Spring Boot中配置Bean Validation? 2. 如何解决Spring Boot中的依赖冲突? 3. 如何查看Spring Boot应用的依赖树? 4. Spring Boot中如何使用自定义的验证器? 5. 如何排除Spring Boot中的特定依赖?</think>### 解决 Spring Boot 启动时的日志冲突与 Bean Validation 缺失问题 #### 一、解决日志冲突问题:`Standard Commons Logging discovery in action` **问题原因** Spring Boot 默认使用 `spring-jcl`(Spring 的 Commons Logging 实现),当类路径中存在 `commons-logging.jar` 时,会导致日志实现冲突。 **解决方案** 1. **检查并排除冲突依赖** 在 Maven 项目中执行依赖分析: ```bash mvn dependency:tree -Dincludes=commons-logging ``` 找到引入 `commons-logging` 的依赖,并在 `pom.xml` 中排除: ```xml <dependency> <groupId>problematic-group</groupId> <artifactId>problematic-artifact</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> ``` 2. **强制使用 Spring 的日志实现** 在 `application.properties` 中显式指定日志门面: ```properties spring.jmx.enabled=false logging.config=classpath:logback-spring.xml ``` 3. **验证修复效果** 清理并重新构建项目: ```bash mvn clean package && java -jar target/your-app.jar ``` #### 二、解决 Bean Validation 缺失问题:`NoProviderFoundException` **问题原因** Spring Boot 未检测到 Bean Validation 实现(如 Hibernate Validator)。 **解决方案** 1. **添加验证依赖** 在 `pom.xml` 中添加: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> ``` 此依赖包含: - `hibernate-validator`(Jakarta Bean Validation 实现) - `jakarta.validation-api`(验证接口) 2. **验证依赖树** 确保无版本冲突: ```bash mvn dependency:tree -Dincludes=org.hibernate.validator ``` 正常输出应包含: ``` [INFO] +- org.springframework.boot:spring-boot-starter-validation:jar:3.1.0 [INFO] | \- org.hibernate.validator:hibernate-validator:jar:8.0.0.Final ``` 3. **检查运行时类路径** 确认构建后的 JAR/WAR 中包含: ```bash unzip -l target/your-app.jar | grep hibernate-validator ``` #### 三、完整修复流程 1. **更新 `pom.xml`** ```xml <dependencies> <!-- 其他依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!-- 示例:排除 commons-logging --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> </dependencies> ``` 2. **重建并启动应用** ```bash mvn clean spring-boot:run ``` 3. **验证修复效果** - 启动日志中不再出现 `Commons Logging` 警告 - Bean Validation 功能正常(如 `@Valid` 注解生效) - 无 `NoProviderFoundException` 错误 #### 四、故障排查技巧 1. **诊断类路径冲突** ```java @SpringBootApplication public class App { public static void main(String[] args) { // 打印加载的验证提供者 System.out.println(Validation.byDefaultProvider().provider()); SpringApplication.run(App.class, args); } } ``` 2. **启用调试日志** 在 `application.properties` 中添加: ```properties logging.level.org.hibernate.validator=DEBUG logging.level.org.springframework.boot=TRACE ``` --- ### 相关问题 1. **如何在 Spring Boot 中自定义验证错误消息?** 在 `src/main/resources` 创建 `ValidationMessages.properties` 文件: ```properties user.name.notempty=用户名不能为空 ``` 在实体类中使用: ```java @NotBlank(message = "{user.name.notempty}") private String name; ``` 2. **Jakarta Bean Validation 与 Java Bean Validation 有何区别?** - **包名变更**:`javax.validation` → `jakarta.validation` - **规范升级**:Jakarta EE 9+ 支持 Java 11+ 特性 - **依赖分离**:Jakarta 版本需显式添加实现库(如 Hibernate Validator 7+) 3. **如何解决 Spring Boot 中的多日志框架冲突?** 使用 `mvn dependency:tree` 分析冲突,通过 `<exclusions>` 移除重复依赖,推荐统一使用 Logback 或 Log4j2。 4. **为什么添加了 `spring-boot-starter-validation` 仍报错?** 检查是否有依赖覆盖了版本(如手动指定旧版 Hibernate Validator),确保依赖树中版本号统一。 5. **如何验证 Bean Validation 是否生效?** 编写测试用例: ```java @SpringBootTest class ValidationTest { @Autowired Validator validator; @Test void testValidation() { User user = new User(); // 无 name 属性 Set<ConstraintViolation<User>> violations = validator.validate(user); assertFalse(violations.isEmpty()); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值