HttpServletResponse.sendRedirect与RequestDispatcher.forward方法都可以实现获取相应URL资源。
sendRedirect实现请求重定向,forward实现的是请求转发。
在web服务器内部的处理机制也是不一样的。
1 .forward方法只能转发给同一个web站点的资源,而sendRedirect方法还可以定位到同一个web站点的其他应用,甚至可以通过传入绝对路径定位到别的web站点,这事forward的方法所不能比拟的优势。
可以看到这两种方法的用法,如果传给RequestDispatcher 的参数以"/"开头,则访问的是当前web应用的根目录
加入当前web的根目录是myweb。如果传给sendRedirect方法以"/"开头,访问的是整个web站点的根目录。
- RequestDispatcher rd = request.getRequestDispatcher("/index.jsp" );
- rd.forward(request, response);
- response.sendRedirect("/index.jsp" );
2 .forward重定向后,浏览器url地址不变,sendRedirect转发后,浏览器url地址变为目的url地址。
3. 使用forward重定向的过程,是浏览器先向目的Servlet发送一次Request请求,然后再服务器端由Servlet再将请求发送到目的url,再由服务器端Servlet返回Response到浏览器端。浏览器和服务器一次请求响应。
使用sendRedirect转发的过程,浏览器先向目的Servlet发送一次请求,Servlet看到sendRedirect将目的url返回到浏览器,浏览器再去请求目的url,目的url再返回response到浏览器。浏览器和服务器两次请求响应。
4 . forward方法的调用者与被调用者之间共享Request和Response
sendRedirect方法由于两次浏览器服务器请求,所以有两个Request和Response。
如果使用request.setAttribute传递一些属性就需要用forward,如果想要跳转到别的应用的资源,就需要用sendRedirect。
5 .无论是forward方法还是sendRedirect方法调用前面都不能有PrintWriter输出到客户端。
forward方法报错: java.lang.IllegalStateException: Cannot forward after response has been committed
sendRedirect报错:java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:435)
以上摘自http://liuqiang5151.iteye.com/blog/653727
在Java Web 开发中,经常会用到跳转页面的方法,一般有下面两种方法。
- HttpServletResponse response = new HttpServletResponse();
- response.sendRedirect(location)
- RequestDispatcher rd = new RequestDispatcher();
- rd.forward(request, response)
- 跳转方式
http://localhost:8080/Test 应用
运用forward 方法只能重定向到同一个Web 应用程序中的一个资源。而sendRedirect 方法可以让你重定向到任何URL 。
表单form 的action= "/uu ";sendRedirect( "/uu "); 表示相对于服务器根路径。如http://localhost:8080/Test 应用(则提交至http://localhost:8080/uu );
Forward 代码中的 "/uu " 则代表相对与WEB 应用的路径。如http://localhost:8080/Test 应用(则提交至http://localhost:8080/Test/uu ); - (运用RequestDispatcher 接口的Forward )方法
forward() 无法重定向至有frame 的jsp 文件, 可以重定向至有frame 的html 文件,
同时forward() 无法在后面带参数传递, 比如servlet?name=frank, 这样不行, 可以程序内通过response.setAttribute( "name ",name) 来传至下一个页面.
重定向后浏览器地址栏URL 不变.
只有在客户端没有输出时才可以调用forward 方法。如果当前页面的缓冲区(buffer )不是空的,那么你在调用forward 方法前必须先清空缓冲区。
"/ " 代表相对与web 应用路径
RequestDispatcher rd = request.getRequestDispatcher( "/ooo ");
rd.forward(request, response); 提交至http://localhost:8080/Test/ooo
RequestDispatcher rd = getServletContext().getRequestDispatcher( "/ooo ");
rd.forward(request, response); 提交至http://localhost:8080/Test/ooo
RequestDispatcher rd =getServletContext().getNamedDispatcher( "TestServlet "); (TestServlet 为一个 <servlet-name> )
rd.forward(request, response); 提交至名为TestServlet 的servlet
如果在 <jsp:forward> 之前有很多输出, 前面的输出已使缓冲区满, 将自动输出到客户端, 那么该语句将不起作用, 这一点应该特别注意。
另外要注意:它不能改变浏览器地址,刷新的话会导致重复提交
从http://localhost:8080/Test/gw/page.jsp 中转发
<jsp:forward page= "OtherPage.jsp "/> 在JSP 页面被解析后转换成pageContext.forward( "OtherPage.jsp ");
"/OtherPage.jsp " 提交到http://localhost:8080/Test/OtherPage.jsp
"OtherPage.jsp " 提交到http://localhost:8080/Test/gw/OtherPage.jsp
( 运用HttpServletResponse 接口的sendRedirect )方法302
是在用户的浏览器端工作,sendRedirect() 可以带参数传递, 比如servlet?name=frank 传至下个页面,
同时它可以重定向至不同的主机上,sendRedirect() 可以重定向有frame. 的jsp 文件.
假设转发代码包含于注册的servlet -url 为/ggg/tt;jsp 为/ggg/tt.jsp:
绝对路径:response.sendRedirect( "http://www.brainysoftware.com ") 发送至http://www.brainysoftware.com
根路径:response.sendRedirect( "/ooo ") 发送至http://localhost:8080/ooo
相对路径:response.sendRedirect( "ooo ") 发送至http://localhost:8080/Test/ggg/ooo,
sendRedirect 等同于此方式
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
String newLocn = "/newpath/jsa.jsp ";
response.setHeader( "Location ",newLocn);
(Meta Refresh) 方法200
这种方法是由HTML 提供的,Meta 本身就是HTML 标签。使用方法是: <meta http-equiv= "refresh " content= "5; url=http://www.dreamdu.com/ " />
相应的java 代码
String content=stayTime+ ";URL= "+URL;
response.setHeader( "REFRESH ",content); - 使用response.sendRedirect() 地址栏将改变
使用request.getRequestDispatcher().forward(request,response) 地址栏中的信息保持不变 - request.setAttribute 存的东西
只用通过方法2 跳转 才能在新页取出来 - redirect 会首先发一个response 给浏览器, 然后浏览器收到这个response 后再发一个requeset 给服务器, 然后服务器发新的response 给浏览器. 这时页面收到的request 是一个新从浏览器发来的.
forward 发生在服务器内部, 在浏览器完全不知情的情况下发给了浏览器另外一个页面的response. 这时页面收到的request 不是从浏览器直接发来了, 可能己经放了数据.
所以:
request.setAttribute 存的东西
只用通过方法2 跳转 才能在新页取出来