Spring MVC表单空输入校验失效:BindingResult.hasErrors始终返回false
嘿,我之前也遇到过一模一样的问题!明明加了校验注解,提交空表单就是不触发错误,直接跳确认页,太闹心了。结合你的代码和环境,给你梳理几个最可能的原因和解决办法:
先看你的代码片段(方便对照)
customer-form.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> //... <form:form action="processForm" modelAttribute="customer"> First name: <form:input path="firstName" /> <br><br> Last name (*): <form:input path="lastName" /> <form:errors path="lastName" cssClass="error" /> <br><br> <input type="submit" value="Submit" /> </form:form>
CustomerController.java
@RequestMapping("/processForm") public String processForm( @ModelAttribute("customer") @Valid Customer theCustomer, BindingResult theBindingResult) { if (theBindingResult.hasErrors()) return "customer-form"; return "customer-confirmation"; } @RequestMapping("/showForm") public String showForm(Model theModel) { theModel.addAttribute("customer", new Customer()); return "customer-form"; }
Customer.java
@Size(min=1, message="is required") @NotEmpty private String lastName;
重点排查这几个地方!
1. 注解重复+包导错了?
你给lastName同时加了@Size(min=1)和@NotEmpty,其实这俩功能重叠了——@NotEmpty已经能判断字符串不为空且长度大于0,再加@Size有点多余,不过这不是核心问题。
关键是:你用的@NotEmpty是不是javax.validation.constraints.NotEmpty? 很多人会不小心导入Hibernate自己的或者其他包的注解,那肯定不生效!一定要确保是JSR-380标准的注解(也就是javax.validation.constraints下的)。
2. Spring MVC没开启校验配置!
这是最容易漏掉的一步!Spring MVC默认不会自动启用校验,你得在配置里手动指定校验器:
如果是XML配置:
<!-- 配置Hibernate Validator作为校验器 --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/> </bean> <!-- 开启MVC注解驱动,并绑定校验器 --> <mvc:annotation-driven validator="validator"/>
如果是Java配置:
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public Validator getValidator() { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setProviderClass(HibernateValidator.class); return validator; } }
讲师的代码大概率已经配置过这个了,你可能没注意到,赶紧补上!
3. 依赖不全,缺了API包!
Hibernate Validator是JSR-380的实现,你得同时引入javax.validation-api(比如2.0.1.Final版本),不然光有实现没有API,校验逻辑根本跑不起来。检查你的依赖,确保这俩都在:
hibernate-validator:6.1.3.Finaljavax.validation-api:2.0.1.Final
4. Tomcat类加载冲突?
Tomcat 9的lib目录里可能自带了旧版本的validation相关jar,和你项目里的依赖冲突了。去Tomcat的lib下看看有没有javax.validation-api*.jar或者hibernate-validator*.jar,有的话删掉,让项目用自己引入的版本。
5. 再确认下BindingResult的位置
这个你做对了!BindingResult必须紧跟在@Valid注解的参数后面,不然Spring没法把错误信息绑定进去,你的代码顺序没问题,这个可以排除。
最后总结下排查顺序
- 先把
@Size(min=1)删掉,只保留@NotEmpty,并确认注解包是javax.validation.constraints - 检查Spring配置里有没有开启校验器的配置
- 确认依赖里
javax.validation-api和hibernate-validator都齐全 - 排查Tomcat的jar冲突
按照这个顺序来,应该能解决问题!
内容的提问来源于stack exchange,提问作者swimmingsprite

