在项目开发中,经常会用到转发和重定向,它们虽然都是转向,但是二者却有着本质的区别。而且,该开始接触的时候,也不清楚到底什么时候用转发,什么时候用重定向。那到底它们有什么区别呢?又该怎么用呢?下面就一起看看吧。
转发是用RequestDispatcher的forward进行的,一般情况下代码是这样写的:
request.getRequestDispatcher("/basedata/item_modify.jsp").forward(request, response);
在一个Servlet中的代码:
request.setAttribute("itemUnitList", itemUnitList); //转发 request.getRequestDispatcher("/basedata/item_modify.jsp").forward(request, response);
List itemUnitList = (List)request.getAttribute("itemUnitList");
重定向是用response.sendRedirect方法来实现的,代码如下:
response.sendRedirect(request.getContextPath() + "/servlet/item/SearchItemServlet");
1、转发是发生在服务器端的,重定向是发生在浏览器端的。
转发是不同页面或Servlet要做同一个请求处理,也就是说浏览器向服务器发送了一个请求,服务器的一个Servlet并不能完全处理这个请求,只处理了一部分,然后会让另一个Servlet接着处理另外一部分,这时候就需要转发给另一个Servlet,并将数据通过Request对象传递过去。第二个Servlet处理完成后,就直接返回给浏览器处理结果了。它是服务器为了处理浏览器的请求进行的操作,浏览器并不知道服务器进行了转发,所以这个过程中,浏览器的URL是不变的。
而重定向就不同了,重定向是浏览器给服务器发送了一个请求,服务器对浏览器的请求给出了一个响应,告诉浏览器应该访问下一个地址了。这个时候,浏览器是应该自己再去访问另外一个URL,这时候就可以看到地址栏的URL是改变了的。重定向时,浏览器至少向服务器传递了两个请求。
2、转发的速度较快,重定向的速度较慢
转发的请求是在容器的内部进行处理的,只能讲请求转发给同一个Web应用中的组件是一次请求完成的,所以响应速度较快。
而重定向不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至重定向到其他站点的资源。而且重定向至少要两次向服务器请求,所以响应速度较慢。
3、转发的地址是相对于当前Web应用程序的根目录,重定向的地址是相对于整个Web站点的根目录
从上面的代码可以看出,在转发时,可以直接用
"/servlet/item/SearchItemServlet"
它会直接在该应用程序根目录下找该路径。
而重定向的路径需要这样写,
request.getContextPath() + "/servlet/item/SearchItemServlet"
这样才是找该应用程序下的路径。如果不写前面的
request.getContextPath()
则要从整个Web站点根目录下开始找,如果没有该路径,程序就该抛异常了。
二者的区别搞清楚了,那么什么时候用转发,什么时候用重定向呢?
当不同servlet或页面之间共享相同的request和response对象时,表明它们属于同一个请求过程,这时候就要用转发。
当不同servlet或页面之间使用各自的request和response对象,则表明它们是不同的请求过程,这时候就要用重定向。另外,如果一个Web应用程序需要调用另一个Web应用程序的资源时,就需要用到重定向。
看过的《高效能人士的七个习惯》这本书中,有一个小例子很相似。作者去外地讲课时住在一家宾馆,讲课时他忘了带笔,于是向服务员请求帮忙,服务员说“先生您稍等,我马上解决这个问题!”,这就是转发,作者并不知道他是怎么做的,但是确实解决了这个问题。如果服务员跟作者说“您可以去问一下前台”,这样就是把一个URL返回给了作者,让他去另外一个地址寻求帮助,也就是重定向。明显的重定向要比转发的效率低。这个故事虽然是在讲企业文化的,但是放在这里同样适用,可谓生活中处处是编程。