zoukankan      html  css  js  c++  java
  • Spring MVC重定向和转发

    技术交流群:233513714 

    转发和重定向

     开始Java EE时,可能会对转发(forward)和重定向(redirect)这个两个概念不清楚。本文先通过代码实例和运行结果图片感性 认识二者的区别,然后给出二者的定义。

    1、常规用法,返回一个View

    @RequestMapping(value="/testa", method=RequestMethod.GET)
    public String inputData(){
        return "testa"; //Spring框架找到对应的View并渲染
    }
    
    @RequestMapping(value="/testa", method=RequestMethod.POST)
    public String outputData(HttpServletRequest request){
        String userName = request.getParameter("name");
        String password = request.getParameter("pwd");
        request.setAttribute("name", userName);
        request.setAttribute("pwd", password);
        return "testb"; //Spring框架找到对应的View并渲染
     }

    打开testa网页:

    输入用户名:spring,密码:spring:

    这里写图片描述

    点击登陆按钮,页面变为如下:

    这里写图片描述

    再次刷新,谷歌浏览器提示重新提交表单。

    这里写图片描述

    对比图片,发现浏览器的输入框中URL不变,但是不同情况下显示不同的View。跳转时Model共享(表单会被重复提交)。

    2、转发(forward)

    @RequestMapping(value="/testa", method=RequestMethod.GET)
    public String inputData(){
        return "testa"; //Spring框架找到对应的View并渲染
    }
    
    @RequestMapping(value="/testa", method=RequestMethod.POST)
    public String outputData(HttpServletRequest request){
        String userName = request.getParameter("name");
        String password = request.getParameter("pwd");
        request.setAttribute("name", userName);
        request.setAttribute("pwd", password);
        //转发到 /testb 的Controller方法(即outputDataX)上
        return "forward:/testb"; 
    }
    
    @RequestMapping(value="/testb", method=RequestMethod.POST)
    public String outputDataX(HttpServletRequest request){
        return "testb";
    }

    打开testa网页:

    输入用户名:spring,密码:spring:

    这里写图片描述

    点击登陆按钮,页面变为如下:

    这里写图片描述

    调试分析:forward后面跟一个资源。当程序运行到return “forward:/testb”时,会执行会执行该资源对应的方法outputDataX。 
    另外转发时,浏览器的URL不变。

    再次刷新,谷歌浏览器提示重新提交表单。

    这里写图片描述

    3、重定向(redirect)

    @RequestMapping(value="/testa", method=RequestMethod.GET)
    public String inputData(){
        return "testa"; //Spring框架找到对应的View并渲染
    }
    
    @RequestMapping(value="/testa", method=RequestMethod.POST)
    public String outputData(HttpServletRequest request){
        String userName = request.getParameter("name");
        String password = request.getParameter("pwd");
        request.setAttribute("name", userName);
        request.setAttribute("pwd", password);
        //重定向到 /testb 的Controller方法(即outputDataY)上
        return "redirect:/testb"; 
    }
    
    @RequestMapping(value="/testb", method=RequestMethod.POST)
    public String outputDataX(HttpServletRequest request){
        return "testb";
    }
    
    @RequestMapping(value="/testb", method=RequestMethod.GET)
    public String outputDataY(HttpServletRequest request){
        return "testb";
    }

    打开testa网页:

    输入用户名:spring,密码:spring:

    这里写图片描述

    点击登陆按钮,页面变为如下:

    这里写图片描述

    调试分析:redirect后面跟一个资源。当执行到return “redirect:/testb”时,会执行该资源对应个方法outputDataY。由于重定向Model不共享,所以页面无数据显示。 
    另外重定向后浏览器的输入框中URL也发生变化。

    刷新后,谷歌浏览器没有提示重新提交表单

    这里写图片描述

    总结: 
    常说的可以通过redirect: URL防止重复提交表单,就是上面过程的意思。 
    原理是对于redirect而言,Request的attribute不会被传递,放到session中,session在跳到页面后马上移除对象。所以你刷新一下后这个值就会丢掉。

    如果你希望Request的attribute被传递,可以使用RedirectAttributes类。

    @RequestMapping(value="/testa", method=RequestMethod.GET)
     public String inputData(){
      return "testa"; //Spring框架找到对应的View并渲染
     }
    
     @RequestMapping(value="/testa", method=RequestMethod.POST)
     public String outputData(HttpServletRequest request, RedirectAttributes redirectAttributes){
      String userName = request.getParameter("name");
      String password = request.getParameter("pwd");
      request.setAttribute("name", userName);
      request.setAttribute("pwd", password);
      //重定向到 /testb 的Controller方法(即outputDataY)上
      //重定向传递参数的两种方法
      redirectAttributes.addAttribute("name", userName);
      redirectAttributes.addFlashAttribute("pwd", password);
    
      return "redirect:/testb"; 
     }
    
     @RequestMapping(value="/testb", method=RequestMethod.POST)
     public String outputDataX(HttpServletRequest request){
      return "testb";
     }
    
     @RequestMapping(value="/testb", method=RequestMethod.GET)
     public String outputDataY(HttpServletRequest request){
      String userName = request.getParameter("name");
      request.setAttribute("name", userName);
      return "testb";
     }
    

    运行如下:

    这里写图片描述

    上面示例了使用RedirectAttributes传递参数的两种方法: 
    1. 使用RedirectAttributes类的addAttribute方法传递参数会跟随在URL后面,如上图谷歌浏览器所示,URL为http://localhost:8080/testb?name=spring 
    2. 使用RedirectAttributes类的addFlashAttribute方法传递参数不会跟随在URL后面,会把该参数值暂时保存于session,待重定向URL获取该参数后从session中移除,这里的redirect必须是方法映射路径,jsp无效。你会发现redirect后的jsp页面中pwd只会出现一次,刷新后pwd再也不会出现了。下图为刷新后的结果,密码pwd显示为空。这验证了上面说的,pwd在被访问后就会从session中移除。对于防止重复提交可以使用此方法。

    定义

    作为一个经验丰富的servlet/JSP程序员,必须知道转发和重定向的区别。 转发比重定向快,因为重定向经过客服端,而转发没有。但是,又是采用重定向更好,若需要重定向到一个外部网站,则无法使用转发。

    个人理解:好比服务器窗口A点餐,窗口B取餐。转发就是浏览器到服务器窗口A点餐,点完餐后,服务器内部从窗口B取餐,把饭菜直接给浏览器。重定向就是浏览器到服务器窗口A点餐,服务器不帮助浏览器从窗口B取餐,而是告知浏览器到B取餐。浏览器得到信息后再向窗口B发出取餐要求。

  • 相关阅读:
    【BZOJ】1671: [Usaco2005 Dec]Knights of Ni 骑士(bfs)
    【BZOJ】1689: [Usaco2005 Open] Muddy roads 泥泞的路(贪心)
    Maven使用
    上传图片
    Model、ModelMap和ModelAndView的使用详解
    Spring MVC 基于AnnotationFormatterFactory接口实现自定义的规则
    mybatis 分页插件PageHelper的简单使用
    Mybatis 自动生成mapper文件
    Tomcat部署时war和war exploded区别以及平时踩得坑
    springMVC @response 中文乱码解决
  • 原文地址:https://www.cnblogs.com/cnndevelop/p/8351079.html
Copyright © 2011-2022 走看看