本篇來介紹Servlet中很是重要的對象,如ServletConfig類和ServletContext類,尤爲是ServletContext類中的一些方法,本篇先講述一部分,在下一篇中繼續補充。html
在對Servlet配置的web.xml文件中,常常會使用一些初始化的參數來配置Servlet,總的功能來講就是不在Servlet程序中將某個變量寫死,而是經過外界(如web.xml文件)進行傳遞,同時便於修改。這個是使用<servlet>標籤下的<init-param>標籤,使用<init-param>標籤的<param-name>和<param-value>來封裝一個鍵值對,可使用多個<init-param>標籤進行多個初始化參數的設定,咱們能夠看看Tomcat的web.xml中的默認Servlet:web
能夠看到在這個默認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中的程序獲取這個配置的參數:jsp
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的控制檯上打印出:this
在ServletConfig類中,getInitParameter(String name)方法是傳入特定參數名來獲取對應參數的值,getInitParameterNames()方法則是將全部的參數名裝進一個Enumeration對象返回,當咱們有多個參數鍵值對時:編碼
在Servlet中進行遍歷和輸出:spa
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適用於實際開發場景)。