Java Spring简单POST表单提交失败,请求未达控制器求助
首先,404说明Spring找不到匹配/notes的POST端点,结合你的代码,我们从最可能的原因开始排查:
1. 控制器类漏加了核心注解
你只贴了@PostMapping("/notes")的方法,但控制器类必须加上@Controller注解(因为你返回的是视图result),否则Spring根本不会把这个类识别为控制器,自然无法映射请求。赶紧检查你的控制器类顶部是不是有:
@Controller public class NoteController { // 你的@PostMapping方法写在这里 }
如果是纯REST接口才用@RestController,但你的场景是返回视图,所以@Controller才是正确的。
2. 表单提交的路径/方法匹配问题
你的表单用了th:action="@{/notes}",这是Thymeleaf的正确写法,会自动处理应用的上下文路径,所以路径本身大概率没问题,但要确认两点:
- 表单的
method="POST"是不是写对了?控制器用的是@PostMapping,如果表单不小心写成GET,也会触发404; - 你的应用是不是部署在根路径?比如访问地址是
http://localhost:8080/而不是http://localhost:8080/xxx/,不过Thymeleaf的@{/notes}会自动加上上下文路径,所以这个问题不大。
顺便帮你揪出代码里的其他致命错误(解决404后会遇到的)
即使搞定了404,你的代码还有几个严重问题,提前修正避免踩坑:
(1)Note类的Setter方法完全写反了
看你的Setter代码:
public void setNoteid(Integer fileId) { this.noteid = noteid; } // 应该改成 this.noteid = fileId; public void setNotetitle(String filename) { this.notetitle = notetitle; } // 应该改成 this.notetitle = filename;
这种错误会导致表单提交的参数根本无法绑定到Note对象,到时候控制器拿到的note属性全是null。
(2)MyBatis的Insert语句错得离谱
你的Mapper里写的是:
@Insert("INSERT INTO CREDENTIALS (notetitle, notedescription, userid) VALUES(#{filename}, #{notetitle}, #{notedescription}, #{userid})")
- 表名错了!你的SQL表是
NOTES,不是CREDENTIALS; - 字段数不匹配:INSERT指定了3个字段,但VALUES里写了4个参数(多了个
#{filename}),正确的语句应该是:
@Insert("INSERT INTO NOTES (notetitle, notedescription, userid) VALUES(#{notetitle}, #{notedescription}, #{userid})")
另外@Options(useGeneratedKeys = true, keyProperty = "noteid")是对的,能自动把生成的主键回填到Note的noteid属性里。
(3)表单参数与Note属性的绑定不匹配
表单里的输入框name是noteTitle、noteDescription,但你的Note类属性是notetitle、notedescription(全小写)。Spring MVC默认是根据Setter方法名绑定参数,你的Setter是setNotetitle,所以请求参数名得是notetitle才能正确绑定。最简单的解决办法是把表单里的name改成和类属性一致:
<input type="text" name="notetitle" class="form-control" id="note-title" maxlength="20" required> <textarea class="form-control" name="notedescription" id="note-description" rows="5" maxlength="1000" required></textarea>
总结
优先检查控制器类有没有加@Controller注解,这是导致请求到不了控制器的最可能原因。解决完404后,再把上面提到的其他错误一一修正,你的表单就能正常工作啦!
内容的提问来源于stack exchange,提问作者Leff

