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发出取餐要求。
Spring MVC 转发和重定向的更多相关文章
- Spring mvc 转发、重定向
spring控制器最后返回一个ModelAndView(urlName),其中urNamel可以是一个视图名称,由视图解析器负责解析后将响应流写回客户端;也可以通过redirect/forward:u ...
- spring MVC 转发与重定向(传参)
return "forward:index.jsp"; //转发 return "forward:user.do?method=reg5"; //转发 ret ...
- spring MVC页面的重定向
如图,一个jsp页面跳转到下一个jsp页面通常需要上一个页面发出带有参数得请求,我们都知道spring MVC是不能直接跳页面的. 需要配置视图解析器,通过返回视图名再跳转到相应得JSP页面. 即使这 ...
- 使用Spring Mvc 转发 带着模板 父页面 之解决方法 decorators.xml
周末了,周一布置的任务还没完毕,卡在了页面跳转上,接手了一个半截的项目要进行开发,之前没有人给培训.全靠自己爬代码,所以进度比較慢.并且加上之前没实用过 Spring Mvc 开发项目.所以有点吃力, ...
- Spring MVC异常处理 和 重定向传递数据
1.异常处理介绍 Spring在web项目中,如果在请求处理时出现异常,那输出会是Servlet响应.这时异常需要以某种方式转换为响应. Spring将异常转换为响应的方式: a.特定的Spring异 ...
- spring mvc带参数重定向
http://blog.csdn.net/jackpk/article/details/19121777/ https://isudox.com/2017/02/16/spring-mvc-redir ...
- Spring MVC温故而知新 – 参数绑定、转发与重定向、异常处理、拦截器
请求参数绑定 当用户发送请求时,根据Spring MVC的请求处理流程,前端控制器会请求处理器映射器返回一个处理器,然后请求处理器适配器之心相应的处理器,此时处理器映射器会调用Spring Mvc 提 ...
- Spring MVC—模型数据,转发重定向,静态资源处理方式
Spring MVC处理模型数据 添加模型数据的方法 ModelAndView Map及Model SessionAttribute ModelAttribute Spring MVC转发和重定向 S ...
- Spring MVC 教程,快速入门,深入分析
http://elf8848.iteye.com/blog/875830/ Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门 资源下载: ...
随机推荐
- 【Struts2二】结果集(result-type)
在jsp/servlet中,结果集一般是指请求转发和重定向这两种. Struts2作为框架,提供了基于这两种的很多其它的结果集! 在struts-default.xml中定义了一些默认的结果集: ...
- Traversing a list
The most common way to traverse the elements of a list is with a for loop. The syntax is the same as ...
- POJ 3204 网络流的必须边
思路: 求一遍网络流 在残余网络上DFS 从起点DFS 从终点把边反向DFS 一个边跟起点连通 跟终点反向的边连通 ans++ 注:此题不能用tarjan 因为有边权为0的边 //By SiriusR ...
- java9新特性-4-模块化系统: Jigsaw与Modularity
1.官方Feature 200: The Modular JDK 201: Modular Source Code 220: Modular Run-Time Images 260: Encapsul ...
- ajax中Post和Get请求方式的区别?
ajax中Post和Get请求方式的区别: 1.Post传输数据时,不需要在URL中显示出来,而Get方法要在URL中显示. 2.Post传输的数据量大,可以达到2M,而Get方法由于受到URL长度的 ...
- Servlet监听器及在线用户
Servlet中的监听器分为三种类型Ⅰ 监听ServletContext.Request.Session作用域的创建和销毁 (1)ServletContextListener (2)HttpSessi ...
- uname---用于打印当前系统相关信息
uname命令用于打印当前系统相关信息(内核版本号.硬件架构.主机名称和操作系统类型等). 语法 uname(选项) 选项 -a或--all:显示全部的信息: -m或--machine:显示电脑类型: ...
- 一:1.1 python程序与数据储存【进制转换】
二进制 :0 1 [逢二进一]0+0=00+1=11+1=1011+1=100 1 1+ 1------ 100 八进制: 0 1 2 3 4 5 6 7 [逢八进一] 1+7=101+2=3 十进制 ...
- centos7 安装rsyslog
http://blog.csdn.net/u011630575/article/details/50896781 http://blog.chinaunix.net/uid-21142030-id-5 ...
- 阿里云主机centos设置虚拟内存
http://blog.csdn.net/luwei42768/article/details/51241758 https://my.oschina.net/u/2306127/blog/65726 ...