在對(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”和“listings=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ù):
1
2
3
4
5
6
7
|
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)行遍歷和輸出:
1
2
3
4
5
6
7
8
9
10
11
|
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ì)象的獲取的兩種方式:
1
2
3
4
5
6
7
8
9
|
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ì),代碼為:
1
2
3
4
5
6
|
public void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { servletcontext context = this .getservletcontext(); context.setattribute( "lover" , "lrr" ); } |
servletdemo2從servletcontext中獲取鍵值對(duì),代碼為:
1
2
3
4
5
6
|
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中的代碼如下:
1
2
3
4
5
6
7
8
9
|
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)型:
1
2
3
4
5
6
7
|
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,代碼為:
1
2
3
4
5
6
7
8
9
|
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中:
1
2
3
|
<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ū)別之一。