回到顶部
您的当前位置: 编程语言> JAVA> JAVA基础> WEB开发
Servlet技术-请求重定向与请求转发(二)
2014-04-22 11:27:50
标签: 原创 Servlet 开发 请求重定向 请求转发
用forward方法实现请求转发

    Forward方法用于将请求转发到RequestDispatcher对象封装的资源,Servlet程序在调用这个方法进行转发之前可以对请求进行一些前期的预处理(在MVC架构中,forward方法是一个核心方法),使用forward方法时,应该注意下面一些问题:

    (1)如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常(属于系统级的异常,运行时异常).

    (2)调用RequestDispatcher. Forward方法时,Servlet容器将根据目标资源路径对当前HttpServletRequest对象中的请求路径和参数信息进行调整.

    (3)如果在调用forward方法之前向Servlet引擎的缓冲区中写入内容,只要写入到输出缓冲区的内容还没有被真正输出到客户端, forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空.在调用forward方法之后,如果调用者程序继续向Servlet引擎的缓冲区中执行写入操作,这些写入操作的执行结果将被忽略.

    (4)在调用者程序中设置的响应状态码和响应头不会被忽略,在被调用者程序中设置的响应状态码和响应头也不会被忽略.注意:对于RequestDispatcher.include方法调用,只有调用者程序设置的响应状态码和响应头才会有效,在被调用者程序中设置的响应状态码和响应头将被忽略.

    (5)如果调用者与被调用者的访问URL不属于同一个目录,当被调用者输出的内容中包含使用相对URL的访问路径时,原来相对被调用者的URL将变成相对于调用者的URL.这是因为浏览器只知道当前访问的是调用者程序的URL,所以对响应内容中的相对路径都以调用者程序的访问URL作为基准进行计算,这样就导致被调用者程序输出的相对路径不再是相对于被调用者的路径了.

ForwardingServlet.java
response.setContentType("text/html;charset=UTF-8");
PrintWriter out=response.getWriter();
//禁止浏览器缓存,以免影响显示效果
response.setDateHeader("Expires",0);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
String china="2008是中国的奥运年!!!";
out.println("before forward.........<br>");
//response.flushBuffer();//用于将缓冲区中的内容强制刷新到客户端
RequestDispatcher rd=getServletContext().getRequestDispatcher("/forwardedServlet?p1="+URLEncoder.encode(china,"Gb2312"));
rd.forward(request,response);
out.println("after forwarding.......<br>");
System.out.println("after forwarding........");	
	
response.setContentType("text/html;charset=GB2312");
PrintWriter out=response.getWriter();
request.setCharacterEncoding("GB2312");
/*String basePath=request.getScheme()+"://"+request.getServletName()+":"+request.getServerPort()+request.getRequestURI();
out.println("<base href=\""+basePath+"\">"); */
out.println("<a href=\"forwardedServlet\">访问自</a><br>");
out.println("URI: "+request.getRequestURI()+"<br>");
out.println("QueryString: "+request.getQueryString()+"<br>");
out.println("URL: "+request.getRequestURL()+"<br>");
String p1=request.getParameter("p1");
if(p1!=null){out.println("Parameter p1: "+p1+"<br>");
请求转发的运行流程

    步骤1:

    浏览器根据用户的请求生成HTTP请求消息,并将其发送给Web服务器(web容器)

    步骤2:

    如果请求资源为Servlet,Web服务器(Web容器)检查内存中是否存在该Servlet对象,如果不存在,则加载和创建该Servlet对象.

    步骤3:

    Web服务器(Web容器)创建针对该次访问的请求对象(request)和响应对象(response)请求对象中包含了HTTP的请求信息,响应对象用于封装将要发送的HTTP响应信息,此时的响应对象中的内容为空.

    步骤4:

    Web容器调用Servlet1的service(ServletRequest request,ServletResponse response)方法,并将请求对象和响应对象传递给该方法.

    步骤5:

    Servlet1对象的service方法从请求对象中读取请求信息,这时可以在响应对象中写入部分响应头和响应体.

    步骤6:

    Service方法向Web容器发出forward命令表示要跳转到Servlet2,Web容器清空先前所写入的响应体内容,并调整请求头中的信息.

    步骤7:

    Web服务器(Web容器)根据forward命令调用Servlet2对象,如果内存中不存在Servlet2,则加载和创建Servlet2对象.

    步骤8:

    Web容器调用Servlet2的service(ServletRequest request,ServletResponse response)方法,并将请求对象和响应对象传递给该方法.注意,这里传递的还是调用Servlet1时所创建的request和response对象.

    步骤9:

    Servlet2对象的service方法从请求对象中读取请求信息,并向响应对象中写入响应头和响应体信息.

    步骤10:

    Servlet2的service方法执行完毕后返回.

    步骤11:

    Servlet1的service方法继续执行调用forward方法的语句后面的代码,执行完毕后返回.

    步骤12:

    Web服务器(Web容器)从响应对象中读取响应信息.

    步骤13:

    Web服务器(Web容器)将响应信息发送给浏览器处理和显示,一次请求响应过程完全结束,request和response变成垃圾,等待垃圾收集器将其彻底从内存中清除.