JSP指令概述
JSP指令的格式:<%@指令名 attr1=”” attr2=”” %>,一般都會把JSP指令放到JSP文件的最上方,但這不是必須的。
JSP中的指令共有三個:page、taglib、include。最常用的是page指令和taglib。
一.page指令
- page指令
page指令是最為常用的指定,也是屬性最多的屬性!
page指令沒有必須屬性,都是可選屬性。例如<%@page %>,沒有給出任何屬性也是可以的!
在JSP頁面中,任何指令都可以重復出現!
<%@ page language=”java”%>
<%@ page import=”java.util.*”%>
<%@ page pageEncoding=”utf-8”%>
這也是可以的! - page指令的pageEncoding和contentType(重點)
pageEncoding指定當前JSP頁面的編碼!這個編碼是給服務器看的,服務器需要知道當前JSP使用的編碼,不然服務器無法正確把JSP編譯成java文件。所以這個編碼只需要與真實的頁面編碼一致即可!在MyEclipse中,在JSP文件上點擊右鍵,選擇屬性就可以看到當前JSP頁面的編碼了。
contentType屬性與response.setContentType()方法的作用相同!它會完成兩項工作,一是設置響應字符流的編碼,二是設置content-type響應頭。例如:<%@ page contentType=”text/html;charset=utf-8”%>,它會使“真身”中出現response.setContentType(“text/html;charset=utf-8”)。
無論是page指令的pageEncoding還是contentType,它們的默認值都是ISO-8859-1,我們知道ISO-8859-1是無法顯示中文的,所以JSP頁面中存在中文的話,一定要設置這兩個屬性。
其實pageEncoding和contentType這兩個屬性的關系很“曖昧”:
1.當設置了pageEncoding,而沒設置contentType時: contentType的默認值為pageEncoding;
2.當設置了contentType,而沒設置pageEncoding時: pageEncoding的默認值與contentType;
也就是說,當pageEncoding和contentType只出現一個時,那么另一個的值與出現的值相同。如果兩個都不出現,那么兩個屬性的值都是ISO-8859-1。所以通過我們至少設置它們兩個其中一個! - page指令的import屬性
import是page指令中一個很特別的屬性!
import屬性值對應“真身”中的import語句。
import屬性值可以使逗號:<%@page import=”java.net.* ,java.util.* ,java.sql.*”%>
import屬性是可以重復出現的:
<%@page import=”java.util.* ” import=”java.net.* ” import=”java.sql.*”%>
然而,pageEncoding這個屬性不能夠重復出現,不管是在一條page指令中還是在多條page指令中,只要其中一條page指令出現過了,另外一條page指令就不能夠再出現pageEncoding,不管屬性值是否相同。(我現在只檢查了pageEncoding不能夠重復出現,其它的page屬性我沒有檢查,不檢查的原因是個人感覺沒有必要,因為你是不會犯這種低級錯誤的。常常我們設置了的就不會去重復設置了,除了import導包外。)
然而,我們一般會使用多個page指令來導入多個包:
<%@ page import=”java.util.*”%>
<%@ page import=”java.net.*”%>
<%@ page import=”java.text.*”%> - page指令的errorPage和isErrorPage
我們知道,在一個JSP頁面出錯后,Tomcat會響應給用戶錯誤信息(500頁面)!如果你不希望Tomcat給用戶輸出錯誤信息,那么可以使用page指令的errorPage來指定錯誤頁!也就是自定義錯誤頁面,例如:<%@page errorPage=”xxx.jsp”%>。這時,在當前JSP頁面出現錯誤時,會請求轉發到xxx.jsp頁面。瀏覽器地址欄是不會變化的。並且轉發是留消息頭而不留消息體即當前頁面輸出的內容是不會在錯誤頁面出現的。
a.jsp:
<%@ page import="java.util.*" pageEncoding="UTF-8"%> <%@ page errorPage="b.jsp" %> <% if(true) throw new Exception("哈哈~"); %>
b.jsp:
<%@ page pageEncoding="UTF-8"%> <html> <body> <h1>出錯啦!</h1> </body> </html>
在上面代碼中,a.jsp拋出異常后,會請求轉發到b.jsp。在瀏覽器的地址欄中還是a.jsp,因為是請求轉發!
而且客戶端瀏覽器收到的響應碼為200,表示請求成功!如果希望客戶端得到500,那么需要指定b.jsp為錯誤頁面(page添加屬性為:isErrorPage=”true”)。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ page isErrorPage="true" %> <html> <body> <h1>出錯啦!</h1> <%=exception.getMessage() %> </body>
<!-- 設置b.jsp頁面為錯誤頁,在錯誤頁中就可以使用exception隱藏對象了。-->
<!-- 注意:一旦轉發到錯誤頁,那么Tomcat會把狀態碼設置為500,而不在是200了。--> </html>
注意,當isErrorPage為true時,說明當前JSP為錯誤頁面,即專門處理錯誤的頁面。那么這個頁面中就可以使用一個內置對象exception了。其他頁面是不能使用這個內置對象的!
溫馨提示:IE會在狀態碼為500時,並且響應正文的長度小於等於512B時不給予顯示!而是顯示“網站無法顯示該頁面”字樣。這時你只需要添加一些響應內容即可,例如上例中的b.jsp中我給出一些內容,IE就可以正常顯示了!
5.web.xml中配置錯誤頁面
不只可以通過JSP的page指令來配置錯誤頁面,還可以在web.xml文件中指定錯誤頁面。這種方式其實與page指令無關.在WEB-INF的web.xml中配置。
<error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error500.jsp</location> </error-page> <error-page> <exception-type>java.lang.RuntimeException</exception-type> <location>/error.jsp</location><!--如果沒有配置這個<error-page>,在拋出RuntimeException時會轉發到error500.jsp頁面。即匹配響應碼500--> </error-page>
<error-page>有兩種使用方式:
- <error-code>和<location>子元素;
- <exception-type>和<location>子元素;
- 其中<error-code>是指定響應碼;<location>指定轉發的頁面;<exception-type>是指定拋出的異常類型。
在上例中:
- 當出現404時,會跳轉到error404.jsp頁面;
- 當出現RuntimeException異常時,會跳轉到error.jsp頁面;
- 當出現非RuntimeException的異常時,會跳轉到error500.jsp頁面。
- 即當jsp發生錯誤時,處理錯誤頁面的配置越詳細就會讓那個配置頁面處理這個異常。也就是當出現非RuntimeException的異常時,會跳轉到error500.jsp頁面。有點像深度搜索。
- 注意:如果想要用這種配置WEB-INF/web.xml的方法捕獲Servlet的異常,就不要用try-catch來處理異常,要直接拋出,否則在當前項目的WEB-INF/web.xml中配置的錯誤處理是捕獲不到的。
這種方式會在控制台看到異常信息!而使用page指令時不會在控制台打印異常信息。
6.page指令的autFlush和buffer
- buffer表示當前JSP的輸出流(out隱藏對象)的緩沖區大小,默認為8kb。
- authFlush表示在out對象的緩沖區滿時如何處理!當authFlush為true時,表示緩沖區滿時把緩沖區數據輸出到客戶端;當authFlush為false時,表示緩沖區滿時,拋出異常。authFlush的默認值為true。
- 這兩個屬性一般我們也不會去特意設置,都是保留默認值!
7.page指令的isELIgnored
- page指令的isElIgnored屬性表示當前JSP頁面是否忽略EL表達式,默認值為false,表示不忽略(即支持)。
8.page指令的其他屬性
- language:只能是Java,這個屬性可以看出JSP最初設計時的野心!希望JSP可以轉換成其他語言!但是,到現在JSP也只能轉換成Java代碼;
- info:JSP說明性信息;
- isThreadSafe:默認為false,為true時,JSP生成的Servlet會去實現一個過時的標記接口SingleThreadModel,這時JSP就只能處理單線程的訪問;
- session:默認為true,表示當前JSP頁面可以使用session對象,如果為false表示當前JSP頁面不能使用session對象;
- extends:指定當前JSP頁面生成的Servlet的父類;
9.<jsp-config>(了解)
在web.xml頁面中配置也可以完成很多page指定的功能!
<jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> //對所有jsp進行配置 <el-ignored>true</el-ignored> //忽略EL表達式 <page-encoding>UTF-8</page-encoding> //指定頁面編碼為utf-8 <scripting-invalid>true</scripting-invalid>//禁用Java腳本!如果在JSP頁面中使用了Java腳本就會拋出異常。 </jsp-property-group> </jsp-config>
二.include指令
include指令表示靜態包含!即目的是把多個JSP合並成一個JSP文件!
include指令只有一個屬性:file,指定要包含的頁面,例如:<%@include file=”b.jsp”%>。
靜態包含:當hel.jsp頁面包含了lo.jsp頁面后,在編譯hel.jsp頁面時,需要把hel.jsp和lo.jsp頁面合並成一個文件,然后再編譯成Servlet(Java文件)。
很明顯,在ol.jsp中在使用username變量,而這個變量在hel.jsp中定義的,所以只有這兩個JSP文件合並后才能使用。通過include指定完成對它們的合並!
三.taglib指令
這個指令需要在學習了自定義標簽后才會使用,現在只能做了了解而已!
在JSP頁面中使用第三方的標簽庫時,需要使用taglib指令來“導包”。例如:
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
其中prefix表示標簽的前綴,這個名稱可以隨便起。uri是由第三方標簽庫定義的,所以你需要知道第三方定義的uri。當然uri也可以是絕對路徑!