servlet之ServletContext簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
在對(duì)Servlet配置的web.xml文件中,經(jīng)常會(huì)使用一些初始化的參數(shù)來(lái)配置Servlet,總的功能來(lái)說(shuō)就是不在Servlet程序中將某個(gè)變量寫(xiě)死,而是通過(guò)外界(如web.xml文件)進(jìn)行傳遞,同時(shí)便于修改。這個(gè)是使用<servlet>標(biāo)簽下的<init-param>標(biāo)簽,使用<init-param>標(biāo)簽的<param-name>和<param-value>來(lái)封裝一個(gè)鍵值對(duì),可以使用多個(gè)<init-param>標(biāo)簽進(jìn)行多個(gè)初始化參數(shù)的設(shè)定,我們可以看看Tomcat的web.xml中的默認(rèn)Servlet:

可以看到在這個(gè)默認(rèn)Servlet中有兩個(gè)初始化參數(shù),分別是“debug=0”和“l(fā)istings=false”。
當(dāng)Servlet在web.xml文件中配置了<init-param>標(biāo)簽后,web容器會(huì)在創(chuàng)建Servlet實(shí)例對(duì)象時(shí),自動(dòng)將這些初始化參數(shù)封裝到ServletConfig對(duì)象中,并在調(diào)用Servlet的初始化init方法時(shí),將ServletConfig對(duì)象傳遞給Servlet。
我們從Servlet接口的初始化方法:init(ServletConfig config),可以知道,當(dāng)服務(wù)器創(chuàng)建Servlet對(duì)象就將ServletConfig對(duì)象傳遞,而在ServletConfig對(duì)象中包含著<init-param>標(biāo)簽所配置的參數(shù)和值。
剛開(kāi)始學(xué)Servlet時(shí),就已經(jīng)談到過(guò)Servlet接口的非生命周期方法就有一個(gè)方法是getServletConfig()方法,返回ServletConfig對(duì)象。所以當(dāng)我們?cè)陂_(kāi)發(fā)的Servlet的web.xml文件中配置一些信息:

而在Servlet中的程序獲取這個(gè)配置的參數(shù):
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletConfig config = this.getServletConfig();
String initValue = config.getInitParameter("love");
System.out.println(initValue);
}
重新部署該web應(yīng)用,然后在瀏覽器來(lái)訪問(wèn)這個(gè)Servlet,將會(huì)看到在MyEclipse的控制臺(tái)上打印出:

在ServletConfig類(lèi)中,getInitParameter(String name)方法是傳入特定參數(shù)名來(lái)獲取對(duì)應(yīng)參數(shù)的值,getInitParameterNames()方法則是將所有的參數(shù)名裝進(jìn)一個(gè)Enumeration對(duì)象返回,當(dāng)我們有多個(gè)參數(shù)鍵值對(duì)時(shí):

在Servlet中進(jìn)行遍歷和輸出:
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對(duì)象的作用通常用于獲得編碼表類(lèi)型,獲得數(shù)據(jù)庫(kù)連接信息,獲得配置文件(如Struts的web.xml文件中)等等。
說(shuō)完了ServletConfig對(duì)象,當(dāng)我們?nèi)タ催@個(gè)對(duì)象的方法時(shí)會(huì)發(fā)現(xiàn)這個(gè)方法中還有一個(gè)方法getServletContext()是返回一個(gè)ServletContext對(duì)象,這是Servlet中一個(gè)非常重要的類(lèi)。當(dāng)然ServletContext對(duì)象還可以從父類(lèi)的方法中直接獲取。
Web容器在啟動(dòng)時(shí)會(huì)為每個(gè)web應(yīng)用創(chuàng)建一個(gè)ServletContext對(duì)象,而這個(gè)ServletContext對(duì)象就代表當(dāng)前這個(gè)web應(yīng)用。因?yàn)橐粋€(gè)ServletContext對(duì)象代表一個(gè)web應(yīng)用,所以該web應(yīng)用中所有的Servlet和其他資源都共享一個(gè)ServletContext對(duì)象,這時(shí),我們就可以通過(guò)ServletContext對(duì)象進(jìn)行Servlet對(duì)象之間的通訊。而ServletContext對(duì)象也稱之為Context域?qū)ο蟆?nbsp;
我們先來(lái)看看ServletContext對(duì)象的獲取的兩種方式:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//兩種獲取ServletContext對(duì)象的方法:
ServletContext context1 = this.getServletConfig().getServletContext();
ServletContext context2 = this.getServletContext();
//System.out.println(context1 == context2); //ture
}
可以通過(guò)先獲取ServletConfig對(duì)象來(lái)獲取,或者直接通過(guò)父類(lèi)的方法來(lái)獲取,這兩種方式獲取到的是同一對(duì)象(相同地址)。
既然說(shuō)ServletContext代表這個(gè)web應(yīng)用,我們可以用它來(lái)進(jìn)行Servlet直接的通訊,那么我們就創(chuàng)建一個(gè)工程來(lái)進(jìn)行兩個(gè)Servlet之間的數(shù)據(jù)傳輸。在一個(gè)【myservlet】web工程下創(chuàng)建兩個(gè)Servlet:ServletDemo1和ServletDemo2,
ServletDemo1在ServletContext中設(shè)置參數(shù)鍵值對(duì),代碼為:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
context.setAttribute("lover", "LRR");
}
ServletDemo2從ServletContext中獲取鍵值對(duì),代碼為:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println(context.getAttribute("lover"));
}
在瀏覽器先訪問(wèn)ServletDemo1后(先執(zhí)行ServletDemo1才能使ServletContext設(shè)置參數(shù)),再訪問(wèn)ServletDemo2后,MyEclipse的控制臺(tái)就輸出了ServletContext中設(shè)置的參數(shù),這就達(dá)到了從一個(gè)Servlet傳遞數(shù)據(jù)給另一個(gè)Servlet。當(dāng)然這只是ServletContext的一個(gè)小小應(yīng)用。
在ServletContext類(lèi)中還有g(shù)etInitParameter(String name)方法或者getInitParameterNames()方法,這兩個(gè)方法獲取的是web應(yīng)用所配置的參數(shù)(畢竟ServletContext代表web應(yīng)用),就像ServletConfig中類(lèi)似的方法獲取的是某個(gè)Servlet中的<init-param>標(biāo)簽配置的參數(shù)。
而對(duì)于配置web應(yīng)用的參數(shù)是在web.xml文件中使用<context-param>標(biāo)簽,正如在該文件中為Servlet配置參數(shù)而使用<init-param>標(biāo)簽一樣。這種配置<context-param>標(biāo)簽的好處在于屬于全局性的配置,而每個(gè)Servlet的配置參數(shù)僅局限于在Servlet的范圍內(nèi),舉個(gè)例子,對(duì)于整個(gè)web應(yīng)用配置數(shù)據(jù)庫(kù)連接,這樣在web應(yīng)用中的每個(gè)Servlet都可以使用,而無(wú)需再在每個(gè)Servlet中都單獨(dú)設(shè)置一次,提高了效率。
例:在【myservlet】web工程下建立了名為ServletDemo3的Servlet,并在該web工程下的web.xml文件中添加<context-param>標(biāo)簽作為該web應(yīng)用的配置參數(shù):

在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);
}
在瀏覽器中訪問(wèn)該Servlet,如果MyEclipse的控制臺(tái)能打印該信息,說(shuō)明每個(gè)Servlet可以通過(guò)ServletContext對(duì)象來(lái)獲取web應(yīng)用的配置信息,也從側(cè)面說(shuō)明了ServletContext代表了這個(gè)web應(yīng)用:

ServletContext類(lèi)中的getMimeType(String file)方法用于返回該文件的MIME類(lèi)型:
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中的轉(zhuǎn)發(fā)方法(重要)
在ServletContext對(duì)象中還有這么兩個(gè)方法:getNameDispatcher(String name)(不常用)和getRequestDispatcher(String path),返回的是RequestDispatcher對(duì)象。轉(zhuǎn)發(fā)有什么作用呢,舉個(gè)例子,比如一個(gè)Servlet中的數(shù)據(jù)交個(gè)另一個(gè)Servlet來(lái)處理,或者Servlet將某個(gè)實(shí)時(shí)數(shù)據(jù)交給JSP來(lái)顯示,雖然我們?cè)跒g覽器中訪問(wèn)的是最開(kāi)始的Servlet,但是進(jìn)行轉(zhuǎn)發(fā)后看到的其他web資源,而瀏覽器的地址欄不會(huì)改變。
注:在請(qǐng)求對(duì)象request對(duì)象中也有這么一個(gè)getRequestDispatcher(String path)方法,功能與ServletContext對(duì)象的這個(gè)方法一樣,也可以實(shí)現(xiàn)轉(zhuǎn)發(fā),因此用哪個(gè)對(duì)象都行,沒(méi)有區(qū)別。
例:在【myservlet】web工程下創(chuàng)建一個(gè)名為ServletDemo1的Servlet和一個(gè)show.jsp,
在ServletDemo1中將數(shù)據(jù)轉(zhuǎn)發(fā)給show.jsp,代碼為:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data = "Ding love LRR";
this.getServletContext().setAttribute("data", data); //將數(shù)據(jù)存至web應(yīng)用的配置中
ServletContext context = this.getServletContext();
RequestDispatcher dispathcer = context.getRequestDispatcher("/show.jsp"); //通過(guò)要轉(zhuǎn)發(fā)的目的地來(lái)獲取轉(zhuǎn)發(fā)對(duì)象
dispathcer.forward(request, response); //通過(guò)forward方法將請(qǐng)求對(duì)象和響應(yīng)對(duì)象轉(zhuǎn)發(fā)給別人處理
}
而在show.jsp中接收這個(gè)數(shù)據(jù),并封裝在HTML中:
<font size="100px" color="red">
${data }
</font>
接著我們?nèi)g覽器里訪問(wèn)ServletDemo1,就會(huì)看到:

雖然我們請(qǐng)求的ServletDemo1資源,但是由于在ServletDemo1中將請(qǐng)求進(jìn)行了轉(zhuǎn)發(fā),所以其實(shí)服務(wù)器返回的是show.jsp的資源,但是我們?yōu)g覽器地址依然會(huì)是ServletDemo1,這也是轉(zhuǎn)發(fā)和重定向的區(qū)別之一。
相關(guān)文章
SpringBoot使用SOFA-Lookout監(jiān)控的方法
本文介紹SpringBoot使用螞蟻金服SOFA-Lookout配合Prometheus進(jìn)行監(jiān)控,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03
淺談Java異常的Exception e中的egetMessage()和toString()方法的區(qū)別
下面小編就為大家?guī)?lái)一篇淺談Java異常的Exception e中的egetMessage()和toString()方法的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
Prometheus 入門(mén)教程之SpringBoot 實(shí)現(xiàn)自定義指標(biāo)監(jiān)控
這篇文章主要介紹了Prometheus 入門(mén)教程之SpringBoot 實(shí)現(xiàn)自定義指標(biāo)監(jiān)控,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
詳解RSA加密算法的原理與Java實(shí)現(xiàn)
這篇文章主要和大家分享非對(duì)稱加密中的一種算法,那就是 RSA 加密算法。本文介紹了RSA算法的原理與Java實(shí)現(xiàn),感興趣的小伙伴可以嘗試一下2022-10-10
JAVA把結(jié)果保留兩位小數(shù)的3種方法舉例
在寫(xiě)程序的時(shí)候,有時(shí)候可能需要設(shè)置小數(shù)的位數(shù),所以下面這篇文章主要給大家介紹了關(guān)于JAVA把結(jié)果保留兩位小數(shù)的3種方法,文章通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-08-08

