request转发问题
请求转发:由下一个Servlet完成响应体,当前Servlet可以设置响应头(留头不留体)。举个例子,AServlet请求转发到BServlet,那么AServlet不能够使用response.getWriter() 和response.getOutputStream() 向客户端输出响应体,但可以使用response.setContentType("text/html;charset=utf-8") 设置响应头。而在BServlet中可以输出响应体。
请求包含:由两个Servlet共同完成响应体(留头又留体)。同样用上面的例子,AServlet请求包含到BServlet,那么AServlet既可以设置响应头,也可以完成响应体。
public class AServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { final Date date = new Date(); request.setAttribute("date", date); request.getRequestDispatcher("/bServlet").forward(request, response); } } public class BServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); final Object attribute = request.getAttribute("date"); out.print("<p>" + "date: " + attribute + "</p>"); } }
在同一次请求中,当AServlet向BServlet做了一次请求转发后,BServlet收到AServlet的request和response,然后服务器执行BServlet的service并将BServlet的response发送给客户端,这样整个过程下来,date最后的值就是当前时间,a设置了属性->a向b做了转发请求->b收到转发请求->b打印了属性,整个过程始终只是一次请求。
如果直接运行BServlet,那么BServlet照常执行自己的service,这时候AServlet并不在BServlet的请求域内,因此此时date的值为null(通俗的说,刷新b网页后b自己干自己的和a没关系,只有刷新a然后服务器说哦你找b有事才会去找b把事情做完)