博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IT兄弟连 JavaWeb教程 请求转发案例
阅读量:6288 次
发布时间:2019-06-22

本文共 3203 字,大约阅读时间需要 10 分钟。

hot3.png

CheckServlet类与OutputServlet类之间为请求转发关系。在web.xml文件中,为CheckServlet映射的URL为"/check",为OutputServlet映射的URL为"/outout"。

public class CheckServlet extends HttpServlet{

    public void service(HttpServletRequest request,

         HttpServletResponse response)throws ServletException,IOException{

         String username = request.getParameter("username");

         String message = null;

         if(username == null){

              message = "Please input username.";

         }else{

              message = "Hello," + username;

         }

         // request.setAttribute("msg",message);

         // servletContext context = getServletContext();

         RequestDispatcher dispatcher =

                   request.getRequestDispatcher ("output");

         PrintWriter out = response.getWriter();

         out.println("Output from CheckServlet before forwarding request");

         System.out.println(

                   "Output from CheckServlet before forwarding request");

         // out.close();

         dispatcher.forward(request,response);

         out.println("Output from CheckServlet after forward request.");

         System.out.println(

                   "Output from CheckServlet after forwarding request.");

    }

}

public class OutputServlet extends HttpServlet{

    public void service(HttpServletRequest request,

           HttpServletResponse response)thrwos ServletException,IOException{

         String message = (String)request.getAttribute("msg");

         PrintWriter out = response.getWriter();

         out.println(message);

         out.close();

    }

}

CheckServlet先检查客户端是否提供了username请求参数,再根据此生成一条消息,用变量message表示,接下来把这条消息作为属性保存到ServletRequest对象中,再把请求转发给OutputServlet。与请求转发相关的代码为:

RequestDispatcher dispatcher = request.getRequestDispatcher("output");

dispatcher.forward(request,response);

以上dispatcher.forward(request,response)方法的处理流程如下。

●  清空用于存放响应正文数据的缓冲区。

●  如果目标组件为Servlet或JSP,就调用它们的service()方法,把该方法产生的响应结果发送到客户端;如果目标组件为文件系统中的静态HTML文档,就读取文档中的数据并把它发送到客户端。

转发流程图

从Dispatcher.forward(request,response)方法的处理流程可以看出,请求转发具有以下特点。

由于forward()方法先清空用于存放响应正文数据的缓冲区,因此Servlet源组件生成的响应结果不会被发送到客户端,自由目标组件生成的响应结果才会被发送到客户端。

如果源组件在进行请求转发之前,已经提交了响应结果(例如调用ServletResponse的flushBuffer()方法,或者调用与ServletResponse关联的输出流的close()方法),那么forward()方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果。

案例中的OutputServlet类作为转发目标组件,先从ServletRequest对象中读取msg属性,然后把它作为响应结果发送到客户端。下面按照如下步骤演示本案例:

1.通过浏览器访问http://localhost:8080/helloapp/check,其中helloapp是项目名称,/check是请求路径,浏览器中会出现"Please input username"。

CheckServlet负责生成消息,而OutputServlet负责把消息发送给客户端。由此可见,CheckServlet与OutputServlet既分工明确,各行其职,又紧密协作,来响应同一个客户请求。

CheckServlet在调用dispatcher.forward(request,response)方法之前和之后,都试图向浏览器以及服务器的控制台输出一些数据:

out.println("Output from CheckServlet before forwarding request");

System.out.println("Output from CheckServlet before forwarding request");

dispatcher.forward(request,response);

out.println("Output from CheckServlet after forward request.");

System.out.println("Output from CheckServlet after forwarding request.");

从浏览器中显示的页面可以看出,CheckServlet作为源组件,它所生成的响应结果不会被发送到客户端。

此外,在Tomcat服务器的控制台,会显示调用forward()方法之前及之后的System.out.println()语句的打印结果。由此可见,在Servlet源组件中调用forward()方法之后的代码也会被执行。

2.修改CheckServlet类的代码,在CheckServlet类中调用forward()方法之前先关闭输出流:

out.close();

dispatcher.forward(request,response);

再次通过浏览器访问CheckServlet,浏览器端仅接收到了由CheckServlet输出的内容:

Output from CheckServlet before forward request;

这是因为CheckServlet的out.close()方法先把CheckServlet输出的内容提交给客户端,然后再关闭输出流。接下来调用forward()方法会抛出异常。

转载于:https://my.oschina.net/u/4125915/blog/3047807

你可能感兴趣的文章