本篇接上一篇《JSP的學習(2)——語法知識一》,繼續來學習JSP的語法。本文主要從JSP指令中的page指令,對其各個屬性進行詳細的學習:html
JSP指令:java
JSP指令是爲JSP引擎而設計的,JSP指令不產生任何可見輸出,只是告訴在轉換成Servlet的過程當中如何處理JSP頁面中的其他部分。在JSP 2.0 規範中共定義了三個指令:web
1) page指令瀏覽器
2) include指令安全
3) taglib指令服務器
taglib指令是導入標籤庫的指令,之後會介紹到。session
JSP指令格式:多線程
<%@ 指令(如page、include或taglib) 屬性1="屬性值" 屬性2="屬性值" … %>
例如:jsp
<%@ page contentType = "text/html;charset=utf-8" %>
若是一個指令有多個屬性,這多個屬性能夠寫在一個指令中,也能夠分開寫。工具
例如:
1 <%@ page contentType = "text/html;charset=utf-8" %> 2 <%@ page import = "java.util.Date" %>
或者寫成:
<%@ page contentType="text/html;charset=utf-8" import="java.util.Date" %>
page指令
page指令用於定義JSP頁面的各類屬性,不管page指令出如今JSP頁面中的什麼地方,它做用的都是整個JSP頁面,爲了保持程序的可讀性和良好習慣,page指令最好都放置在整個page頁面的起始位置。
page指令包含如下屬性(屬性值爲示例):
(1). language = 「java 」 指示JSP頁面若是嵌入的代碼爲Java代碼。
(2). extends = 「package.class」 指定當該JSP轉換後的Servlet繼承哪一個類(一般不用動)。
(3). import = 」包名.類名」或者」包名.*」 等等格式,
其中JSP引擎會自動導入以下包:
java.lang.*
javax.servlet.*
javax.servlet.jsp.*
javax.servlet.http.*
正是由於這樣,因此咱們在JSP中使用像System,response,request這樣的類或對象都不須要再另外導包。
使用多條page指令的「import」屬性進行導入多個類或包,也能夠在一條page指令的「import」屬性中導入多個類或包,其中每一個包或者類之間用逗號隔開,例如:
<%@ page import=" java.util.Date , java.util.* " %>
(4). session = 「true」(默認值)或」false」
若在page指令中將「session」屬性置爲「true」,那麼在JSP轉換後的Servlet中將自動建立Session對象。
若是咱們在page指令中指定「session」屬性置爲「true」,那麼在Tomcat的【work】目錄下JSP對應的 .java文件中就自動出現以下代碼:
session = pageContext.getSession() ;
這時咱們就能夠在JSP腳步片段中直接使用session,若是在page指令中指定「session」屬性置爲「false」,那麼就不能在JSP腳步片段中直接使用session,想使用就手動獲取 (request.getSession())。
(5). buffer = 「none」 或 」8 kb」(默認值) 或 」自定義值kb」
指定JSP頁面是否須要緩衝。即咱們直到JSP轉換後的Servlet中包含大量的經過out對象進行輸出,但輸出的數據並不是直接寫給瀏覽器,而是直到緩衝滿時纔將數據發送回瀏覽器上。
(6). autoFlush = 「true」(默認值) 或」false」
指定JSP頁面是否自動刷新。
(7). isThreadSafe = 「true」(默認值) 或」false」
JSP中的「isThreadSafe」屬性若是設置爲「false」,那麼表示轉換後的Servlet將會繼承SingleThreadMode接口,以Singleton(單線程)模式運行,這種模式同一個時刻只容許一個實例,若多個用戶同時訪問該JSP,那麼只有先訪問者徹底訪問完該頁面後,後訪問者才能開始進行訪問。
例:未設置「isThreadSafe」屬性時:
設置「isThreadSafe」屬性爲「false」後:
而若是「isThreadSafe」屬性設置爲「true」,默認值也是「true」,那麼表示轉換後的Servlet以多線程方式運行,是線程安全的。
(8). info = 「自定義信息…」
用於在JSP頁面中定義一些說明,能夠在Servlet中經過getServletInfo()方法獲取經過page指令獲取」info」的值。
(9). errorPage = 「/ 相對URL 」
當JSP頁面錯誤,或者其中的Java程序出錯,拋出異常沒有處理,那麼在瀏覽器上訪問的JSP頁面能夠跳轉到「errorPage」屬性指定的某個頁面,友好顯示。
注意,」errorPage」屬性的值是相對於web應用下的地址(給服務器端的地址,由於拋出異常的話是由服務器來處理跳轉到哪一個頁面)。
例如:在web工程【JSPLearning】下,建立一個【exceptions】目錄,並在該目錄下新建一個「error.jsp」,同時記住將該JSP中的JSP指令中的「pageEncoding」改成支持中文格式的編碼,內容以下:
1 <body> 2 對不起,你的頁面內容有錯。。。 3 </body>
在該web工程的【WebRoot】即根目錄下建立一個「1.jsp」文件,寫入一段JSP腳本片段:
1 <% 2 int x = 1; 3 out.write(1/0); //會拋出異常 4 %>
同時在該JSP的上部添加進JSP指令,這裏直接寫了屬性:
errorPage = "/exceptions/error.jsp"
那麼如今咱們來訪問這個web應用的「1.jsp」頁面,能夠看到:
會拋出咱們沒有處理的異常的JSP自動跳轉到了咱們在「errorPage」屬性設置的頁面,這樣用戶就不會看到那些「經典」的505頁面和裏面各類異常的說明了。
題外話:
當咱們是個大項目時,裏面會有不少個網頁,當這些網頁多起來後,若是對每一個JSP網頁都設置「errorPage」確定是不切實際的。這時咱們就能夠在web.xml文件中設置錯誤處理頁面。若是要將Tomcat中全部的web應用設置,就在Tomcat的【conf】文件下的web.xml文件中設置;若是隻對某個web應用設置錯誤處理頁面,就在該web應用中【WEB-INF】目錄下的web.xml文件中設置。
在web.xml文件中使用<error-page>標籤爲整個web應用程序設置錯誤處理頁面,其中<exception-type>子元素指定具體異常完整包名和異常名稱,<location>標籤指定以「/」開頭的錯誤處理頁面的路徑(也是以web應用爲根目錄的路徑,即服務器端的路徑)。
咱們對上面的例子進行從新改寫,將包含「errorPage」屬性的page指令從1.jsp中刪除,因爲咱們知道在1.jsp文件中咱們的JSP腳本片段會拋出ArithmeticException異常,所以記下這個異常及異常的包名路徑,以後須要添加到<exception-type>標籤中。
接着咱們咱們到web工程【JSPLearning】中的【WEB-INF】目錄下的web.xml文件,添加下面幾句代碼:
1 <error-page> 2 <exception-type>java.lang.ArithmeticException</exception-type> 3 <location>/exceptions/error.jsp</location> 4 </error-page>
完成上面的工做以後,當訪問該web應用下的某個資源(不論是JSP仍是Servlet等等),只要會拋出ArithmeticException這個異常,服務器會立馬將資源跳轉到指定這個異常的錯誤處理頁面,在咱們的例子中是/exceptions/error.jsp,再次訪問1.jsp仍是看到一樣的效果:
這樣就完成了在一個web應用中進行所有資源的錯誤處理頁面的配置,固然這點有一個不足的地方就是使用這種方法必須指明會發生何種錯誤異常(<exception-type>必須指明)。但若是使用<error-code>就能夠免去這種煩擾,後面會說到。
另一個,採用這種方法時,若是瀏覽器,好比說IE,在其【工具】--->【Internet選項】中,選擇【高級】,找到一個【顯示友好HTTP錯誤信息】,以下圖所示:
一般這個選項瀏覽器默認是勾選上的,這會有一個什麼問題呢,就是採用在web.xml文件中配置<error-page>這元素時,若是咱們的錯誤處理頁面中的內容太少,不足1024字節,那麼在瀏覽器是沒法正常跳轉到錯誤處理頁面的,好比說咱們剛纔的/exceptions/error.jsp中將<body>標籤內容就設置爲:ERROR!,內容夠少了吧,那麼咱們從新打開瀏覽器來訪問1.jsp:
能夠看到沒法看到錯誤處理頁面。
兩種解決方式:1,將【Internet選項】中的【顯示友好HTTP錯誤信息】鉤去除;2,在/exceptions/error.jsp錯誤處理頁面中將內容添加超過1024字節(多添加點很容易就超過了)。以上兩種方法均可以從新看到錯誤處理頁面。
上面說到在<error-page>中能夠設置<exception-type>這個子元素,可是咱們必須給定明確的異常,畢竟麻煩。可是在<error-page>中還能夠設置<error-code>這個子元素,這個元素用來代表當瀏覽器訪問遇到錯誤響應碼時應該訪問哪些頁面,有哪些錯誤的響應碼呢? 404!500!眼熟嗎,T_T!
咱們繼續以上面的web工程【JSPLearning】爲例,在以前的【exceptions】目錄下新建一個error404.jsp,添加自定義內容。
接着咱們繼續在該web工程的web.xml中添加以下代碼:
1 <error-page> 2 <error-code>404</error-code> 3 <location>/exceptions/error404.jsp</location> 4 </error-page>
當咱們訪問一個在web應用中不存在的資源時,服務器就會幫咱們跳轉到這個出現404錯誤而設置的錯誤處理頁面,友好顯示:
能夠看到,這樣就比指定特別異常要方便的多,固然指定某個特定異常天然有其做用的地方,這些都要靠實際狀況來考慮。
題外話講多了,不過這都是對開發有幫助的技巧。這裏最後說明一點,若是在某個頁面中設置了「errorPage」屬性的page指令,那麼在web.xml文件中設置的<error-page>兩種形式都對其沒有做用,也就是說JSP頁面只先認page指令的「errorPage」屬性。
(10). isErrorPage = 「true」 或」false」(默認值)
結合上一點,當咱們將某個JSP頁面設置爲錯誤處理頁面,那麼咱們最好將該頁面設置page指令的「isErrorPage」屬性,並置其爲「true」。
這麼作有什麼好處呢?當這個錯誤處理JSP頁面以後被轉換成Servlet後,在這個Servlet中會自動生成一個異常對象exception,該對象封裝了以前錯誤訪問的一些信息。記住,若是在錯誤處理頁面中沒有設置page指令的「isErrorPage」屬性或者說爲」false」的話,那麼轉換以後的Servlet是不會有這個exception對象的。
那麼咱們仍是以上面的web工程【JSPLearning】爲例,當咱們爲/exceptions/error.jsp這個JSP設置了page指令的「isErrorPage」屬性:
<%@ page isErrorPage="true" %>
讓瀏覽器訪問一次有錯誤代碼的1.jsp使得瀏覽器跳轉到錯誤處理頁面後,咱們到Tomcat的【work】目錄下查看 error_jsp.java文件,咱們會發如今error_jsp這個類中的_jspService()方法中多出了對exception對象的定義,這是沒有設置「isErrorPage」爲」true」的JSP轉換Servlet所沒有的:
這個exception對象同out對象,page對象等,都是能夠在JSP中直接使用的,切記這個對象必定是在那些聲明瞭「isErrorPage」爲」true」的JSP中直接使用。
(11). contentType = 「 MIME類型/對應類型 [(;chrset=某個編碼表)可選] 」
在page指令中的「contentType」屬性告訴JSP引擎(或Tomcat)該JSP頁面的類型,例如:
<%@ page contentType="text/html; charset=ISO-8859-1" %>
在JSP轉換到Servlet時,會根據page指令中的「contentType」屬性生成相應的調用ServletResponse.setContentType(…)方法語句。
「contentType」屬性是用來通知瀏覽器以什麼碼錶來解碼打開JSP(實際上是Servlet)中的內容。
這個屬性能夠用來解決JSP中可能出現的亂碼問題,這個問題咱們之後會討論到。
(12). pageEncoding = 「某個編碼表」
該page指令的屬性「pageEncoding」指定服務器以什麼碼錶將JSP文件翻譯成.java文件中的內容。當設置了這個「pageEncoding」屬性以後,其實也默認將「contentType」屬性中的編碼表設置的和它同樣,因此總結來講咱們只需設置「pageEncoding」屬性便可。
(13). isELIgnored = 「true」 或 「false」(默認值)
告訴JSP引擎(或Tomcat)該JSP頁面是否忽略EL表達式。默認值爲「false」即JSP均支持EL表達式。