- 論壇徽章:
- 0
|
1 定義頭和根元素
部署描述符文件就像所有XML文件一樣,必須以一個XML頭開始。這個頭聲明可以使用的XML版本并給出文件的字符編碼。
DOCYTPE聲明必須立即出現(xiàn)在此頭之后。這個聲明告訴服務(wù)器適用的servlet規(guī)范的版本(如2.2或2.3)并指定管理此文件其余部分內(nèi)容的語法的DTD(Document Type Definition,文檔類型定義)。
所有部署描述符文件的頂層(根)元素為web-app。請注意,XML元素不像HTML,他們是大小寫敏感的。因此,web-App和WEB-APP都是不合法的,web-app必須用小寫。
2 部署描述符文件內(nèi)的元素次序
XML 元素不僅是大小寫敏感的,而且它們還對出現(xiàn)在其他元素中的次序敏感。例如,XML頭必須是文件中的第一項,DOCTYPE聲明必須是第二項,而web- app元素必須是第三項。在web-app元素內(nèi),元素的次序也很重要。服務(wù)器不一定強制要求這種次序,但它們允許(實際上有些服務(wù)器就是這樣做的)完全 拒絕執(zhí)行含有次序不正確的元素的Web應(yīng)用。這表示使用非標準元素次序的web.xml文件是不可移植的。
下面的列表給出了所有可直接出現(xiàn)在web-app元素內(nèi)的合法元素所必需的次序。例如,此列表說明servlet元素必須出現(xiàn)在所有servlet-mapping元素之前。請注意,所有這些元素都是可選的。因此,可以省略掉某一元素,但不能把它放于不正確的位置。
l icon icon元素指出IDE和GUI工具用來表示W(wǎng)eb應(yīng)用的一個和兩個圖像文件的位置。
l display-name display-name元素提供GUI工具可能會用來標記這個特定的Web應(yīng)用的一個名稱。
l description description元素給出與此有關(guān)的說明性文本。
l context-param context-param元素聲明應(yīng)用范圍內(nèi)的初始化參數(shù)。
l filter 過濾器元素將一個名字與一個實現(xiàn)javax.servlet.Filter接口的類相關(guān)聯(lián)。
l filter-mapping 一旦命名了一個過濾器,就要利用filter-mapping元素把它與一個或多個servlet或JSP頁面相關(guān)聯(lián)。
l listener servlet API的版本2.3增加了對事件監(jiān)聽程序的支持,事件監(jiān)聽程序在建立、修改和刪除會話或servlet環(huán)境時得到通知。Listener元素指出事件監(jiān)聽程序類。
l servlet 在向servlet或JSP頁面制定初始化參數(shù)或定制URL時,必須首先命名servlet或JSP頁面。Servlet元素就是用來完成此項任務(wù)的。
l servlet-mapping 服務(wù)器一般為servlet提供一個缺省的URL:
http://host/webAppPrefix/servlet/ServletName
。但是,常常會更改這個URL,以便servlet可以訪問初始化參數(shù)或更容易地處理相對URL。在更改缺省URL時,使用servlet-mapping元素。
l session-config 如果某個會話在一定時間內(nèi)未被訪問,服務(wù)器可以拋棄它以節(jié)省內(nèi)存?赏ㄟ^使用HttpSession的setMaxInactiveInterval方法 明確設(shè)置單個會話對象的超時值,或者可利用session-config元素制定缺省超時值。
l mime-mapping 如果Web應(yīng)用具有想到特殊的文件,希望能保證給他們分配特定的MIME類型,則mime-mapping元素提供這種保證。
l welcom-file-list welcome-file-list元素指示服務(wù)器在收到引用一個目錄名而不是文件名的URL時,使用哪個文件。
l error-page error-page元素使得在返回特定HTTP狀態(tài)代碼時,或者特定類型的異常被拋出時,能夠制定將要顯示的頁面。
l taglib taglib元素對標記庫描述符文件(Tag Libraryu Descriptor file)指定別名。此功能使你能夠更改TLD文件的位置,而不用編輯使用這些文件的JSP頁面。
l resource-env-ref resource-env-ref元素聲明與資源相關(guān)的一個管理對象。
l resource-ref resource-ref元素聲明一個資源工廠使用的外部資源。
l security-constraint security-constraint元素制定應(yīng)該保護的URL。它與login-config元素聯(lián)合使用
l login-config 用login-config元素來指定服務(wù)器應(yīng)該怎樣給試圖訪問受保護頁面的用戶授權(quán)。它與sercurity-constraint元素聯(lián)合使用。
l security-role security-role元素給出安全角色的一個列表,這些角色將出現(xiàn)在servlet元素內(nèi)的security-role-ref元素的role-name子元素中。分別地聲明角色可使高級IDE處理安全信息更為容易。
l env-entry env-entry元素聲明Web應(yīng)用的環(huán)境項。
l ejb-ref ejb-ref元素聲明一個EJB的主目錄的引用。
l ejb-local-ref ejb-local-ref元素聲明一個EJB的本地主目錄的應(yīng)用。
3 分配名稱和定制的URL
在web.xml中完成的一個最常見的任務(wù)是對servlet或JSP頁面給出名稱和定制的URL。用servlet元素分配名稱,使用servlet-mapping元素將定制的URL與剛分配的名稱相關(guān)聯(lián)。
3.1 分配名稱
為 了提供初始化參數(shù),對servlet或JSP頁面定義一個定制URL或分配一個安全角色,必須首先給servlet或JSP頁面一個名稱?赏ㄟ^ servlet元素分配一個名稱。最常見的格式包括servlet-name和servlet-class子元素(在web-app元素內(nèi)),如下所示:
Test
moreservlets.TestServlet
這 表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已經(jīng)得到了注冊名Test。給 servlet一個名稱具有兩個主要的含義。首先,初始化參數(shù)、定制的URL模式以及其他定制通過此注冊名而不是類名引用此servlet。其次,可在 URL而不是類名中使用此名稱。因此,利用剛才給出的定義,URL
http://host/webAppPrefix/servlet/Test
可用于
http://host/webAppPrefix/servlet/moreservlets.TestServlet
的場所。
3.2 定義定制的URL
大多數(shù)服務(wù)器具有一個缺省的serlvet URL:
http://host/webAppPrefix/servlet/packageName.ServletName
。 雖然在開發(fā)中使用這個URL很方便,但是我們常常會希望另一個URL用于部署。例如,可能會需要一個出現(xiàn)在Web應(yīng)用頂層的URL(如,http: //host/webAppPrefix/Anyname),并且在此URL中沒有servlet項。位于頂層的URL簡化了相對URL的使用。此外,對 許多開發(fā)人員來說,頂層URL看上去比更長更麻煩的缺省URL更簡短。
事實上,有時需要使用定制的URL。比如,你可能想關(guān)閉缺省URL映射,以便更好地強制實施安全限制或防止用戶意外地訪問無初始化參數(shù)的servlet。如果你禁止了缺省的URL,那么你怎樣訪問servlet呢?這時只有使用定制的URL了。
為 了分配一個定制的URL,可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一個任意名稱,可利用此名稱引用相應(yīng)的servlet;url-pattern描述了相對于Web應(yīng)用的根目錄的URL。url- pattern元素的值必須以斜杠(/)起始。
下面給出一個簡單的web.xml摘錄,它允許使用URL
http://host/webAppPrefix/UrlTest
而不是
http://host/webAppPrefix/servlet/Test
或
http: //host/webAppPrefix/servlet/moreservlets.TestServlet。請注意,仍然需要XML頭、 DOCTYPE聲明以及web-app封閉元素。此外,可回憶一下,XML元素出現(xiàn)地次序不是隨意的。特別是,需要把所有servlet元素放在所有 servlet-mapping元素之前。
Test
moreservlets.TestServlet
Test
/UrlTest
URL模式還可以包含通配符。例如,下面的小程序指示服務(wù)器發(fā)送所有以Web應(yīng)用的URL前綴開始,以..asp結(jié)束的請求到名為BashMS的servlet。
BashMS
msUtils.ASPTranslator
BashMS
/*.asp
3.3 命名JSP頁面
因為JSP頁面要轉(zhuǎn)換成sevlet,自然希望就像命名servlet一樣命名 JSP頁面。畢竟,JSP頁面可能會從初始化參數(shù)、安全設(shè)置或定制的URL中受益,正如普通的serlvet那樣。
部署描述符實際上是一個XML文件,包含了很多描述servlet/JSP應(yīng)用的各個方面的元素,如servlet注冊、servlet映射以及監(jiān)聽器注冊。部署描述符從下面的XML頭開始:
這個頭指定了XML的版本號以及所使用的編碼。頭的下面是DOCTYPE聲明:
這段代碼指定文件類型定義(DTD),可以通過它檢查XML文檔的有效性。下面顯示的元素有幾個特性,這些特性告訴我們關(guān)于DTD的信息:
● web-app定義該文檔(部署描述符,不是DTD文件)的根元素
● PUBLIC意味著DTD文件可以被公開使用
● "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"意味著DTD由Sun Microsystems, Inc.維護。
該信息也表示它描述的文檔類型是DTD Web Application 2.3,而且DTD是用英文書寫的。
● URL"
http://java.sun.com/dtd/web-app_2_3.dtd
"表示D文件的位置。
注意:
在部署描述符中, 用于注釋。
部署描述符的根元素是web-app。DTD文件規(guī)定,web-app元素的子元素的語法如下:
正如您所看到的,這個元素含有23個子元素,而且子元素都是可選的。問號(?)表示子元素是可選的,而且只能出現(xiàn)一次。星號(*)表示子元素可在部署描述符中出現(xiàn)零次或多次。有些子元素還可以有它們自己的子元素。
web.xml文件中web-app元素聲明的是下面每個子元素的聲明。下面的章節(jié)講述部署描述符中可能包含的所有子元素。
注意:
在Servlet 2.3中,子元素必須按照DTD文件語法描述中指定的順序出現(xiàn)。比如,如果部署描述符中的web-app元素有servlet和servlet-mapping兩個子元素,則servlet子元素必須出現(xiàn)在servlet-mapping子元素之前。在Servlet 2.4中,順序并不重要。
下面對web.xml文件各元素進行詳解
1. icon元素
icon元素用來指定GIF格式或JPEG格式的小圖標(16×16)或大圖標(32×32)的文件名。
icon元素包括兩個可選的子元素:small-icon子元素和large-icon子元素。文件名是Web應(yīng)用歸檔文件(WAR)的根的相對路徑。
部署描述符并沒有使用icon元素。但是,如果使用XML工具編輯部署描述符,XML編輯器可以使用icon元素。
2. display-name元素
如果使用工具編輯部署描述符,display-name元素包含的就是XML編輯器顯示的名稱。
下面是一個含有display-name元素的部署描述符:
Online Store Application
3. description元素
可以使用description元素來提供有關(guān)部署描述符的信息。XML編輯器可以使用description元素的值。
4. distributable元素
可以使用distributable元素來告訴servlet/JSP容器,編寫將在分布式Web容器中部署的應(yīng)用:
例如,下面是一個含有distributable元素的部署描述符的例子:
5. context-param元素
context-param元素含有一對參數(shù)名和參數(shù)值,用作應(yīng)用的servlet上下文初始化參數(shù)。參數(shù)名在整個Web應(yīng)用中必須是惟一的。
param-name 子元素包含有參數(shù)名,而param-value子元素包含的是參數(shù)值。作為選擇,可用description子元素來描述參數(shù)。
下面是一個含有context-param元素的有效部署描述符:
jdbcDriver
com.mysql.jdbc.Driver
6. filter元素
filter元素用于指定Web容器中的過濾器。在請求和響應(yīng)對象被servlet處理之前或之后,可以使用過濾器對這兩個對象進行操作。利用下一節(jié)介紹的filter-mapping元素,過濾器被映射到一個servlet或一個URL模式。這個過濾器的filter元素和filter-mapping元素必須具有相同的名稱。
icon、display-name和description元素的用法和上一節(jié)介紹的用法相同。init-param元素與context-param元素具有相同的元素描述符。filter-name元素用來定義過濾器的名稱,該名稱在整個應(yīng)用中都必須是惟一的。filter-class元素指定過濾器類的完全限定的名稱。
下面是一個使用filter元素的部署描述符的例子:
Encryption Filter
com.branysoftware.EncryptionFilter
7. filter-mapping元素
filter-mapping元素用來聲明Web應(yīng)用中的過濾器映射。過濾器可被映射到一個servlet或一個URL模式。將過濾器映射到一個servlet中會造成過濾器作用于servlet上。將過濾器映射到一個URL模式中則可以將過濾器應(yīng)用于任何資源,只要該資源的URL與URL模式匹配。過濾是按照部署描述符的filter-mapping元素出現(xiàn)的順序執(zhí)行的。
filter-name值必須對應(yīng)filter元素中聲明的其中一個過濾器名稱。下面是一個含有filter-mapping元素的部署描述符:
Encryption Filter
com.brainysoftware.EncryptionFilter
Encryption Filter
EncryptionFilteredServlet
8. listener元素
listener元素用來注冊一個監(jiān)聽器類,可以在Web應(yīng)用中包含該類。使用listener元素,可以收到事件什么時候發(fā)生以及用什么作為響應(yīng)的通知。
下面是一個含有l(wèi)istener元素的有效部署描述符:
MyAppListener
9. servlet元素
servlet元素用來聲明一個servlet。
icon、display-name和description元素的用法和上一節(jié)介紹的用法相同。init-param元素與context-param元素具有相同的元素描述符。可以使用init-param子元素將初始化參數(shù)名和參數(shù)值傳遞給servlet。
(1) servlet-name、servlet-class和jsp-file元素
servlet元素必須含有servlet-name元素和servlet-class元素,或者servlet-name元素和jsp-file元素。描述如下:
● servlet-name元素用來定義servlet的名稱,該名稱在整個應(yīng)用中必須是惟一的。
● servlet-class元素用來指定servlet的完全限定的名稱。
● jsp-file元素用來指定應(yīng)用中JSP文件的完整路徑。這個完整路徑必須由a/開始。
(2) load-on-startup元素
當啟動Web容器時,用load-on-startup元素自動將servlet加入內(nèi)存。加載servlet就意味著實例化這個servlet,并調(diào)用它的init方法。可以使用這個元素來避免第一個servlet請求的響應(yīng)因為servlet載入內(nèi)存所導致的任何延遲。如果load-on-startup元素存在,而且也指定了jsp-file元素,則JSP文件會被重新編譯成servlet,同時產(chǎn)生的servlet也被載入內(nèi)存。
load-on-startup元素的內(nèi)容可以為空,或者是一個整數(shù)。這個值表示由Web容器載入內(nèi)存的順序。舉個例子,如果有兩個servlet元素都含有l(wèi)oad-on-startup子元素,則load-on-startup子元素值較小的servlet將先被加載。如果load-on-startup子元素值為空或負值,則由Web容器決定什么時候加載servlet。如果兩個servlet的load-on-startup子元素值相同,則由Web容器決定先加載哪一個servlet。
(3) run-as元素
如果定義了run-as元素,它會重寫用于調(diào)用Web應(yīng)用中servlet所設(shè)定的Enterprise JavaBean(EJB)的安全身份。Role-name是為當前Web應(yīng)用定義的一個安全角色的名稱。
(4) security-role-ref元素
security-role-ref元素定義一個映射,該映射在servlet中用isUserInRole (String name)調(diào)用的角色名與為Web應(yīng)用定義的安全角色名之間進行。security-role-ref元素的描述如下:
role-link元素用來將安全角色引用鏈接到已定義的安全角色。role-link元素必須含有已經(jīng)在security-role元素中定義的一個安全角色的名稱。
(5) Faces Servlet的servlet元素
在 JSF應(yīng)用中,需要為Faces Servlet定義一個servlet元素,如下所示:
Faces Servlet
javax.faces.webapp.FacesServlet
1
Faces Servlet
/faces/*
10. seervlet-mapping 元素
seervlet-mapping 元素將URL模式映射到某個servlet。
在前面的“servlet元素”一節(jié)中已經(jīng)介紹了使用servlet-mapping元素的例子。
11. session-config元素
session-config元素為Web應(yīng)用中的javax.servlet.http.HttpSession對象定義參數(shù)。
session-timeout元素用來指定默認的會話超時時間間隔,以分鐘為單位。該元素值必須為整數(shù)。如果session-timeout元素的值為零或負數(shù),則表示會話將永遠不會超時。
下面是一個部署描述符,在用戶最近訪問HttpSession對象30分鐘后,HttpSession對象默認為無效:
30
12. mime-mapping元素
mime-mapping元素將mime類型映射到擴展名。
extension元素用來描述擴展名。mime-type元素則為MIME類型。
舉個例子,下面的部署描述符將擴展名txt映射為text/plain:
txt
text/plain
13. welcome-file-list元素
當用戶在瀏覽器中輸入的URL不包含某個servlet名或JSP頁面時,welcome-file-list元素可指定顯示的默認文件。
舉個例子說明,假設(shè)用戶在瀏覽器的地址框中輸入
http://www.mycompany.com/appName/
等地址。如果在Web應(yīng)用的部署描述符中指定welcome-file-list元素,用戶就會看到一個權(quán)限錯誤消息,或者是應(yīng)用目錄下的文件和目錄列表。如果定義了welcome-file-list元素,用戶就能看到由該元素指定的具體文件。
welcome-file子元素用于指定默認文件的名稱。welcome-file-list元素可以包含一個或多個welcome-file子元素。如果在第一個welcome-file元素中沒有找到指定的文件,Web容器就會嘗試顯示第二個,以此類推。
下面是一個包含welcome-file-list元素的部署描述符。該元素包含兩個welcome-file元素:第一個指定應(yīng)用目錄中的main.html文件,第二個定義jsp目錄下的welcom.jsp文件,jsp目錄也在應(yīng)用目錄下。
main.html
jsp/welcome.jsp
如果用戶鍵入的URL不包含servlet名稱、JSP頁面或其他資源,則不會在應(yīng)用目錄中找到main.html文件,這時就會顯示jsp目錄下的welcome.jsp文件。
14. error-page元素
error-page元素用于將一段錯誤代碼或一個異常類型映射到Web應(yīng)用中的資源路徑,從而在產(chǎn)生特殊的HTTP錯誤或指定的Java異常時,將顯示相關(guān)的資源。
error-code元素包含HTTP錯誤代碼。exception-type是Java異常類型的完全限定的名稱。location元素是Web應(yīng)用中的資源相對于應(yīng)用目錄的路徑。location的值必須從a/開始。
舉個例子,每次產(chǎn)生HTTP 404錯誤代碼時,下面的部署描述符可使Web容器顯示error404.html頁面:
404
/error404.html
15. taglib元素
taglib元素描述JSP定制標記庫。
taglib-uri元素是用于Web應(yīng)用中的標記庫的URI。taglib-uri元素的值與WEB-INF目錄相對應(yīng)。
taglib-location元素包含一個位置,其中可以找到標記庫的標記庫描述符(TLD)文件。
16. resource-env-ref元素
可以使用resource-env-ref元素來指定對管理對象的servlet引用的聲明,該對象與servlet環(huán)境中的資源相關(guān)聯(lián)。
resource-env-ref-name元素是資源環(huán)境引用的名稱,其值為servlet代碼中使用的環(huán)境的入口名稱。該名稱是一個與java:comp/env相對應(yīng)的Java命名和目錄接口(JNDI)名稱,該名稱在整個Web應(yīng)用中必須是惟一的。
17. resource-ref元素
resource-ref元素用于指定對外部資源的servlet引用的聲明。
resource-ref子元素的描述如下:
● res-ref-name是資源工廠引用名的名稱。該名稱是一個與java:comp/env上下文相對應(yīng)的JNDI名稱,并且在整個Web應(yīng)用中必須是惟一的。
● res-auth表明:servlet代碼通過編程注冊到資源管理器,或者是容器將代表servlet注冊到資源管理器。該元素的值必須為Application或Container。
● res-sharing-scope表明:是否可以共享通過給定資源管理器連接工廠引用獲得的連接。該元素的值必須為Shareable(默認值)或Unshareable。
18. security-constraint元素
部署描述符中的security-constraint元素允許不通過編程就可以限制對某個資源的訪問。
(1) web-resource-collection元素
web-resource-collection元素標識需要限制訪問的資源子集。在web-resource-collection元素中,可以定義URL模式和HTTP方法。如果不存在HTTP方法,就將安全約束應(yīng)用于所有的方法。
web-resource-name是與受保護資源相關(guān)聯(lián)的名稱。http-method元素可被賦予一個HTTP方法,比如GET和POST。
(2) auth-constraint元素
auth-constraint元素用于指定可以訪問該資源集合的用戶角色。如果沒有指定auth-constraint元素,就將安全約束應(yīng)用于所有角色。
role-name元素包含安全角色的名稱。
(3) user-data-constraint元素
user-data-constraint元素用來顯示怎樣保護在客戶端和Web容器之間傳遞的數(shù)據(jù)。
transport-guarantee元素必須具有如下的某個值:
● NONE,這意味著應(yīng)用不需要傳輸保證。
● INTEGRAL,意味著服務(wù)器和客戶端之間的數(shù)據(jù)必須以某種方式發(fā)送,而且在傳送中不能改變。
● CONFIDENTIAL,這意味著傳輸?shù)臄?shù)據(jù)必須是加密的數(shù)據(jù)。
在大多數(shù)情況下,安全套接字層(SSL)用于INTEGRAL或CONFIDENTIAL。
19. login-config元素
login-config元素用來指定所使用的驗證方法、領(lǐng)域名和表單驗證機制所需的特性。
login-config子元素的描述如下:
● auth-method指定驗證方法。它的值為下面的一個:BASIC、DIGEST、FORM或 CLIENT-CERT
● realm-name指定HTTP Basic驗證中使用的領(lǐng)域名。
● form-login-config指定基于表單的登錄中應(yīng)該使用的登錄頁面和出錯頁面。如果沒有使用基于表單的驗證,則忽略這些元素。這個元素的定義如下,其中form-login-page用于指定顯示登錄頁面的資源路徑, form-error-page則用于指定用戶登錄失敗時顯示出錯頁面的資源路徑。這兩個頁面路徑都必須以a/開始,并與應(yīng)用目錄相對應(yīng)。
20. security-role元素
security-role元素指定用于安全約束中的安全角色的聲明。
21. env-entry元素
env-entry元素用于指定應(yīng)用環(huán)境入口。
env-entry-name元素包含Web應(yīng)用環(huán)境入口的名稱。該名稱是一個與java:comp/env相對應(yīng)的JNDI名稱,并且在整個應(yīng)用中必須是惟一的。
env-entry-value元素包含Web應(yīng)用環(huán)境入口的值。該值必須是一個字符串類型的值,并且對于指定類型的構(gòu)造函數(shù)是有效的,該函數(shù)獲得一個String參數(shù);或者對于java.lang.Character是有效的,java.lang.Character對象是一個字符。
env-entry-type元素包含環(huán)境入口值的完全限定的Java類型,該環(huán)境入口值是Web應(yīng)用代碼所期望的。這個env-entry-type元素的值必須是如下之一:
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.String
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double
22. ejb-ref元素
ejb-ref元素用于指定EJB的home接口的引用。
ejb-ref-name包含EJB引用的名稱。EJB引用是servlet環(huán)境中的一個入口,它與java:comp/env相對應(yīng)。這個名稱在Web應(yīng)用中必須是惟一的。為求一致性,推薦您的ejb-ref-name元素名稱以ejb/開始。
ejb-ref-name元素包含引用的EJB的期望類型。這個值必須是Entity或Session。
home元素包含EJB的home接口的完全限定的名稱。remote元素包含EJB的remote接口的完全限定的名稱。
ejb-ref或ejb-local-ref元素中用到的ejb-link元素可指定EJB 引用被鏈接到另一個EJB。Ejb-link元素的值必須是同一個J2EE應(yīng)用單元中某個EJB的ejb-name。Ejb-link元素中的名稱可以由指定ejb-jar的路徑名組成,該ejb-jar包含引用的EJB。目標bean的名稱添加在后面,用字符a# 與路徑名分隔。路徑名與包含引用EJB的Web應(yīng)用的WAR相對應(yīng)。這就允許我們惟一標識具有相同ejb-name的多個企業(yè)bean。
23. ejb-local-ref元素
ejb-local-ref元素用于聲明對EJB的本地home的引用。
local元素包含EJB本地接口的完全限定的名稱。Local-home元素包含EJB本地home接口的完全限定的名稱。
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u2/69320/showart_2148580.html |
|