在對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中的程序獲取這個配置的參數:
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應用,然后在瀏覽器來訪問這個servlet,將會看到在myeclipse的控制臺上打印出:
在servletconfig類中,getinitparameter(string name)方法是傳入特定參數名來獲取對應參數的值,getinitparameternames()方法則是將所有的參數名裝進一個enumeration對象返回,當我們有多個參數鍵值對時:
在servlet中進行遍歷和輸出:
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對象的作用通常用于獲得編碼表類型,獲得數據庫連接信息,獲得配置文件(如struts的web.xml文件中)等等。
說完了servletconfig對象,當我們去看這個對象的方法時會發現這個方法中還有一個方法getservletcontext()是返回一個servletcontext對象,這是servlet中一個非常重要的類。當然servletcontext對象還可以從父類的方法中直接獲取。
web容器在啟動時會為每個web應用創建一個servletcontext對象,而這個servletcontext對象就代表當前這個web應用。因為一個servletcontext對象代表一個web應用,所以該web應用中所有的servlet和其他資源都共享一個servletcontext對象,這時,我們就可以通過servletcontext對象進行servlet對象之間的通訊。而servletcontext對象也稱之為context域對象。
我們先來看看servletcontext對象的獲取的兩種方式:
1
2
3
4
5
6
7
8
9
|
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中設置參數鍵值對,代碼為:
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中獲取鍵值對,代碼為:
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" )); } |
在瀏覽器先訪問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中的代碼如下:
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); } |
在瀏覽器中訪問該servlet,如果myeclipse的控制臺能打印該信息,說明每個servlet可以通過servletcontext對象來獲取web應用的配置信息,也從側面說明了servletcontext代表了這個web應用:
servletcontext類中的getmimetype(string file)方法用于返回該文件的mime類型:
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中的轉發方法(重要)
在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,代碼為:
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); //將數據存至web應用的配置中 servletcontext context = this .getservletcontext(); requestdispatcher dispathcer = context.getrequestdispatcher( "/show.jsp" ); //通過要轉發的目的地來獲取轉發對象 dispathcer.forward(request, response); //通過forward方法將請求對象和響應對象轉發給別人處理 } |
而在show.jsp中接收這個數據,并封裝在html中:
1
2
3
|
<font size= "100px" color= "red" > ${data } </font> |
接著我們去瀏覽器里訪問servletdemo1,就會看到:
雖然我們請求的servletdemo1資源,但是由于在servletdemo1中將請求進行了轉發,所以其實服務器返回的是show.jsp的資源,但是我們瀏覽器地址依然會是servletdemo1,這也是轉發和重定向的區別之一。