jsp(Java Server Pages)技術
簡介
JSP是一種建立在Servlet規范功能之上的動態網頁技術。也就是在網頁文件中嵌入java代碼和JSP標記,用于產生動態內容。 JSP文件在用戶第一次請求時,會被編譯成Servlet,然后由這個Servlet處理用戶的請求。
JSP的運行機制
-
JSP容器管理JSP頁面生命周期的兩個階段:
- 翻譯階段:
當有一個對JSP頁面的客戶請求到來時,JSP容器檢驗JSP頁面的語法是否正確,將JSP頁面轉換為Servlet
源文件 jsp--->java - 編譯階段:
調用javac工具類編譯將Servlet源文件生成字節碼文件。 java->class
執行階段:
Servlet容器加載轉換后的Servlet類,實例化一個對象處理客戶端的請求,在請求處理完成后,響應對象被JSP容器接受,容器將HTML格式的響應信息發送到客戶端。 調用_jspService()
- 翻譯階段:
第一次加載JSP頁面時,因為要將JSP文件轉換為Servlet類,響應速度較慢,再次請求時,JSP容器就會直接執行第一次請求時產生的Servlet,不會重新轉換JSP文件,在JSP執行期間,JSP容器會檢查JSP文件,看是否有更新或修改,如果有,JSP容器會再次編譯JSP或者Servlet,如果沒有更新或者修改,直接執行前面產生的Servlet.
-
JSP頁面轉換后的Servlet類必須實現javax.servlet.jsp.JspPage接口,絕大多數情況下,JSP頁面都使用HTTP協議,所以在JSP頁面轉換后的Servlet類必須實現javax.servlet.jsp.HttpJspPage接口,該接口繼承自JspPage接口。
_jspService(HttpServletRequest request, HttpServletResponse response); 該方法用來處理業務邏輯。
JSP語法
一個JSP頁面由元素和模板數據組成,元素是必須由JSP容器處理。元素有三種類型
指令元素,腳本元素,動作元素。
-
腳本元素 :嵌套寫java代碼
-
聲明(Declaration) (聲明各種變量,方法和內部類看生成的結果)
- 語法: <%!聲明的內容%>
- 作用: 在servlet中聲明一些成員變量、成員方法和內部類
- 特點: 聲明被翻譯進servlet后變成了成員變量、成員方法和內部類
- 注意: 不能使用表達式和隱含對象
-
表達式(Expression)
語法: <%=expression%>
作用: 將expression輸出到out(輸出流)中,
expression可以是算術、邏輯、常量、 關系表達式、變量、有返回值的方法、jsp中的9種隱含對象。
-
9種隱含對象:
- page:當前的jsp頁面,指針this
- pageContext:當前的jsp頁面的上下文
- request:封裝請求的信息
- response:封裝響應
- session:會話
- application:指web應用
- out:輸出流
- config:配置信息
- exception:異常信息。當isErrorPage=true時,才可以使用該對象
特點: 表達式翻譯進servlet后變成了out.print(expression),該代碼處于_jspService()方法中。
注意: expression都一律被轉換成字符串后再寫到輸出流out(JspWriter)中。另外,expression中不能有分號(;)。
-
腳本(Scriptlet)
* 語法: <%java code%>
* 作用: 在jsp中嵌入java代碼,不能嵌入成員變量、成員方法。所以在此模塊申明的變量為局部變量。任何邏輯的代碼都可以放在腳本標簽中。如for循環,匿名內部類,連接數據庫,創建對象等- 特點: 腳本被翻譯進servlet的_jspService()方法中。
-
-
指令元素:指令主要用來提供整個
JSP網頁相關的信息,并且用來設定JSP頁面的相關屬性-
page指令
語法: <%@ page attributeName="attribuerValue"...%>
作用: 利用page指令中的屬性可以和容器進行通信,這些屬性的設置,對整個jsp都有影響。
-
page指令中的屬性:
- language="java"
定義當前頁面使用的編程語言,目前只能是java - contentType="text/html;charset=UTF-8"
定義response中的內容類型和編碼格式和jsp頁面的編碼格式,翻譯后變成response.setContentType("text/html;charset=UTF-8")。 - pageEncoding="UTF-8"
定義當前jsp頁面的編碼格式 - isErrorPage="true|false" 默認為false
表明當前的頁面是否為其它頁面的errorPage目標,如果設置為true,則可以使用exception對象。反之,如果設置為false,則不可以使用exception對象 - errorPage="error.jsp"
默認忽略,定義此頁面出現異常時調用的頁面 - import="package.class,package2.class2"
和一般的java import意義一樣,用","來隔開 - session="true|false" 默認為true
指定這個jsp中是否可以使用session - buffer="none|8kb|sizekb" 默認為8kb
指定到客戶端輸出流的緩沖模式,如果是none則不緩沖,如果指定數值,那么輸出就用不小于這個值的緩沖區進行緩沖。 - autoFlush="true|false" 默認為true
true 當緩沖區滿時,到客戶端的輸出被刷新
false 當緩沖區滿時,出現運行異常,表示緩沖溢出 - isThreadSafe="true|false" 默認為true
用來設置jsp文件是否能支持多線程的使用。如為true,那么一個jsp能夠同時處理多個用戶的請求,反之,一個jsp只能一次處理一個請求。 - info="text"
關于jsp頁面的信息,定義一個字符串,可以使用getServletInfo()獲得
l2. extends="package.class"
指定jsp對應的servlet類繼承某個父類 - isELIgnored="true|false"
指定EL表達式語言是否被忽略,如為true則忽略,反之可以使用EL。
- language="java"
-
include指令
- 語法: <%@ include file="url"%>,稱為靜態導入(靜態包含)
作用: 在一個頁面中導入另一個頁面的內容(這些內容一般不會有變化,如公司的標題和版權等信息)。
特點: 在jsp翻譯成servlet后就將被導入的頁面內容嵌入到servlet中。導入時間發生在翻譯階段。被導入的資源:html、xml、jsp等
優點: 執行效率高(只翻譯一次)
-
缺點: 當被導入頁面的內容發生變化,那么jsp必須要重新被翻譯。如果導入的多個頁面,其中的一個頁面的內容發生變化,就需要將所有的頁面都翻譯一次。
static { _jspx_dependants = new java.util.ArrayList(1); _jspx_dependants.add("/day10/static.jsp"); }
- 語法: <%@ include file="url"%>,稱為靜態導入(靜態包含)
taglib指令
<%@ taglib uri="" prefix=""%>
例如: 導入jstl標簽庫
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
指定在jsp中要使用的標簽庫描述文件(*.tld)的路徑
-
動作元素(jsp自帶的標準標簽)
語法: <jsp:tagName/>
- 動態導入(動態包含)
語法:
<jsp:include page="url" flush="true|false"/>
或者
<jsp:include page="url" flush="true|false">
{<jsp:param …/>}*
</jsp:include>特點: 動態導入發生在執行階段,也就是在運行serlvet的時候才動態生成被導入頁面的內容,然后嵌入到調用頁面,最后將兩個頁面的內容一起,返回給客戶端。
注意: 在翻譯階段并沒有生成被導入頁面的內容。沒有跳轉,請求還是同一個缺點: 執行效率沒有靜態導入高
-
優點: 如果被導入頁面的內容發生變化,調用頁面不必重新翻譯。
_jspService(){ org.apache.jasper.runtime.JspRuntimeLibrary .include(request, response, "dynamic.jsp", out, false); }
JSP隱含對象
JSP容器生成的Servlet類的_jspService()方法中,定義的幾個對象我們可以在編寫JSP頁面時使用的隱含對象。page: 當前的jsp頁面,指針this
pageContext: 當前的jsp頁面的上下文
request: 封裝請求的信息
response: 封裝響應
session: 會話
application: 指web應用
out: 輸出流
config: 配置信息
exception: 異常信息
其中pageContext 對象提供了以下方法:
訪問其他隱含對象的方法
- getRequest()
- getResponse()
- getSession()
- getServletContext()
- JspWriter getOut()
- getServletConfig()
- Object getPage()
- Exception getException()
還可以用來保存屬性,但是只能在當前頁面中獲取
- setAttribute(String name,Object val);
- Object getAttribute(String name);
還可以設置和得到其他范圍對象中保存的屬性
setAttribute(String name,Object val,int scope);
Object getAttribute(String name,int scope);
removeAttribute(String name,int scope)
刪除指定范圍內名字為name的屬性removeAttribute(String name)
刪除所有范圍內名字為name的屬性findAttribute(String name)
該方法會按照page,request,session,application范圍順序搜索指定名字的屬性。PageContext.PAGE_SCOPE 頁面范圍
PageContext.REQUEST_SCOPE 請求范圍
PageContext.SESSION_SCOPE 會話范圍
PageContext.APPLICATION_SCOPE 應用程序范圍
exception
對象表示了JSP頁面運行時產生的異常,該對象只有在錯誤頁面(page指令中指定isErrorPage=true的頁面)中才可以使用。當JSP頁面運行發生錯誤時,JSP容器會自動調用指定的錯誤處理頁面,如果JSP頁面使用errorPage屬性定義了錯誤頁面,那么在web.xml文件中定義的任何錯誤頁面將不會被使用
對象和范圍
在JSP中,有4中范圍
- page范圍:
具有page范圍的對象被綁定到javax.servlet.jsp.PageContext對象中,在這個范圍中的對象,只能在創建對象的頁面中訪問。page范圍內的對象,在客戶端每次請求JSP頁面時創建,在頁面向客戶端發送回響應或請求被轉發到其他資源后被刪除。 - request范圍
具有request范圍的對象被綁定到javax.servlet.http.HttpServletRequest對象中。在調用forward()方法轉向的頁面或調用include()方法包含的頁面中,都可以訪問這個范圍內的對象。 - session范圍
具有session返回的對象被綁定到javax.servlet.http.HttpSession對象中,JSP容器為每次會話,創建一個HttpSession對象,在會話期間,可以訪問session范圍內的數據 - application范圍
具有application范圍的對象被綁定到javax.servlet.ServletContext中,在web應用程序運行期間,所有頁面都可以訪問這個范圍內的對象