Spring MVC项目提交表单到@PostMapping("/add")返回400 Bad Request问题排查
问题根因排查方向
你遇到的400错误是Spring MVC参数绑定阶段失败导致的,还没进入到你写的Controller业务方法就被拦截返回了,所以控制台没有业务报错,以下是对应你代码的核心问题点:
1. 最常见原因:表单字段和Libri实体属性不匹配
@ModelAttribute会自动把表单参数绑定到实体类,只要出现以下任意一种情况都会直接返回400:
- 表单input的
name属性和Libri的属性名大小写、拼写不一致,比如实体类字段是nomeLibro,表单写的是nomelibro - 类型转换失败:比如实体类的数值字段(int、float)、日期字段,表单提交了不符合格式的内容(比如数字字段填了中文、日期格式不是Spring默认的
yyyy/MM/dd) - 必填字段为空:如果
Libri有非空约束的字段,表单提交时传了空值
2. 模型名不匹配
你Controller里add方法用的是@ModelAttribute("datiLibri"),对应的FreeMarker表单必须明确绑定这个模型名,写法参考:
<@spring.form modelAttribute="datiLibri" action="/add" method="post"> <!-- 表单字段 --> </@spring.form>
如果表单没有绑定datiLibri这个模型名,参数无法映射就会报400。
3. 组件扫描范围不全
你AppConfig里的@ComponentScan只扫描了Biblioteca.Controller包,如果Libri实体类、LibriService不在这个包路径下,也会导致参数绑定、Bean注入失败,需要修改扫描范围:
@ComponentScan(basePackages={"Biblioteca.Controller", "Biblioteca.Service", "Biblioteca.Entity"})
同时EntityManagerFactory的setPackagesToScan也需要加上实体类所在的包,否则JPA无法识别实体:
factory.setPackagesToScan("Biblioteca.Entity");
4. CSRF校验拦截
如果你的项目集成了Spring Security,默认开启了CSRF校验,表单没有携带CSRF token的话也会直接返回400,要么在表单里加CSRF隐藏字段,要么调试阶段先关闭CSRF校验。
快速定位方法
在你的Biblioteca.properties里加上两行配置,打开Spring MVC绑定日志,直接就能看到具体是哪个字段绑定失败:
logging.level.org.springframework.web=DEBUG spring.mvc.log-resolved-exception=true
重启项目后再提交表单,控制台会打印明确的绑定错误信息,对应修改即可。
内容的提问来源于stack exchange,提问作者helloJava
相关产品推荐
相关产品推荐

