In the end, it’s not the years in your life that count. It’s the life in your years.
最终,重要的不是活了多少年,而是这些年你怎么活。–林肯
重定向Redirect的原理
/*没有重定向时的跳转方法
*response.setStatus(302);
*response.setHeader("Location", "login_success.html");
*/
//重定向写法: 重新定位方向 参数即跳转的位置
response.sendRedirect("login_success.html");
处理流程
- 接受客户端的http请求
- 在接受请求的Servelet中调用sendRedirect( )方法
- 服务器发回包含3xx状态码和目标资源URL的response
- 客户端浏览器读取到3xx状态码, 再次发送新的请求到目标URL
p.s. 有关重定向3xx状态码和重定向种类请参阅MDN
请求转发RequestDispatch的原理
//请求转发的写法: 参数即跳转的位置
request.getRequestDispatcher("login_success.html").forward(request, response);
请求转发的处理流程
- 接收客户端的http请求
- 在Servlet中调用forword()方法将请求转发到另外一个URL(jsp/servlet)
- jsp/servlet处理请求, 并将响应发送给客户端(此时请求路径依然是上一个Servlet)
两者区别
生活中例子举例: 你去商店买可乐, 商店没有
- 请求转发 : 老板自己去帮你买, 买回来给你, 所以你买到可乐的地方还是在最初的地方
- 重定向 : 老板告诉你说他家没有, 叫你去别的地方买. 所以你买到可乐的地方是最后的那个地方.
重定向
1. 地址上显示的是最终的资源路径地址
http://localhost:8080/RequestRedirctionDemo/login_success.html
2. 请求次数最少有两次, 服务器在第一次请求后,会返回302 以及一个地址,浏览器再根据这个地址,执行第二次访问。
3. 可以跳转到任意路径。 不是自己的工程也可以跳。
4. 效率稍微低一点,执行两次请求。
5. 后续的请求,没法使用上一次的request存储的数据,或者没法使用上一次的request对象,因为这是两次不同的请求。
请求转发:
//请求转发的写法: 参数即跳转的位置
request.getRequestDispatcher("login_success.html").forward(request, response);
1. 地址上显示的是请求servlet的地址。 返回200 ok
http://localhost:8080/RequestRedirctionDemo/login?username=admin&password=123
2. 请求次数只有一次, 因为是服务器内部帮客户端执行了后续的工作。
3. 只能跳转自己项目的资源路径 。
4. 效率上稍微高一点,因为只执行一次请求。
5. 可以使用上一次的request对象。
转发和重定向的选择
1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。
2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。
转发和重定向的应用场景
在上面我已经提到了,转发是要比重定向快,因为重定向需要经过客户端,但是,转发没有。但是有时候,采用重定向会更好,若需要重定向到另外一个外部网站,则无法使用转发。另外,重定向还有一个应用场景:避免在用户重新加载页面时两次调用相同的动作。
例如,当提交产品表单的时候,执行保存的方法将会被调用,并执行相应的动作;这在一个真实的应用程序中,很有可能将表单中的所有产品信息加入到数据库中。但是如果在提交表单后,重新加载页面,执行保存的方法就很有可能再次被调用。同样的产品信息就将可能再次被添加,为了避免这种情况,提交表单后,你可以将用户重定向到一个不同的页面,这样的话,这个网页任意重新加载都没有副作用;但是,使用重定向的一个不便之处是,无法将值轻松地传递给目标页面。而采用转发,则可以简单地将属性添加到Model,使得目标视图可以轻松访问。由于重定向经过客户端,所以Model中的一切都会在重定向时丢失。但幸运的是,在Spring3.1版本以后,我们可以通过Flash属性,解决重定向时传值丢失的问题。