什么是Java Server Pages?
JSP全稱(chēng)Java Server Pages,是一種動(dòng)態(tài)網(wǎng)頁(yè)開(kāi)發(fā)技術(shù)。它使用JSP標(biāo)簽在HTML網(wǎng)頁(yè)中插入Java代碼。標(biāo)簽通常以<%開(kāi)頭以%>結(jié)束。 JSP是一種Java servlet,主要用于實(shí)現(xiàn)Java web應(yīng)用程序的用戶(hù)界面部分。網(wǎng)頁(yè)開(kāi)發(fā)者們通過(guò)結(jié)合HTML代碼、XHTML代碼、XML元素以及嵌入JSP操作和命令來(lái)編寫(xiě)JSP。 JSP通過(guò)網(wǎng)頁(yè)表單獲取用戶(hù)輸入數(shù)據(jù)、訪問(wèn)數(shù)據(jù)庫(kù)及其他數(shù)據(jù)源,然后動(dòng)態(tài)地創(chuàng)建網(wǎng)頁(yè)。 JSP標(biāo)簽有多種功能,比如訪問(wèn)數(shù)據(jù)庫(kù)、記錄用戶(hù)選擇信息、訪問(wèn)JavaBeans組件等,還可以在不同的網(wǎng)頁(yè)中傳遞控制信息和共享信息。
為什么使用JSP?
JSP程序與CGI程序有著相似的功能,但和CGI程序相比,JSP程序有如下優(yōu)勢(shì):
<li>
性能更加優(yōu)越,因?yàn)镴SP可以直接在HTML網(wǎng)頁(yè)中動(dòng)態(tài)嵌入元素而不需要單獨(dú)引用CGI文件。
<li>服務(wù)器調(diào)用的是已經(jīng)編譯好的JSP文件,而不像CGI/Perl那樣必須先載入解釋器和目標(biāo)腳本。
<li>JSP基于Java Servlets API,因此,JSP擁有各種強(qiáng)大的企業(yè)級(jí)Java API,包括JDBC,JNDI,EJB,JAXP等等。
<li>JSP頁(yè)面可以與處理業(yè)務(wù)邏輯的servlets一起使用,這種模式被Java servlet 模板引擎所支持。
<li>最后,JSP是Java EE不可或缺的一部分,是一個(gè)完整的企業(yè)級(jí)應(yīng)用平臺(tái)。這意味著JSP可以用最簡(jiǎn)單的方式來(lái)實(shí)現(xiàn)最復(fù)雜的應(yīng)用。
JSP的優(yōu)勢(shì)
以下列出了使用JSP帶來(lái)的其他好處:
<li>
與ASP相比:JSP有兩大優(yōu)勢(shì)。首先,動(dòng)態(tài)部分用Java編寫(xiě),而不是VB或其他MS專(zhuān)用語(yǔ)言,所以更加強(qiáng)大與易用。第二點(diǎn)就是JSP易于移植到非MS平臺(tái)上。
<li>與純 Servlets相比:JSP可以很方便的編寫(xiě)或者修改HTML網(wǎng)頁(yè)而不用去面對(duì)大量的println語(yǔ)句。
<li>與SSI相比:SSI無(wú)法使用表單數(shù)據(jù)、無(wú)法進(jìn)行數(shù)據(jù)庫(kù)鏈接。
<li>與JavaScript相比:雖然JavaScript可以在客戶(hù)端動(dòng)態(tài)生成HTML,但是很難與服務(wù)器交互,因此不能提供復(fù)雜的服務(wù),比如訪問(wèn)數(shù)據(jù)庫(kù)和圖像處理等等。
<li>與靜態(tài)HTML相比:靜態(tài)HTML不包含動(dòng)態(tài)信息。
JSP 生命周期
理解JSP底層功能的關(guān)鍵就是去理解它們所遵守的生命周期。
JSP生命周期就是從創(chuàng)建到銷(xiāo)毀的整個(gè)過(guò)程,類(lèi)似于servlet生命周期,區(qū)別在于JSP生命周期還包括將JSP文件編譯成servlet。
以下是JSP生命周期中所走過(guò)的幾個(gè)階段:
<li>編譯階段: servlet容器編譯servlet源文件,生成servlet類(lèi)
<li>初始化階段: 加載與JSP對(duì)應(yīng)的servlet類(lèi),創(chuàng)建其實(shí)例,并調(diào)用它的初始化方法
<li>執(zhí)行階段: 調(diào)用與JSP對(duì)應(yīng)的servlet實(shí)例的服務(wù)方法
<li>銷(xiāo)毀階段: 調(diào)用與JSP對(duì)應(yīng)的servlet實(shí)例的銷(xiāo)毀方法,然后銷(xiāo)毀servlet實(shí)例
JSP編譯
當(dāng)瀏覽器請(qǐng)求JSP頁(yè)面時(shí),JSP引擎會(huì)首先去檢查是否需要編譯這個(gè)文件。如果這個(gè)文件沒(méi)有被編譯過(guò),或者在上次編譯后被更改過(guò),則編譯這個(gè)JSP文件。
編譯的過(guò)程包括三個(gè)步驟:
1.解析JSP文件。 2.將JSP文件轉(zhuǎn)為servlet。 3.編譯servlet。
JSP初始化
容器載入JSP文件后,它會(huì)在為請(qǐng)求提供任何服務(wù)前調(diào)用jspInit()方法。如果您需要執(zhí)行自定義的JSP初始化任務(wù),復(fù)寫(xiě)jspInit()方法就行了,就像下面這樣:
public void jspInit(){
// 初始化代碼
}
一般來(lái)講程序只初始化一次,servlet也是如此。通常情況下您可以在jspInit()方法中初始化數(shù)據(jù)庫(kù)連接、打開(kāi)文件和創(chuàng)建查詢(xún)表。
JSP執(zhí)行
這一階段描述了JSP生命周期中一切與請(qǐng)求相關(guān)的交互行為,直到被銷(xiāo)毀。
當(dāng)JSP網(wǎng)頁(yè)完成初始化后,JSP引擎將會(huì)調(diào)用_jspService()方法。 _jspService()方法需要一個(gè)HttpServletRequest對(duì)象和一個(gè)HttpServletResponse對(duì)象作為它的參數(shù),就像下面這樣:
void _jspService(HttpServletRequest request,
HttpServletResponse response)
{
// 服務(wù)端處理代碼
}
_jspService()方法在每個(gè)request中被調(diào)用一次并且負(fù)責(zé)產(chǎn)生與之相對(duì)應(yīng)的response,并且它還負(fù)責(zé)產(chǎn)生所有7個(gè)HTTP方法的回應(yīng),比如GET、POST、DELETE等等。
JSP清理
JSP生命周期的銷(xiāo)毀階段描述了當(dāng)一個(gè)JSP網(wǎng)頁(yè)從容器中被移除時(shí)所發(fā)生的一切。
jspDestroy()方法在JSP中等價(jià)于servlet中的銷(xiāo)毀方法。當(dāng)您需要執(zhí)行任何清理工作時(shí)復(fù)寫(xiě)jspDestroy()方法,比如釋放數(shù)據(jù)庫(kù)連接或者關(guān)閉文件夾等等。 jspDestroy()方法的格式如下:
public void jspDestroy()
{
// 清理代碼
}
JSP 語(yǔ)法
腳本程序
腳本程序可以包含任意量的Java語(yǔ)句、變量、方法或表達(dá)式,只要它們?cè)谀_本語(yǔ)言中是有效的。
腳本程序的語(yǔ)法格式:
<% 代碼片段 %>
或者,您也可以編寫(xiě)與其等價(jià)的XML語(yǔ)句,就像下面這樣
<jsp:scriptlet>
代碼片段
</jsp:scriptlet>
任何文本、HTML標(biāo)簽、JSP元素必須寫(xiě)在腳本程序的外面。
下面給出一個(gè)示例,同時(shí)也是本教程的第一個(gè)JSP示例:
<html>
<head><title>Hello World</title></head>
<body>
Hello World!<br/>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
</body>
</html>
JSP聲明
一個(gè)聲明語(yǔ)句可以聲明一個(gè)或多個(gè)變量、方法,供后面的Java代碼使用。在JSP文件中,您必須先聲明這些變量和方法然后才能使用它們。
JSP聲明的語(yǔ)法格式:
<%! declaration; [ declaration; ]+ ... %>
或者,您也可以編寫(xiě)與其等價(jià)的XML語(yǔ)句,就像下面這樣:
<jsp:declaration>
代碼片段
</jsp:declaration>
程序示例:
<%! int i = 0; %>
<%! int a, b, c; %>
<%! Circle a = new Circle(2.0); %>
JSP表達(dá)式
一個(gè)JSP表達(dá)式中包含的腳本語(yǔ)言表達(dá)式,先被轉(zhuǎn)化成String,然后插入到表達(dá)式出現(xiàn)的地方。
由于表達(dá)式的值會(huì)被轉(zhuǎn)化成String,所以您可以在一個(gè)文本行中使用表達(dá)式而不用去管它是否是HTML標(biāo)簽。
表達(dá)式元素中可以包含任何符合Java語(yǔ)言規(guī)范的表達(dá)式,但是不能使用分號(hào)來(lái)結(jié)束表達(dá)式。
JSP表達(dá)式的語(yǔ)法格式:
<%= 表達(dá)式 %>
同樣,您也可以編寫(xiě)與之等價(jià)的XML語(yǔ)句:
<jsp:expression>
表達(dá)式
</jsp:expression>
程序示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<p>
今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>
</body>
</html>
JSP指令
JSP指令用來(lái)設(shè)置與整個(gè)JSP頁(yè)面相關(guān)的屬性。
JSP指令語(yǔ)法格式:
<%@ directive attribute="value" %>
這里有三種指令標(biāo)簽:
| 指令 | 描述 |
| ---| --------|
| <%@ page ... %> | 定義頁(yè)面的依賴(lài)屬性,比如腳本語(yǔ)言、error頁(yè)面、緩存需求等等 |
| <%@ include ... %>| 包含其他文件 |
| <%@ taglib ... %>| 引入標(biāo)簽庫(kù)的定義,可以是自定義標(biāo)簽 |
JSP行為
JSP行為標(biāo)簽使用XML語(yǔ)法結(jié)構(gòu)來(lái)控制servlet引擎。它能夠動(dòng)態(tài)插入一個(gè)文件,重用JavaBean組件,引導(dǎo)用戶(hù)去另一個(gè)頁(yè)面,為Java插件產(chǎn)生相關(guān)的HTML等等。
行為標(biāo)簽只有一種語(yǔ)法格式,它嚴(yán)格遵守XML標(biāo)準(zhǔn):
<jsp:action_name attribute="value" />
行為標(biāo)簽基本上是一些預(yù)先就定義好的函數(shù),下表羅列出了一些可用的JSP行為標(biāo)簽::
| 語(yǔ)法|描述 |
|----|---|
| jsp:include|用于在當(dāng)前頁(yè)面中包含靜態(tài)或動(dòng)態(tài)資源 |
|jsp:useBean|尋找和初始化一個(gè)JavaBean組件|
|jsp:setProperty|設(shè)置 JavaBean組件的值|
|jsp:forward|從一個(gè)JSP文件向另一個(gè)文件傳遞一個(gè)包含用戶(hù)請(qǐng)求的request對(duì)象|
|jsp:plugin|用于在生成的HTML頁(yè)面中包含Applet和JavaBean對(duì)象|
|jsp:element|動(dòng)態(tài)創(chuàng)建一個(gè)XML元素|
|jsp:attribute|定義動(dòng)態(tài)創(chuàng)建的XML元素的屬性|
|jsp:body|定義動(dòng)態(tài)創(chuàng)建的XML元素的主體|
|jsp:text|用于封裝模板數(shù)據(jù)|
Jsp()