处理完Post请求后,一般要进行重定向。防止因为浏览器刷新或回退时重新执行Post请求
使用转发forward时,由于控制器方法和视图处理的是同一个request,所以转发的过程中,request的属性得以保存
控制器方法中的Model对象最终是以请求参数的形式复制到请求中的,因此发生重定向时,不能用Model传递数据
-
常用的跨重定向传递数据的方式有2种
(1) 通过URL模板以路径变量和/或查询参数的形式传递数据(简单,数据少的情况)
(2) 通过Spring的flash属性传递数据
-
通过URL模板进行重定向数据传输
(1) 之前采取的方法是 return ("redirect:/spitter/" + spitter.getUserName());
这样做的危险支出在于userName中的不安全字符不会进行转义,造成不安全的情况
(2) 示例
@Controller @RequestMapping("/spitter") public class SpitterController { ... @RequestMapping(value = "/register", method = POST) public String processRegistration(Spitter spitter, Model model) { spitterRepository.save(spitter); model.addAttribute("username", spitter.getUserName()); model.addAttribute("spitterId", spitter.getId()); return "redirect:/spitter/{username}"; } ... }
首先在模型Model中添加两个属性 username和spitterId。其中,username作为占位符填充到了URL模板中,而不是直接进行字符串连接,这样username中的所有不安全字符都会进行转义,然后附加到路径上;
spitterId属性没有匹配重定向URL中的任何占位符,它会自动以查询参数的形式附加到重定向URL上;
所以,如果 username="bochen", spitterId="1",那么重定向的URL地址为 "/spitter/bochen?spitterId=1"
-
通过flash属性进行重定向数据传输
(1) URL模板的方式只能传递简单的字符串,不能传递对象
(2) 能够长期存在的是 session,并且可以跨多个请求。所以我们应该在重定向前把对象放入session,重定向后从session取出对象,然后将session清理掉
(3) spring的flash属性的底层原理同(2),但是它帮我们做好了这些工作,flash属性会自动一直携带数据一直到下一次请求然后消失。具体地,重定向前,所有的flash属性都会复制到session中;重定向后,flash属性被取出,并从会话转移到模型Model中,这就和获取其他的Model对象一样了
(4) 示例
@Controller @RequestMapping("/spitter") public class SpitterController { ... @RequestMapping(value = "/register", method = POST) public String processRegistration( @RequestPart(value = "profilePicture") MultipartFile profilePicture, @Valid Spitter spitter, Errors errors, RedirectAttributes redirectAttributes) throws IllegalStateException, IOException { if (errors.hasErrors()) { return "registerForm"; } spitterRepository.save(spitter); profilePicture.transferTo(new File("/" + spitter.getUsername() + ".png")); redirectAttributes.addAttribute("username", spitter.getUsername()); redirectAttributes.addFlashAttribute("spitter", spitter); return "redirect:/spitter/{username}"; } @RequestMapping(value = "/{username}", method = GET) public String showSpitterProfile(@PathVariable String username, Model model) { if (!model.containsAttribute("spitter")) { model.addAttribute(spitterRepository.findByUsername(username)); } return "profile"; } ... }
RedirectAttribute接口扩展了Model接口,增加了几个关于flash的方法。它可以像Model一样addAttribute(),这和URL模板传递数据方式一样;addFlashAttribute()方法可以传递数据到session中,实现跨重定向数据传输;
当重定向到 /spitter/{username} 时,会被控制器的showSpitterProfile()处理。此时这个方法会读到路径变量username;同时重定向后,由于flash属性已经被取出,并且从会话转移到了Model,所以model对象也可以读到key为"spitter"的对象,这样就无需重新从数据库中再次查找了,直接交给profile视图渲染
chapter07_SpringMVC的高级技术_4_跨重定向请求传递数据
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 本章主要内容: 备用的Spring MVC配置项 处理文件上传 控制器中的异常处理 使用flash属性 “等等,客...
- 1. 接收请求参数 1.1. 【不推荐】通过HttpServletRequest 在处理请求的方法中,添加Http...
- 接受请求的输入在SpringMVC中一共有3种方式(1) 查询参数(2) 路径参数(3) 表单参数 处理查询参数(...
- 2.2 处理 multipart 请求 配置好了对multipart请求的处理后需要在控制器编写相关方法接受上传文...