• Java開發學習筆記之八:servlet之間的協作

    2016-08-16

      servlet與servlet,servlet與JSP(其本質也是servlet)之間需要合作。主要因為以下幾個原因:
    1.當Web程序比較復雜時,使用一個servlet來完成所有的功能顯然是不合理的。
    2.Web構件之間分工不同。比如servlet比較適合對于請求和響應的控制,而JSP更適合在程序中充當界面。
    3.不同的Web應用之間常常需要相互調用,這種相互調用僅僅通過HTML超鏈接的形式是不夠的。

      servlet和其他Web構件(如servlet,JSP,HTML)的合作主要有三類,分別是servlet鏈接(chaining)、包含響應內容(include)、轉遞請求(forward)。
      較新的Web應用服務器不支持servlet鏈接,取而代之的是過濾器(filter)鏈接機制。下面分別說明后兩種機制:包含響應內容和轉遞請求。
    一、包含響應內容
      顧名思義,包含響應內容這種合作機制的原理,就是在一個servlet內容把另一個servlet的響應內容包含進來。具體是這樣的:當Servlet需要嵌入另一個Web資源時,首先它建立一個請求分派對象(RequestDispatcher),然后使用RequestDispatcher對象的include方法在響應中包括其他Web資源,最后將原servlet及被包含進來的Web構件的內容合成為原Servlet的響應輸出一并發送給客戶端。需要注意的是被包含的Web構件(sevlet或JSP)不能改變從原Servlet傳遞進來的ServletResponse對象的狀態編碼或頭信息,否則將觸發異常。參考如下幾段代碼:
    1.
    public class includeServlet extends HttpServlet{
      public void doGet(HttpServletRequest req,HttpServletResponse resp)
      {
        RequestDispatcher dispatcher = req.getRequestDispatcher("/servletBeIncluded");
        if (dispatcher != null)
          dispatcher.include(req,resp);
          ...
      }
      ...
    }

    2.
    public class includeServlet extends HttpServlet{
      public void doGet(HttpServletRequest req,HttpServletResponse resp)
      {
        RequestDispatcher dispatcher = getServetConfig().getServletContext().getRequestDispatcher("/servletBeIncluded");
        if (dispatcher != null)
          dispatcher.include(req,resp);
          ...
      }
      ...
    }

    3.
    public class includeServlet extends HttpServlet{
      public void doGet(HttpServletRequest req,HttpServletResponse resp)
      {
        RequestDispatcher dispatcher = getServetConfig().getServletContext().getContext("/webApp2").getRequestDispatcher("/servletBeIncluded");
        if (dispatcher != null)
          dispatcher.include(req,resp);
          ...
      }
      ...
    }
    以上三段代碼分別說明了三種取得RequestDispatcher的方式,其中,第一段代碼是由當前的ServletRequest對象直接獲得當前Web應用下的另一個要被包含到當前servlet中的servlet的dispatcher,即這一行代碼:req.getRequestDispatcher("/servletBeIncluded");第二段代碼是由當Web應用的Context對象獲得dispatcher;第三段代碼是由另一個Web應用的Context對象獲得另一個Web應用的servlet的dispatcher。這三段代碼說明了以下幾點:
    1.由當前ServletRequest對象的getRequestDispatcher()方法只能獲得當前Web應用的Web構件的dispatcher,達到了在同一個Web應用,不同的Web構件之間的協作。
    2.可以由ServletContext獲得當前或其它Web應用的Web構件的dispatcher,這樣就可以在不同的Web應用之間進行協作。

    二、向其它Web資源轉遞請求
      這種協作機制和上述include機制類似,也是需要先獲得待協作Web資源(servlet或jsp)的ResquestDispatcher。與include機制不同的是,前者是包含,而后者是轉遞,也就是說直接將響應轉向到另一個Web構件中去,由另一個Web構件去處理。也就是說當轉遞執行之后,ServletRequest對象的URL名稱路徑會變為目標Web構件的URL。參考如下代碼:
    public class includeServlet extends HttpServlet{
      public void doGet(HttpServletRequest req,HttpServletResponse resp)
      {
        RequestDispatcher dispatcher = req.getRequestDispatcher("/servletWillBeForward");
        if (dispatcher != null)
          dispatcher.forward(req,resp);
          ...
      }
      ...
    }

      還有一種轉遞請求的形式:HttpServletRespnse.sendRedirect(String location)。這種方法與forward不同的地方是:sendRedirect是向客戶端發送一個HTTP的URL重定向響應,讓客戶瀏覽器將當前Web請求發磅到另一個URL。因此,sendRedirect方法的參數的相對路徑不是相對于當前Web應用的當前路徑,而是相對于Web應用服務器的根路徑;或者可以直接在參數中指明絕對路徑,如:
    resp.setRedirect("http://xiya.com.cn/xyoa/")。

     


    天堂网