03. Servlet 的转发和包含

来源:互联网 发布:mac iphoto能删除 编辑:程序博客网 时间:2024/06/14 18:45

Servlet 的转发和包含

1、尽管一个 Servlet 无法直接调用另一个 Servlet 的 service(),但是Servelt 规范为 Web 组件之间的协作提供了2种途径:
  • 请求转发: Servlet(源组件)先对客户端请求进行一些预处理,然后将请求转发给其他的 Web 组件(目标组件,通常是JSP页面),来完成生成响应结果在内的后续操作;
  • 包含:Servlet(源组件)把其他的 Web 组件(目标组件,可以是 HTML,Servlet类,JSP)生成的响应结果包含到自身的响应结果中;

2、Servlet 模型中对组件进行转发和包含,主要是依靠 javax.servlet.RequestDispatcher类,这2过程类似于原生 php 的 header() 和 include() 函数;

3、一个 Servlet 对象的 RequestDispatcher 对象可以通过 2种方法获取:
   1)该Servlet的 ServletContext对象  getRequestDispatcher(url) 函数获取;
   2)该Servlet service()方法参数中的 ServletRequest对象 的 getRequestDispatcher(url) 函数获取;
1
//假设目标 Servlet 的映射url为 /hello,名称为 hello
2
public class DemoServlet extends GenericServlet{
3
    public void service(ServletRequest request,ServletResponse reponse){
4
        RequestDispatcher dispatcher = request.getRequestDispatcher("hello");
5
    }
6
}

4、RequestDispatcher的 forward、include 方法
以下是RequestDispatcher的这2部分的API:
forward(ServletRequest request, ServletResponse response)
将请求从一个 servlet 转发到服务器上的另一个资源(servlet、JSP 文件或 HTML 文件)。此方法允许一个 servlet 对请求进行初步处理,并使另一个资源生成响应;
include(ServletRequest request, ServletResponse response)
包含响应中某个资源(servlet、JSP 页面和 HTML 文件)的内容。事实上,此方法支持编程式服务器端包含。
① forward() 方法的处理流程如下:
  • 清空调用方法的 Servlet 用于存放响应正文的缓冲区;
  • 如果转发目标组件为 Servlet 或 JSP,就调用它们的 service() 方法,把响应结果发送到客户端;如果转发页面为 HTML 文档,就读取文档中的数据并发送到客户端;
② include() 方法的处理流程如下:
  • 如果源组件为 Sevlet 或 JSP,就调用它们相应的 sevice() 方法,把方法产生的响应正文添加到源组件的响应结果中;如果该目标组件为 HTML 文档,就把文档的内容添加到响应结果中;
  • 返回源组件的服务方法中,继续执行后续代码;


5、请求范围
  • 请求范围指服务器端响应一次客户请求的过程,从Servlet 容器接收到第一个客户请求开始,到返回响应结果结束;
  • 请求范围在具体实现上与ServletRequest,ServletResponse 对象的生命周期对应;
  • 当源组件和目标组件之间为请求转发/包含关系时,对于每一个客户端请求,它们都共享一个 ServletRequest 和 ServletResponse 对象,因此请求范围内的共享数据可以作为 ServletRequest 的 attribute 存在,在请求方位内的各个组件,可以通过 SevletRequest 的 getAttribute(),setAttribute() 方法共享数据;


6、以下进行简单的代码示例
login.html提交一个表单数据给CheckServlet,CheckServlet检查提交的表单数据是否为空,将相应的信息写入请求范围后,转发到OutputServlet产生响应正文,OutputServlet中包含WelcomeServlet产生的响应正文(html开头部分);

login.html
CheckSevlet.java
1
public class CheckServlet extends HttpServlet {
2
    public void doPost(HttpServletRequest request, HttpServletResponse reponse) throws ServletException,IOException{
3
        //获取来自login.html提交的表单,获取数据进行判断后转发给结果输出
4
        String name = request.getParameter("name");
5
        String msg = "";
6
        if(name.isEmpty())
7
            msg = "Please input the name";
8
        else
9
            msg = "Hello,"+name;
10
        request.setAttribute("msg",msg);   //向请求范围写入msg键值
11
12
        //页面请求转发
13
        ServletContext context = getServletContext();
14
        RequestDispatcher dispatcher = context.getRequestDispatcher("/output");
15
        //or RequestDispatcher dispatcher = request.getRequestDispatcher("output");
16
        dispatcher.forward(request,reponse);
17
    }
18
}
WelcomeServlet.java
OutputServlet.java
1
public class OutputServlet extends GenericServlet{
2
    @Override
3
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
4
        //页面请求写入 include,向响应正文写入html前半段
5
        ServletContext context = getServletContext();
6
        RequestDispatcher dispatcher = context.getRequestDispatcher("/welcome");
7
        dispatcher.include(servletRequest,servletResponse);
8
9
        //最终输出
10
        String msg = (String)servletRequest.getAttribute("msg");
11
        PrintWriter out = servletResponse.getWriter();
12
        out.println("<p>"+msg+"</p>");
13
        out.println("</body></html>");
14
15
        servletResponse.flushBuffer();
16
        out.close();
17
18
    }
19
}
web.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<web-app>
3
    <servlet>
4
        <servlet-name>check</servlet-name>
5
        <servlet-class>control1.CheckServlet</servlet-class>
6
    </servlet>
7
    <servlet-mapping>
8
        <servlet-name>check</servlet-name>
9
        <url-pattern>/check</url-pattern>
10
    </servlet-mapping>
11
    <servlet>
12
        <servlet-name>welcome</servlet-name>
13
        <servlet-class>control1.WelcomeServlet</servlet-class>
14
    </servlet>s
15
    <servlet-mapping>
16
        <servlet-name>welcome</servlet-name>
17
        <url-pattern>/welcome</url-pattern>
18
    </servlet-mapping>
19
    <servlet>
20
        <servlet-name>output</servlet-name>
21
        <servlet-class>control1.OutputServlet</servlet-class>
22
    </servlet>
23
    <servlet-mapping>
24
        <servlet-name>output</servlet-name>
25
        <url-pattern>/output</url-pattern>
26
    </servlet-mapping>
27
</web-app>



原创粉丝点击