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

    本文介绍Spring MVC中转发和重定向的区别。
    

    转发和重定向

     开始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并渲染
     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    打开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";
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    打开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";
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    打开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";
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    运行如下:

    这里写图片描述

    上面示例了使用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发出取餐要求。

    返回 Java EE Web开发系列导航

  • 相关阅读:
    Flume案例
    推荐算法
    Hive安装
    打开相机
    打电话,发短信
    温度传感器,摇一摇
    经度,纬度,获取
    团队站立会议01
    团队项目计划会议
    "群英队"电梯演讲
  • 原文地址:https://www.cnblogs.com/jpfss/p/8078850.html
Copyright © 2011-2022 走看看