Servlet的學習之ServletContext(1)


  本篇來介紹Servlet中非常重要的對象,如ServletConfig類和ServletContext類,尤其是ServletContext類中的一些方法,本篇先講述一部分,在下一篇中繼續補充。

  

  在對Servlet配置的web.xml文件中,經常會使用一些初始化的參數來配置Servlet,總的功能來說就是不在Servlet程序中將某個變量寫死,而是通過外界(如web.xml文件)進行傳遞,同時便於修改。這個是使用<servlet>標簽下的<init-param>標簽,使用<init-param>標簽的<param-name>和<param-value>來封裝一個鍵值對,可以使用多個<init-param>標簽進行多個初始化參數的設定,我們可以看看Tomcat的web.xml中的默認Servlet:

  

可以看到在這個默認Servlet中有兩個初始化參數,分別是“debug=0”和“listings=false”。

  當Servlet在web.xml文件中配置了<init-param>標簽后,web容器會在創建Servlet實例對象時,自動將這些初始化參數封裝到ServletConfig對象中,並在調用Servlet的初始化init方法時,將ServletConfig對象傳遞給Servlet。

  我們從Servlet接口的初始化方法:init(ServletConfig config),可以知道,當服務器創建Servlet對象就將ServletConfig對象傳遞,而在ServletConfig對象中包含着<init-param>標簽所配置的參數和值。

  剛開始學Servlet時,就已經談到過Servlet接口的非生命周期方法就有一個方法是getServletConfig()方法,返回ServletConfig對象。所以當我們在開發的Servlet的web.xml文件中配置一些信息:

  

而在Servlet中的程序獲取這個配置的參數:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        ServletConfig config = this.getServletConfig();
        String initValue = config.getInitParameter("love");
        System.out.println(initValue);
    }

  重新部署該web應用,然后在瀏覽器來訪問這個Servlet,將會看到在MyEclipse的控制台上打印出:

  

  在ServletConfig類中,getInitParameter(String name)方法是傳入特定參數名來獲取對應參數的值,getInitParameterNames()方法則是將所有的參數名裝進一個Enumeration對象返回,當我們有多個參數鍵值對時:

  

在Servlet中進行遍歷和輸出:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        ServletConfig config = this.getServletConfig();
        Enumeration initParams = config.getInitParameterNames();
        while(initParams.hasMoreElements()) {
            String paramName = (String)initParams.nextElement();
            String paramValue = config.getInitParameter(paramName);
            System.out.println(paramName+" = "+paramValue );
        }
    }

  

最后,ServletConfig對象的作用通常用於獲得編碼表類型,獲得數據庫連接信息,獲得配置文件(如Struts的web.xml文件中)等等。

 

  說完了ServletConfig對象,當我們去看這個對象的方法時會發現這個方法中還有一個方法getServletContext()是返回一個ServletContext對象,這是Servlet中一個非常重要的類。當然ServletContext對象還可以從父類的方法中直接獲取。

  Web容器在啟動時會為每個web應用創建一個ServletContext對象,而這個ServletContext對象就代表當前這個web應用。因為一個ServletContext對象代表一個web應用,所以該web應用中所有的Servlet和其他資源都共享一個ServletContext對象,這時,我們就可以通過ServletContext對象進行Servlet對象之間的通訊。而ServletContext對象也稱之為Context域對象。 

  我們先來看看ServletContext對象的獲取的兩種方式:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //兩種獲取ServletContext對象的方法:
        ServletContext context1 = this.getServletConfig().getServletContext();
        ServletContext context2 = this.getServletContext();
        
        //System.out.println(context1 == context2);   //ture
    }

可以通過先獲取ServletConfig對象來獲取,或者直接通過父類的方法來獲取,這兩種方式獲取到的是同一對象(相同地址)。

 

  既然說ServletContext代表這個web應用,我們可以用它來進行Servlet直接的通訊,那么我們就創建一個工程來進行兩個Servlet之間的數據傳輸。在一個【myservlet】web工程下創建兩個Servlet:ServletDemo1和ServletDemo2,

  ServletDemo1在ServletContext中設置參數鍵值對,代碼為:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        ServletContext context = this.getServletContext();
        context.setAttribute("lover", "LRR");
    }

