请求转发与重定向示意图:
- 请求转发是服务器端跳转,它只产生一次请求,客户端请求到达服务器之后中会发生一次转发,之后服务器才将结果发送到客户端。
- 重定向是客户端跳转,它会产生两次请求,首先发一个response到浏览器,浏览器收到这个response后再发一个requeset到服务器,服务器接收后发新的response给浏览器。
- 当使用重定向时,浏览器中所显示的URL会变成新资源的URL。因为浏览器还得发出一个新的请求,所以重定向的速度比转发慢。同时,由于重定向方式产生了一个新的请求,所以经过一次重定向后,原request内的信息将无法使用。
请求转发与重定向的标准代码:
- 请求转发
request.getRequestDispatcher("/WEB-INF/manage/index.jsp").forward(request, response);
- 重定向:
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()+ ":" + request.getServerPort() + path + "/";
url = basePath+"loginFailed.jsp";
response.sendRedirect(url);
重定向与转发的区别:
-
转发时客户端浏览器请求一次服务器;而重定向需要客户端请求两次服务器。
-
重定向时不管第一次请求时的方式是什么,第二次请求时方式都是GET;而转发时,两次的方式是一样的。
-
当请求WEB-INF目录中的资源时,只能使用请求转发而不能使用重定向。
-
重定向是无法传递数据的,要想传内容或者参数只能在url路径后面添加参数例如:url地址?参数名称=参数值;
response.sendRedirect(“url地址?参数名称=参数值”) -
请求转发结束后,浏览器地址栏保持初始的URL地址不变;而调用重定向访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向到的目标URL。
-
请求转发的整个请求跳转过程是在服务器端实现的,客户端并不知道,即:请求转发在服务器端将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为;而重定向是对浏览器的请求直接做出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求。
-
RequestDispatcher.forward()方法的调用者与被调用者之间共享request对象和response对象,它们属于同一个请求和响应的过程;而HttpServletResponse.sendRedirect()方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的请求和响应的过程。
-
RequestDispatcher.forward()只能将请求转发给同一个WEB应用中的其它资源;而HttpServletResponse.sendRedirect()还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
-
如果创建RequestDispatcher对象时指定参数URL以"/“开头,它是相对于当前WEB应用程序的根目录。如果传递给HttpServletResponse.sendRedirect()方法的URL以”/“开头,它是相对于整个Servlet容器的根目录,而不是相对于当前WEB应用程序的根;如果不是以”/"开头,则是相对于当前请求uri的路径,比如:
- response.sendRedirect(“/result.jsp”); 会被解析为:http://localhost:8080/result.jsp。
- 页面http://localhost:8080/sth/sth.jsp中response.sendRedirect(“result.jsp”);会被解析为:http://localhost:8080/
sth/result.jsp。
-
转发地址栏不变,重定向地址改变。
-
转发可以携带request对象到目标资源,重定向未携带request对象。
-
转发浏览器发送一次,重定向浏览器发送两次请求
-
转发可以访问WEB-INF下资源,重定向不能直接访问WEB-INF下资源
- WEB-INF属于服务器私有目录【服务器内部可以访问,浏览器不能直接访问】
请求转发与重定向的选择:
- 优先选择请求转发,因为转发效率更高;
- 由于在转发之后,浏览器中URL仍然指向开始页面,此时如果重载(刷新)当前页面,开始页面将会被重新调用。如果不想看到这样的情况,则选择重定向。
- 在同一Web应用程序的两个请求间传递数据时,在转发与重定向之间,只能通过转发实现。
- 如果需要跳转到其它服务器上的资源,则必须使用重定向。