Spring中@ModelAttribute能否解析含Long字段或Map对象?跨控制器传参除@SessionAttributes还有什么方案?
问题根因
你之前使用redirectAttributes.addAttribute()传递对象的方式存在先天局限:该方法会将所有参数拼接为重定向URL的查询参数,放入对象时会自动调用其toString()方法转为字符串,接收端Spring MVC解析字符串时,默认会把数值范围内的数字优先转为Integer类型,遇到Long类型字段就会触发类型不匹配异常;Map实例的toString()结果更是无法被自动还原为Map结构,自然也会解析失败。
替代方案(无需使用@SessionAttributes)
方案1:使用RedirectAttributes的addFlashAttribute()方法(最推荐)
Flash属性是Spring MVC专门为重定向场景设计的临时存储机制,数据会被临时存放在Session中,重定向完成后自动清除,不会长期占用会话资源,对象的类型结构会完整保留,不存在类型转换问题。
代码示例:
POST控制器写法:
// 你的POST处理方法 public String postHandle(Entity entity, RedirectAttributes redirectAttributes) { // 用addFlashAttribute而非addAttribute redirectAttributes.addFlashAttribute("entitytopass", entity); return "redirect:/display"; }
接收端控制器写法无需改动,你原有的@ModelAttribute代码可以直接正常工作:
@RequestMapping(value ="/display", method = RequestMethod.GET) public String add(@ModelAttribute("entitytopass") Entity entityreceived, Model model) { model.addAttribute("entitypresented", entityreceived); return "/displaypage"; }
该方案同样支持传递Map实例,类型结构完全不会被破坏。
方案2:手动序列化传递(适合需要URL可复用场景)
如果你需要传递的参数可以放在URL中、支持用户复制链接复用,可以手动将对象序列化为JSON字符串传递,接收端再自行反序列化:
代码示例:
POST控制器写法:
@Autowired private ObjectMapper objectMapper; public String postHandle(Entity entity, RedirectAttributes redirectAttributes) throws JsonProcessingException { String entityJson = objectMapper.writeValueAsString(entity); redirectAttributes.addAttribute("entityJson", entityJson); return "redirect:/display"; }
接收端控制器写法:
@Autowired private ObjectMapper objectMapper; @RequestMapping(value ="/display", method = RequestMethod.GET) public String add(@RequestParam String entityJson, Model model) throws JsonProcessingException { Entity entityreceived = objectMapper.readValue(entityJson, Entity.class); model.addAttribute("entitypresented", entityreceived); return "/displaypage"; }
注意:该方案受URL最大长度限制,不适合传递字段过多、体积过大的对象,传递敏感数据时需要做加密处理。
内容的提问来源于stack exchange,提问作者Andrzej Więcławski
相关产品推荐
相关产品推荐