ServletDemo2從ServletContext中獲取鍵值對,代碼為:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        ServletContext context = this.getServletContext();    
        System.out.println(context.getAttribute("lover"));
    }

在瀏覽器先訪問ServletDemo1后(先執行ServletDemo1才能使ServletContext設置參數),再訪問ServletDemo2后,MyEclipse的控制台就輸出了ServletContext中設置的參數,這就達到了從一個Servlet傳遞數據給另一個Servlet。當然這只是ServletContext的一個小小應用。

 

  在ServletContext類中還有getInitParameter(String name)方法或者getInitParameterNames()方法,這兩個方法獲取的是web應用所配置的參數(畢竟ServletContext代表web應用),就像ServletConfig中類似的方法獲取的是某個Servlet中的<init-param>標簽配置的參數。

   而對於配置web應用的參數是在web.xml文件中使用<context-param>標簽,正如在該文件中為Servlet配置參數而使用<init-param>標簽一樣。這種配置<context-param>標簽的好處在於屬於全局性的配置,而每個Servlet的配置參數僅局限於在Servlet的范圍內,舉個例子,對於整個web應用配置數據庫連接,這樣在web應用中的每個Servlet都可以使用,而無需再在每個Servlet中都單獨設置一次,提高了效率。

  例:在【myservlet】web工程下建立了名為ServletDemo3的Servlet,並在該web工程下的web.xml文件中添加<context-param>標簽作為該web應用的配置參數:

  

在ServletDemo3中的代碼如下:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        ServletContext context = this.getServletContext();
        String username = context.getInitParameter("username");
        String password = context.getInitParameter("password");
        
        System.out.println(username +":"+ password);
}

在瀏覽器中訪問該Servlet,如果MyEclipse的控制台能打印該信息,說明每個Servlet可以通過ServletContext對象來獲取web應用的配置信息,也從側面說明了ServletContext代表了這個web應用:

  

 

  ServletContext類中的getMimeType(String  file)方法用於返回該文件的MIME類型:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        String filename = "1.html";
        ServletContext context = this.getServletContext();
        System.out.println(context.getMimeType(filename));    
    }

輸出:text/html。

 

ServletContext中的轉發方法(重要) 

  在ServletContext對象中還有這么兩個方法:getNameDispatcher(String name)(不常用)和getRequestDispatcher(String path),返回的是RequestDispatcher對象。轉發有什么作用呢,舉個例子,比如一個Servlet中的數據交個另一個Servlet來處理,或者Servlet將某個實時數據交給JSP來顯示,雖然我們在瀏覽器中訪問的是最開始的Servlet,但是進行轉發后看到的其他web資源,而瀏覽器的地址欄不會改變。

  注:在請求對象request對象中也有這么一個getRequestDispatcher(String path)方法,功能與ServletContext對象的這個方法一樣,也可以實現轉發,因此用哪個對象都行,沒有區別。

  例:在【myservlet】web工程下創建一個名為ServletDemo1的Servlet和一個show.jsp,

  在ServletDemo1中將數據轉發給show.jsp,代碼為:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    String data = "Ding love LRR";
    this.getServletContext().setAttribute("data", data);  //將數據存至web應用的配置中
    ServletContext context = this.getServletContext();        
    RequestDispatcher dispathcer = context.getRequestDispatcher("/show.jsp");  //通過要轉發的目的地來獲取轉發對象
    dispathcer.forward(request, response);      //通過forward方法將請求對象和響應對象轉發給別人處理
    }

而在show.jsp中接收這個數據,並封裝在HTML中:

<font size="100px" color="red">
        ${data }
</font>

接着我們去瀏覽器里訪問ServletDemo1,就會看到:

  

雖然我們請求的ServletDemo1資源,但是由於在ServletDemo1中將請求進行了轉發,所以其實服務器返回的是show.jsp的資源,但是我們瀏覽器地址依然會是ServletDemo1,這也是轉發和重定向的區別之一。

 (補充:其實使用ServletContext對象將數據轉發至JSP並不合理,可能在多線程中,一個Servlet利用ServletContext在轉發給JSP過程中,而另一個線程中的Servlet使用ServletContext將這個轉發的數據給覆蓋,這樣導致原先該轉發給JSP的數據並不是我們期待的,所以使用ServletContext的getRequestDispatcher方法不如使用request請求對象的getRequestDispatcher適用於實際開發場景)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM