HTTP协议规定了一种重定向机制:
在Java Servlet API中,HttpServeltResponse接口的sendRedirect(String location)方法用于重定向,而在ServletResponse接口中没有这个方法,因为重定向机制是由HTTP协议规定的。
javax.servlet.http public interface HttpServletResponse extends ServletResponse{ void sendRedirect(String location) Sends a temporary redirect response to the client using the specified redirect location URL and clears the buffer }
示例:
创建一个源组件,在其中将请求转发给另一个组件:
package com.gof.test.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; public class RedirectSourceServlet extends HttpServlet { /** * */ private static final long serialVersionUID = -729582654304035822L; protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ PrintWriter out = resp.getWriter(); // try to get the parameter form request String username = req.getParameter("username"); String message = null; if (username == null){ message = "Please input username."; }else{ message = "Hello, " + username; } // try to add an attribute into the request req.setAttribute("msg", message); out.println("Output from RedirectSourceServlet before redirecting."); // print to console System.out.println("Output from RedirectSourceServlet before redirecting."); // redirect //resp.sendRedirect("/base-webapp/redirectdest?msg=" + message); resp.sendRedirect("redirectdest?msg=" + message); out.println("Output from RedirectSourceServlet after redirecting."); // print to console System.out.println("Output from RedirectSourceServlet after redirecting."); } }
目标组件为:
package com.gof.test.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; public class RedirectDestinationServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ String message = (String)req.getAttribute("msg"); System.out.println("The attribute added by Source Sevelt is " + message); message = req.getParameter("msg"); PrintWriter out = resp.getWriter(); out.println(message); out.close(); } }
在web.xml中注册:
<!-- Redirect request --> <!-- test url = http://localhost:8080/base-webapp/redirectsrc?username=New User --> <servlet> <servlet-name>redirectsrc</servlet-name> <servlet-class>com.gof.test.servlet.RedirectSourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>redirectsrc</servlet-name> <url-pattern>/redirectsrc</url-pattern> </servlet-mapping> <servlet> <servlet-name>redirectdest</servlet-name> <servlet-class>com.gof.test.servlet.RedirectDestinationServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>redirectdest</servlet-name> <url-pattern>/redirectdest</url-pattern> </servlet-mapping>
在浏览器中请求如下URL:
http://localhost:8080/base-webapp/redirectsrc?username=New User
可以看到浏览器显示的结果如下:
该请求由两部分组成,第一部分的response中的返回状态码为302,并包含重定向的URL。
同时,浏览器显式的URL变为:
http://localhost:8080/base-webapp/redirectdest?msg=Hello,%20New%20User
在console中打印出的信息为:
Output from RedirectSourceServlet before redirecting. Output from RedirectSourceServlet after redirecting. The attribute added by Source Sevelt is null
可以看到sendRedirect()方法后面的代码仍然会被执行;但是源组件中写入response中的内容不会被发送到客户端。
源组件和目标组件不共享请求范围内的数据,源组件向请求中存放的信息,在目标组件中无法获取该信息。
修改1:
在执行sendRedirect()方法之前,在源组件之前调用flush()方法;将会抛出IllegalStateException异常,同时浏览器会显示出源组件之前输出的内容。
修改2:
将sendRedirect()方法传入一个无效的servlet url,服务器端将返回页面未找到-404的错误提示。
修改3:
将sendRedirect()方法的参数修改为其他的internet网页,如“http://baidu.com”,请求访问源组件将指向这个网页。