技术交流群: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发出取餐要求。

Spring MVC重定向和转发的更多相关文章

  1. Spring MVC重定向和转发以及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  2. Spring MVC重定向和转发及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  3. spring mvc 重定向加传参

    常用: ModelAndViewi: return new ModelAndView("redirect:/toList");  或者 ii:return "redire ...

  4. spring mvc重定向

    spring mvc重定向有三种方法. 1.return new ModelAndView("redirect:/toUrl"); 其中/toUrlt是你要重定向的url. 2.r ...

  5. Spring MVC 的视图转发

    Spring MVC 默认采用的是转发来定位视图,如果要使用重定向,可以如下操作 1.使用RedirectView public ModelAndView login(){ RedirectView ...

  6. spring mvc重定向方法

    一.不带参数,直接重定向到另一个地址: 返回String直接跳转,如: @RequestMapping(value = "/filehandle") public String u ...

  7. spring mvc 重定向问题

    (1)我在后台一个controller跳转到另一个controller,为什么有这种需求呢,是这样的.我有一个列表页面,然后我会进行新增操作,新增在后台完成之后我要跳转到列表页面,不需要传递参数,列表 ...

  8. spring mvc重定向页面

    @RequestMapping(value="/del/{id}") public String delUser(@PathVariable int id){ return &qu ...

  9. spring mvc重定向问题

    在页面提交时中,路径应该使用“/默认上下文/controller路径”,在controller重定向中,应该使用“/controller路径”,不加上下文.

随机推荐

  1. java:Java环境配置

    1.安装JDK开发环境 下载网站:http://www.oracle.com/ 2.配置环境变量: 对于Java程序开发而言,主要会使用JDK的两个命令:javac.exe.java.exe.路径:C ...

  2. 关于ubuntu安装软件的问题:apt-get和dpkg区别?

    两者的区别是dpkg绕过apt包管理数据库对软件包进行操作,所以你用dpkg安装过的软件包用apt可以再安装一遍,系统不知道之前安装过了,将会覆盖之前dpkg的安装.1.dpkg是用来安装.deb文件 ...

  3. 音乐代码 (DNF天空之城、欢乐颂)。

    太感人了 DNF天空之城 #include <cstdio> #include <windows.h> #define qdo 262 #define qre 294 #def ...

  4. 关于硬盘分区使用exFat格式的优势及劣势(含摘抄)

    优势 可以设置最大32M的簇: 不记录日志. 劣势 无法使用windows的“文件共享”: 通过近期某个文件数量密级任务的测试发现,在大量文件的处理性能上,NTFS比exFAT文件系统的性能高出不少. ...

  5. 【js基础修炼之路】- 微任务,宏任务和Event-Loop

    一段代码让你了解Event-Loop console.log(1); setTimeout(() => { console.log(2); }, 0); new Promise((resolve ...

  6. BZOJ 4502: 串 AC自动机

    4502: 串 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 195  Solved: 95[Submit][Status][Discuss] Des ...

  7. STM32-开发环境搭建-STM32CubeMX-安装及配置

    STM32CubeMX系列教程之1.流水灯 刚刚接触到STM32CubeMX软件,感觉挺有意思,动动鼠标使STM32开发变得简单,特写文与大家分享.但具体性能如何还需测试. 硬件开发中的流水灯相当于软 ...

  8. cesium 动态水面效果

    后续继续更新

  9. 修改Windows下的Memcached下的服务端口

    在命令模式下,可以使用 memcached -p 12000 去指定端口,可服务安装后,却总是只有 -d runservice 的参数. 通过修改注册表来达到这个修改端口的目的. 在 HKEY_LOC ...

  10. [转载]Memcached缓存服务的简单安装

    1.Linux下的安装方法 下载:wget http://memcached.org/latest tar -zxvf memcached-1.x.x.tar.gz cd memcached-1.x. ...