请求转发又被称为内部跳转,可以通过以下两个对象获取RequestDispacher对象:
1.调用ServletContext的getRequestDispacher(String path)方法,path参数为目标组件的路径。这里必须为绝对路径。所谓绝对路径就是以“/”开头,“/”表示当前Web应用的URL入口。例如请求转发到另一个Servlet,这里的参数就必须是web.xml文件中的目标Servlet的servlet-mapping中配置的url-pattern的值/ServletName。
2.调用ServletRequest的getRequestDispacher(String path)方法,path参数为目标组件的路径。这里可以为绝对路径也可以为相对路径。所谓相对路径就是不以“/”开头。例如请求转发到另一个Servlet,web.xml文件中的目标Servlet的servlet-mapping中配置的url-pattern的值是/ServletName。这里还可以写为相对路径ServletName即去掉前面的“/”。
请求转发的大致特点:
1.由于RequestDispacher对象在调用forward(request,response)方法会先清空用于存放响应正文的缓冲区,因此(下文实例代码CheckServlet类中注释掉注释A、B两行代码)Servlet源组件生成的响应结果不会被发送到客户端(也就是不会呈现在浏览器中)。只有目标组件生成的响应结果会被发送到客户端。
2.如果目标组件为Servlet或JSP,就会调用它们的service()方法,把该方法所产生的响应结果发送到客户端(呈现在浏览器中)。如果目标组件为静态HTML文档,就读取文档中的数据并把它发送到客户端(呈现在浏览器中)。
3.如果在源组件进行请求转发之间,已经提交了响应结果,有两种情况:
a.ServletResponse调用了flushBuffer()方法
b.ServletResponse调用了关联的输出流的close()方法。例如PrintWriter的close()方法。
以上两种情况会导致不好的后果。因此不应该在源组件中提交相应结果。
实例代码如下:CheckServlet类处理请求后将请求转发给目标组件OutputServlet类:
CheckServlet类:
public class CheckServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String name = request.getParameter("userName");
String message = null;
if (message == null) {
message = "Please input name!";
} else {
message = "Hello:" + name;
}
request.setAttribute("Message", message);
RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/OutputServlet");
PrintWriter out = response.getWriter();
out.println("Output from CheckServlet before forwording request!");//(1)
System.out.println("Output from CheckServlet before forwording request!");
response.flushBuffer();//(A)会在浏览器输出注释(1)的语句,而且不会执行注释(2)和OutputServlet的输出
out.close();//(B)会在浏览器输出注释(1)的语句,而且不会执行注释(2)OutputServlet的输出
dispatcher.forward(request, response);
out.println("Output from CheckServlet after forwording request!");//(2)
System.out.println("Output from CheckServlet after forwording request!");
}
}
OutputServlet类:
public class OutputServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String message = (String) request.getAttribute("Message");
out.println(message);
out.close();
}
}
web.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>CheckServlet</servlet-name>
<servlet-class>servlet002.web.servlet.CheckServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>OutputServlet</servlet-name>
<servlet-class>servlet002.web.servlet.OutputServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CheckServlet</servlet-name>
<url-pattern>/CheckServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>OutputServlet</servlet-name>
<url-pattern>/OutputServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>