HTTP协议规定了一种重定向机制,重定向的运作流程如下:
(1) 用户在浏览器端输入特定URL,请求访问服务器端的某个组件。
(2) 服务器端的组件返回一个状态代码为302的响应结果,该响应结果的含义为:让浏览器再请求访问另一个web组件。在响应结果中提供了另一个web组件的URL。另一个web组件有可能在同一个web服务器上,也有可能不在同一个web服务器上。
(3) 当浏览器接收到这种响应结果后,再立即自动请求访问另一个web组件。
(4) 浏览器端接收到来自另一个web组件的响应结果。
在Servlet API中,HttpServletResponse接口的sendRedirect(String location)方法用于重定向。
Check1Servlet重定向到Output1Servlet,两个Servlet的源代码如下:
public class Check1Servlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter pw=response.getWriter();
String username=request.getParameter("username");
String message=null;
if(username==null){
message="please input username";
}else{
message="Hello,"+message;
}
request.setAttribute("msg",message);
pw.println("Output from Check1Servlet before redirecting. ");
System.out.println("Output from Check1Servlet before redirecting. ");
response.sendRedirect("/web02_demo/output1?msg="+message);
pw.println("Output from Check1Servlet after redirecting.");
System.out.println("Output from Check1Servlet after redirecting.");
}
}
public class Output1Servlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String message=(String)request.getAttribute("msg");
System.out.println("请求范围内的消息:"+message);
message=request.getParameter("msg");
System.out.println("请求参数中的消息:"+message);
PrintWriter pw=response.getWriter();
pw.println(message);
pw.close();
}
}
response.sendRedirect(String location)方法具有以下特点:
1. Servlet源组件生成的响应结果不会被发送到客户端。response.sendRedirect(String location)方法一律返回状态代码为302的响应结果,浏览器端接收到这种响应结果后,再立即自动请求访问重定向的目标web组件,客户端最后接收到的是目标web组件的响应结果。
2. 如果源组件在进行重定向之前,已经提交了响应结果,例如调用ServletResponse的flushBuffer()方法或者调用与ServletResponse关联的输出流的close()方法,那么sendRedirect()方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果
3. 在Servlet源组件中调用response.sendRedirect()方法之后的代码块也会被执行。
4. 源组件和目标组件不共享同一个ServletRequest对象,因此不共享请求范围内的共享数据
5. 对于response.sendRedirect(String location)方法中的参数location,如果以“/”开头,表示相对于当前服务器根路径的URL,如果以“http://”开头,表示一个完整的URL。
6. 目标组件不必是同一个服务器上的同一个web应用中的组件,它可以是Internet上的任意一个有效的网页。
在web.xml中,为Check1Servlet映射的URL为“/check1”,为Output1Servlet映射的URL为“/output1”。
在浏览器地址栏输入:http://localhost:8080/web02_demo/check1,敲回车
返回:please input username.
同时观察IDE的控制台,打印输出:
由此可见,在Servlet源组件中调用response.sendRedirect()方法之后的代码也会被执行。