美文网首页
chapter07_SpringMVC的高级技术_4_跨重定向请

chapter07_SpringMVC的高级技术_4_跨重定向请

作者: 米都都 | 来源:发表于2019-01-15 17:41 被阅读0次
    • 处理完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_跨重定向请

          本文链接:https://www.haomeiwen.com/subject/jgnydqtx.html