重定向 / 转发
在JAVA中进行资源跳转,或者是页面跳转,从本质上来讲,有两种方式:重定向 , 转发
这两者都可以使页面进行跳转,但是两者之间有不同的区别
其中 SendRedirect,setHeader 属于重定向方式,而 forward 属于转发方式
重定向(sendRedirect,setHeader)
1.重定向到指定URL,是客户端跳转
2.地址栏中的地址将会改变,变成重定向的地址
3.调用者和被调用者处于两次不同的请求。不能通过request域对象来共享数据,
如果需要传递参数,需要在 url 后加参数,如 url?id=2,或者使用ServletContext 存放全局数据,不能通过request和response方式
4.使用重定向方式可以重定向到任意 URL
response.sendRedirect(url);
response.sendRedirect( "/uu ");表示相对于服务器根路径
url 可以使用相对路径,也可以使用绝对路径
//需要设置状态码 302(found),重新定位
response.setStatus(302);
response.setHeader("Location","url");
重定向的详细过程:
Redirect 会发送一个 response(响应)给浏览器,当浏览器接收到 response 后,再发送一个request(请求)给服务器,服务器接收到后,会发送新的 response 给浏览器,而这时候,页面接收到的是从浏览器取来的新的request。
那么,在跳转之前的页面所存放在request.setAttribute中的东西就没了,如果在新页面中使用request.getAttribute 获取以前存放的元素,将会得到null。
所以在传递参数时,不能使用request和response方式。
浏览器和服务器两次请求响应。
转发(forward)
1.请求转发到指定URL
2.是服务器端跳转
3.地址栏中的网址保持不变
4.只能重定向到同一个Web应用程序中的某个资源
无法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同时forward()无法在后面带参数传递,比如servlet?name=frank
可以通过response.setAttribute("name",name)来传至下一个页面
5.采用请求转发方式,在跳转页面的时候是带着原来页面的request和response跳转的,request对象始终存在,所以可以使用域对象传递参数。
request.getRequestDispatcher(“url”).forward(request,response);
转发的详细过程:
forward() 过程 发生在服务器端, 客户端浏览器只发出一次请求,在服务器端,Servlet将用户的请求连同请求信息等内容转发给Servlet、HTML、JSP或其它信息资源,由第2个信息资源响应该请求,两个信息资源共享同一个request对象,参数自动传递。
浏览器和服务器一次请求响应。
总结
setHeader() 的其他几种使用方式
一秒刷新页面一次:response.setHeader("refresh","1");
二秒跳到其他页面:response.setHeader("refresh","2;URL=otherPagename");
没有缓存:response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
forward方法只有一次的浏览器服务器请求,只有一个Request和Response,所以调用者与被调用者之间共享Request和Response
sendRedirect方法由于两次浏览器服务器请求,所以有两个Request和Response。
如果使用 request.setAttribute 传递一些属性就需要用forward,如果想要跳转到别的应用的资源,就需要用 sendRedirect,setHeader。
PS:无论是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