• 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并渲染
    }

    打开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发出取餐要求。

    返回 Java EE Web开发系列导航

    本文介绍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并渲染
    }

    打开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发出取餐要求。

    返回 Java EE Web开发系列导航

  • 相关阅读:
    牛客网 哈尔滨理工大学第七届程序设计竞赛决赛(网络赛-低年级组)求最大值
    HDU 5024 Wang Xifeng's Little Plot(DFS)
    java正则表达式
    48.自用qss
    47.使用帧缓存对象生成叠加
    46.Qt 使用OpenGL绘制立方体
    45.Qt openGL实现三维绘图
    44.Qt通过子类化qstyle实现自定义外观
    43.qt通过qss自定义外观
    42.写入XML
  • 原文地址:https://www.cnblogs.com/jpfss/p/8796509.html
Copyright © 2020-2023  润新知