Spring MVC中Model添加带初始值对象后Post接口接收属性为null如何解决
问题解答
1. 能否直接通过Model属性在Post接口获取预设值?
不能。原因如下:
HTTP协议本身是无状态的,@GetMapping接口中存入Model的属性仅在当前GET请求的视图渲染生命周期内有效,视图渲染完成后该请求上下文就会被销毁。你后续提交表单触发的是全新的POST请求,Spring MVC会为processUser接口的User参数创建一个全新的空对象,仅绑定表单中提交的字段值,你表单里没有提交age字段,所以该属性默认就是null。
2. 可行解决方案
你可以根据业务场景选择以下任意一种方案:
方案1:表单添加隐藏域(最简单,适合age字段不敏感、无需防篡改的场景)
直接在Thymeleaf表单中添加age对应的隐藏输入框,提交表单时会自动携带预设的age值:<form th:action="@{/process_user}" th:object="${user}" method="post"> <input type="hidden" th:field="*{age}" /> <input type="text" th:field="*{name}" class="form-control" required /> <button type="submit" class="btn btn-primary">someAction</button> </form>无需修改后端代码,提交后
processUser接口就能正常拿到age属性。方案2:使用
@SessionAttributes存到会话(适合敏感字段、避免前端篡改的场景)
在你当前的Controller类上添加@SessionAttributes注解,指定将user对象存入会话,POST接口绑定参数时会优先从会话中取出预设的user对象,再绑定表单提交的字段:// Controller类上添加注解 @Controller @SessionAttributes("user") public class UserController { @GetMapping("/") public String index(Model model) { User user = new User(); user.setAge(25); model.addAttribute("user", user); return "index"; } // 参数前添加@ModelAttribute注解绑定会话中的user对象 @PostMapping("/process_user") public String processUser(@ModelAttribute("user") User user, SessionStatus sessionStatus) { userService.someService(user); // 业务处理完成后清除会话中的user,避免冗余数据占用会话空间 sessionStatus.setComplete(); return "index"; } }这种方案不需要前端加隐藏字段,字段不会暴露到前端,能避免被恶意篡改。
方案3:从持久层/上下文重新查询(适合user是持久化存储的业务对象场景)
如果这个user的age是存储在数据库、或者是登录用户的固有属性,可以直接在processUser接口中通过用户ID从数据库/安全上下文中查询完整的user信息,再补全表单提交的name字段即可,安全性最高。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

