Spring整合Thymeleaf表单提交时Setter方法未触发问题求助
根本原因
- 表单数据绑定逻辑缺失:Spring MVC默认仅会对标注了
@ModelAttribute的方法参数,或通过@SessionAttributes声明的会话级模型属性执行表单参数自动绑定。你原Post方法中仅手动将注入的user对象放入Model,没有告知Spring需要将本次POST提交的表单参数绑定到该实例上,因此不会触发Setter执行。 - Getter/Setter命名不符合JavaBean规范:
user类中的属性为newEntry,按照JavaBean规范,对应的Setter方法命名应为setNewEntry(属性名首字母大写)、Getter为getNewEntry,你编写的setnewEntry/getnewEntry不符合标准命名规则,Spring的属性访问器解析逻辑无法匹配到对应方法,即便触发绑定也会失败。 - 方法参数默认实例化逻辑:你在控制器方法参数中直接声明
user user时Spring会新建对象,是因为默认情况下如果没有@ModelAttribute或@SessionAttributes关联已有实例,Spring会直接实例化一个新的对象接收参数,不会复用你注入的session域代理对象。
规范解决方案
方案1:调整后直接复用会话域User对象绑定
- 首先修正
user类的Getter/Setter命名,符合JavaBean规范:
// 修正后的getter public String getNewEntry() { System.out.println("GETTER METHOD"); return newEntry; } // 修正后的setter public void setNewEntry(String i) { System.out.println("SETTER METHOD i = " + i); newEntry = i; }
同时建议将类名从小写user、entry改为首字母大写的User、Entry,符合Java编码规范,避免框架解析异常。
2. 在Post方法参数中添加@ModelAttribute绑定已有会话域对象:
@PostMapping("/blog") public String blog(@ModelAttribute("user") user user, Model model){ user.insertentry(); model.addAttribute("entry", entrycount); entrycount.inc(); return "blogform"; }
因为你的user本身是session域的代理Bean,这里@ModelAttribute会直接拿到你注入的实例执行绑定,不会新建对象,可正常触发Setter。
方案2(更推荐的分层规范方案)
你目前使用EntryReceiver作为DTO接收表单参数的方案本身就是更规范的做法:
- 避免直接将会话域的业务对象暴露给前端绑定,防止恶意用户构造额外参数篡改会话对象的其他属性,安全性更高。
- 表单接收DTO和业务域对象职责分离,后续表单字段调整不会影响会话域对象的结构,可维护性更好。
仅需要保留现有逻辑,同时修正User类的Getter/Setter命名即可。
内容的提问来源于stack exchange,提问作者Maciej Wojdyła
相关产品推荐
相关产品推荐

