版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第3章JSP技術(shù)基礎(chǔ)本章首先介紹JSP語(yǔ)法和生命周期、腳本元素、隱含變量,JSP動(dòng)作,接下來介紹錯(cuò)誤處理、作用域?qū)ο蠛蚃avaBean使用,最后介紹MVC設(shè)計(jì)模式。JSP頁(yè)面語(yǔ)法元素JSP頁(yè)面轉(zhuǎn)換過程與生命周期JSP指令和動(dòng)作JSP隱含變量錯(cuò)誤處理方法作用域?qū)ο笈cJavaBeanMVC設(shè)計(jì)模式JSP(JavaServerPages)是一種動(dòng)態(tài)頁(yè)面技術(shù),它的主要目的是將表示邏輯從Servlet中分離出來,實(shí)現(xiàn)表示邏輯。在MVC模式中,JSP頁(yè)面實(shí)現(xiàn)視圖功能。在JSP頁(yè)面中可以包含多種JSP元素,比如聲明變量和方法、JSP表達(dá)式、指令和動(dòng)作等。這些元素具有嚴(yán)格定義的語(yǔ)法。當(dāng)JSP頁(yè)面被訪問時(shí),Web容器將JSP頁(yè)面轉(zhuǎn)換成Servlet類執(zhí)行后將結(jié)果發(fā)送給客戶。與其他的Web頁(yè)面一樣,JSP頁(yè)面也有一個(gè)唯一的URL,客戶可以通過它訪問頁(yè)面。一般來說在JSP頁(yè)面中可以包含的元素如表3-1所示。JSP頁(yè)面元素簡(jiǎn)要說明標(biāo)簽語(yǔ)法指令指定轉(zhuǎn)換時(shí)向容器發(fā)出的指令<%@指令%>動(dòng)作向容器提供請(qǐng)求時(shí)的指令<jsp:動(dòng)作名/>EL表達(dá)式JSP頁(yè)面使用的數(shù)據(jù)訪問語(yǔ)言${EL表達(dá)式}腳本元素JSP聲明聲明變量與定義方法<%!Java聲明%>JSP小腳本執(zhí)行業(yè)務(wù)邏輯的Java代碼<%Java代碼%>JSP表達(dá)式用于在JSP頁(yè)面輸出表達(dá)式的值<%=表達(dá)式%>注釋用于文檔注釋<%--任何文本--%>表3-1JSP頁(yè)面元素在一個(gè)JSP頁(yè)面中,除了JSP元素外,其他內(nèi)容稱為模板文本(templatetext),也就是HTML標(biāo)記和文本。清單3.1是一個(gè)簡(jiǎn)單的JSP頁(yè)面,其中包含了多種JSP元素。3.1JSP頁(yè)面元素該頁(yè)面包含JSP指令、JSP聲明、JSP小腳本和JSP表達(dá)式,其他內(nèi)容稱為模板文本。當(dāng)JSP頁(yè)面被客戶訪問時(shí),頁(yè)面首先在服務(wù)器端被轉(zhuǎn)換成一個(gè)Java源程序文件,然后該程序在服務(wù)器端編譯和執(zhí)行,最后向客戶發(fā)送執(zhí)行結(jié)果,通常是文本數(shù)據(jù)。這些數(shù)據(jù)由HTML標(biāo)簽包圍起來,然后發(fā)送到客戶端。由于嵌入在JSP頁(yè)面中的Java代碼是在服務(wù)器端處理的,客戶并不了解這些代碼。<%@pagecontentType="text/html;charset=UTF-8"%><%@pageimport="java.time.LocalDate"%><%!LocalDatedate=null;%><html><head><title>當(dāng)前日期</title></head><body><%date=LocalDate.now();%>今天的日期是:<%=date.toString()%></body></html>todayDate.jsp清單3.13.1JSP頁(yè)面元素JSP指令(directive)向容器提供關(guān)于JSP頁(yè)面的總體信息。在JSP頁(yè)面中,指令是以“<%@”開頭,以“%>”結(jié)束的標(biāo)簽。指令有三種類型:page指令、include指令和taglib指令。三種指令的語(yǔ)法格式如下:<%@pageattribute-list%><%@includeattribute-list%><%@taglibattribute-list%>在上面的指令標(biāo)簽中,attribute-list表示一個(gè)或多個(gè)針對(duì)指令的“屬性/值”對(duì),多個(gè)屬性之間用空格分隔。JSP指令3.1.1<%@pagecontentType="text/html;charset=UTF-8"%>123page指令include指令taglib指令page指令通知容器關(guān)于JSP頁(yè)面的總體特性。例如,下面的page指令通知容器頁(yè)面輸出的內(nèi)容類型和使用的字符集。page指令通知容器關(guān)于JSP頁(yè)面的總體特性。例如,下面的page指令通知容器頁(yè)面輸出的內(nèi)容類型和使用的字符集。<%@includefile="copyright.html"%><%@taglibprefix="c"uri="/jsp/jstl/core"%>taglib指令用來指定在JSP頁(yè)面中使用標(biāo)準(zhǔn)標(biāo)簽或自定義標(biāo)簽的前綴與標(biāo)簽庫(kù)的URI,下面是taglib指令的例子。JSP指令3.1.1表達(dá)式語(yǔ)言(ExpressionLanguage,EL)是一種可以在JSP頁(yè)面中使用的簡(jiǎn)潔的數(shù)據(jù)訪問語(yǔ)言。它的語(yǔ)法格式為:表達(dá)式語(yǔ)言是以$開頭,后面是一對(duì)大括號(hào),括號(hào)里面的expression是EL表達(dá)式,也可以是作用域變量、EL隱含變量等。該結(jié)構(gòu)可以出現(xiàn)在JSP頁(yè)面的模板文本中,也可以出現(xiàn)在JSP標(biāo)簽的屬性中。清單3.1中輸出日期就可以使用表達(dá)式語(yǔ)言改寫如下:由于LocalDate類的now()方法是靜態(tài)工廠方法,它可以在EL中直接調(diào)用。但需要使用page指令將類導(dǎo)入。${expression}今天的日期是:${LocalDate.now()}表達(dá)式語(yǔ)言3.1.2JSP動(dòng)作(actions)是頁(yè)面發(fā)給容器的命令,它指示容器在頁(yè)面執(zhí)行期間完成某種任務(wù)。動(dòng)作的一般語(yǔ)法為:動(dòng)作是一種標(biāo)簽,在動(dòng)作標(biāo)簽中,prefix為前綴名,actionName為動(dòng)作名,attribute-list表示針對(duì)該動(dòng)作的一個(gè)或多個(gè)“屬性/值”對(duì)。在JSP頁(yè)面中可以使用三種動(dòng)作:JSP標(biāo)準(zhǔn)動(dòng)作,標(biāo)準(zhǔn)標(biāo)簽庫(kù)(JSTL)中的動(dòng)作和用戶自定義動(dòng)作。例如,下面一行指示容器把另一個(gè)JSP頁(yè)面copyright.jsp的輸出包含在當(dāng)前JSP頁(yè)面的輸出中:<prefix:actionNameattribute-list/><jsp:includepage="copyright.jsp"/>JSP動(dòng)作3.1.3腳本元素(scriptingelements)是在JSP頁(yè)面中使用Java代碼,主要用于實(shí)現(xiàn)業(yè)務(wù)邏輯。有三種腳本元素:聲明、小腳本和表達(dá)式。<%!LocalDatedate=null;%>1JSP聲明JSP聲明(declaration)用來在JSP頁(yè)面中聲明變量和定義方法。聲明是以“<%!”開頭,以“%>”結(jié)束的標(biāo)簽,其中可以包含任意數(shù)量的合法的Java聲明語(yǔ)句。下面是JSP聲明的一個(gè)例子:上面代碼聲明了一個(gè)名為date的變量并將其初始化為null。聲明的變量?jī)H在頁(yè)面第一次載入時(shí)由容器初始化一次,初始化后在后面的請(qǐng)求中一直保持該值。注意,由于聲明包含的是聲明語(yǔ)句,所以每個(gè)變量的聲明語(yǔ)句必須以分號(hào)結(jié)束。下面的代碼在一個(gè)標(biāo)簽中聲明了一個(gè)變量r和一個(gè)getArea()方法。<%!doubler=0;//聲明一個(gè)變量rdoublegetArea(doubler){//聲明求圓面積的方法returnr*r*Math.PI;}%>JSP腳本元素3.1.4<%date=LocalDate.now();//創(chuàng)建一個(gè)LocalDate對(duì)象%>2JSP小腳本JSP小腳本(scriptlets)是嵌入在JSP頁(yè)面中的Java代碼段。小腳本是以“<%”開頭,以“%>”結(jié)束的標(biāo)簽。例如,在清單3.1中的下面代碼就是JSP小腳本。小腳本在每次訪問頁(yè)面時(shí)都被執(zhí)行,因此date變量在每次請(qǐng)求時(shí)會(huì)返回當(dāng)前日期。由于小腳本可以包含任何Java代碼,所以它通常用來在JSP頁(yè)面嵌入計(jì)算邏輯。同時(shí)還可以使用小腳本打印HTML模板文本。與其他元素不同,小腳本的起始標(biāo)簽“<%”后面沒有任何特殊字符,在小腳本中的代碼必須是合法的Java語(yǔ)言代碼,例如下面的代碼是錯(cuò)誤的,因?yàn)樗鼪]有使用分號(hào)結(jié)束。不能在小腳本中聲明方法,因?yàn)樵贘ava語(yǔ)言中不能在方法中定義方法。<%out.print(count)%>JSP腳本元素3.1.4今天的日期是:<%=date.toString()%>3JSP表達(dá)式JSP表達(dá)式(expression)是以“<%=”開頭,以“%>”結(jié)束的標(biāo)簽,它作為Java語(yǔ)言表達(dá)式的占位符。下面是JSP表達(dá)式的例子。在頁(yè)面每次被訪問時(shí)都要計(jì)算表達(dá)式,然后將其值嵌入到HTML的輸出中。與變量聲明不同,表達(dá)式不能以分號(hào)結(jié)束,因此下面的代碼是非法的。使用表達(dá)式可以向輸出流輸出任何對(duì)象或任何基本數(shù)據(jù)類型(int、boolean、char等)的值,也可以打印任何算術(shù)表達(dá)式、布爾表達(dá)式或方法調(diào)用返回的值。提示:在JSP表達(dá)式的百分號(hào)和等號(hào)之間不能有空格。<%=date.toString();%>JSP腳本元素3.1.4JSP注釋是以“<%--”開頭,以“--%>”結(jié)束的標(biāo)簽。注釋不影響JSP頁(yè)面的輸出,但它對(duì)用戶理解代碼很有幫助。JSP注釋的格式為:Web容器在輸出JSP頁(yè)面時(shí)去掉JSP注釋內(nèi)容,所以在調(diào)試JSP頁(yè)面時(shí)可以將JSP頁(yè)面中一大塊內(nèi)容注釋掉,包括嵌套的HTML和其他JSP標(biāo)簽。然而,不能在JSP注釋內(nèi)嵌套另一個(gè)JSP注釋。<%--這里是JSP注釋內(nèi)容--%>JSP注釋3.1.5
一個(gè)JSP頁(yè)面在其執(zhí)行過程中要經(jīng)歷多個(gè)階段,這些階段稱為生命周期階段(life-cyclephases)。3.2JSP生命周期
JSP頁(yè)面從結(jié)構(gòu)上看與HTML頁(yè)面類似,但它實(shí)際上是作為Servlet運(yùn)行的。當(dāng)JSP頁(yè)面第一次被訪問時(shí),Web容器解析JSP文件并將其轉(zhuǎn)換成相應(yīng)的Java文件,該文件聲明了一個(gè)Servlet類,該類稱為頁(yè)面實(shí)現(xiàn)類。接下來,Web容器編譯該類并將其裝入內(nèi)存,然后與其他Servlet一樣執(zhí)行并將其輸出結(jié)果發(fā)送到客戶端。頁(yè)面實(shí)現(xiàn)類繼承了HttpJspBase類,同時(shí)實(shí)現(xiàn)JspPage接口,該接口又繼承了Servlet接口。JspPage接口只聲明了兩個(gè)方法:jspInit()和jspDestroy()。所有的JSP頁(yè)面都應(yīng)該實(shí)現(xiàn)這兩個(gè)方法。HttpJspPage接口中聲明了一個(gè)_jspService()方法。這三個(gè)JSP方法的格式如下:publicvoidjspInit();publicvoid_jspService(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException;publicvoidjspDestroy();JSP頁(yè)面實(shí)現(xiàn)類3.2.1這三個(gè)方法分別等價(jià)于Servlet的init()、service()和destroy()方法,稱為JSP頁(yè)面的生命周期方法。JSP頁(yè)面中的所有元素都轉(zhuǎn)換成頁(yè)面實(shí)現(xiàn)類的對(duì)應(yīng)代碼,page指令的import屬性轉(zhuǎn)換成import語(yǔ)句,page指令的contentType屬性轉(zhuǎn)換成response.setContentType()調(diào)用,JSP聲明的變量轉(zhuǎn)換為成員變量,小腳本轉(zhuǎn)換成正常Java語(yǔ)句,模板文本和JSP表達(dá)式都使用out.write()方法打印輸出,輸出是在轉(zhuǎn)換的_jspService()方法完成的。JSP頁(yè)面實(shí)現(xiàn)類3.2.1下面以todayDate.jsp頁(yè)面為例說明JSP頁(yè)面生命周期階段。當(dāng)客戶首次訪問該頁(yè)面時(shí),Web容器執(zhí)行該JSP頁(yè)面要經(jīng)過7個(gè)階段,如圖3-1所示。前4個(gè)階段將JSP頁(yè)面轉(zhuǎn)換成一個(gè)Servlet類并裝載和創(chuàng)建該類實(shí)例,后3個(gè)階段是初始化、提供服務(wù)和銷毀階段。1轉(zhuǎn)換階段Web容器讀取JSP頁(yè)面對(duì)其解析,并將其轉(zhuǎn)換成Java源代碼。JSP文件中的元素都轉(zhuǎn)換成頁(yè)面實(shí)現(xiàn)類的成員。在這個(gè)階段,容器將檢查JSP頁(yè)面的語(yǔ)法,發(fā)現(xiàn)錯(cuò)誤將不能轉(zhuǎn)換。例如,下面指令就是非法的,因?yàn)樵凇癙age”中使用了大寫字母P,這將在轉(zhuǎn)換階段被捕獲。<%@Pageimport="java.util.*"%>JSP執(zhí)行過程3.2.2圖3-1JSP頁(yè)面生命周期階段一旦驗(yàn)證完成,Web容器將JSP頁(yè)面轉(zhuǎn)換成頁(yè)面實(shí)現(xiàn)類,它實(shí)際是一個(gè)Servlet,3.2.1節(jié)描述了頁(yè)面實(shí)現(xiàn)類及其存放位置。Web容器todayDate.jsptodayDate_jsp.java
todayDate_jsp
加載
jspInit()
_jspService()
jspDestroy()Web瀏覽器
創(chuàng)建實(shí)例
todayDate_jsp.classJSP執(zhí)行過程3.2.2在將JSP頁(yè)面轉(zhuǎn)換成Java文件后,Web容器調(diào)用Java編譯器編譯該文件。在編譯階段,將檢查在聲明中、小腳本中以及表達(dá)式中所寫的全部Java代碼。例如,下面的聲明標(biāo)簽盡管能夠通過轉(zhuǎn)換階段,但由于聲明語(yǔ)句沒以分號(hào)結(jié)束,所以不是合法的Java聲明語(yǔ)句,因此在編譯階段會(huì)被查出??赡茏⒁獾?,當(dāng)JSP頁(yè)面被首次訪問時(shí),服務(wù)器響應(yīng)要比以后的訪問慢一些。這是因?yàn)樵贘SP頁(yè)面向客戶提供服務(wù)之前必須要轉(zhuǎn)換成Servlet類的實(shí)例。2編譯階段<%!LocalDatedate=null%>JSP執(zhí)行過程3.2.2對(duì)該頁(yè)面的每次請(qǐng)求容器都調(diào)用一次_jspService(),并給它傳遞請(qǐng)求和響應(yīng)對(duì)象。JSP頁(yè)面中所有的HTML元素,JSP小腳本以及JSP表達(dá)式在轉(zhuǎn)換階段都成為該方法的一部分。345類的加載和實(shí)例化調(diào)用jspInit()調(diào)用_jspService()將頁(yè)面實(shí)現(xiàn)類編譯成類文件后,Web容器調(diào)用類加載程序(classloader)將頁(yè)面實(shí)現(xiàn)類加載到內(nèi)存中。然后,容器調(diào)用頁(yè)面實(shí)現(xiàn)類的默認(rèn)構(gòu)造方法創(chuàng)建該類的一個(gè)實(shí)例。Web容器調(diào)用jspInit()初始化Servlet實(shí)例。該方法是在任何其他方法調(diào)用之前調(diào)用的,并在頁(yè)面生命期內(nèi)只調(diào)用一次。通常在該方法中完成初始化或只需一次的設(shè)置工作,如獲得資源及初始化JSP頁(yè)面中使用<%!...%>聲明的實(shí)例變量。JSP執(zhí)行過程3.2.26調(diào)用jspDestroy()當(dāng)容器決定停止該實(shí)例提供服務(wù)時(shí),它將調(diào)用jspDestroy(),這是在Servlet實(shí)例上調(diào)用的最后一個(gè)方法,它主要用來清理jspInit()獲得的資源。一般不需要實(shí)現(xiàn)jspInit()和jspDestroy(),因?yàn)樗鼈円呀?jīng)由基類實(shí)現(xiàn)了。但可以根據(jù)需要使用JSP的聲明標(biāo)簽<%!...%>覆蓋這兩個(gè)方法。注意,不能覆蓋_jspService(),因?yàn)樵摲椒ㄓ蒞eb容器自動(dòng)產(chǎn)生。JSP執(zhí)行過程3.2.2在3.1.1節(jié)中我們簡(jiǎn)要介紹了JSP指令,它用于向容器提供關(guān)于JSP頁(yè)面的總體信息。在JSP頁(yè)面中,指令是以“<%@”開頭,以“%>”結(jié)束的標(biāo)簽。指令有三種類型:page指令、include指令和taglib指令。下面我們?cè)敿?xì)介紹這三種指令的使用。3.3JSP指令
page指令用于告訴容器關(guān)于JSP頁(yè)面的總體特性,該指令適用于整個(gè)轉(zhuǎn)換單元。例如,下面的page指令通知容器頁(yè)面輸出的內(nèi)容類型和使用的字符集。教材中表3-4描述了page指令的常用的屬性。應(yīng)該了解page指令所有屬性以及它們的取值,但下面幾個(gè)屬性是最重要的:import、contentType、pageEncoding、session、errorPage與isErrorPage。<%@pagecontentType="text/html;charset=UTF-8"%>page指令3.3.1<%@pagecontentType="text/html;charset=UTF-8"%>contentType屬性用來指定JSP頁(yè)面輸出的MIME類型和字符集,MIME類型的默認(rèn)值是text/html,字符集的默認(rèn)值是UTF-8。MIME類型和字符集之間用分號(hào)分隔,如下所示。對(duì)于包含中文的JSP頁(yè)面,字符編碼指定為UTF-8或GB18030,如果頁(yè)面僅包含西文字符,字符編碼可以指定ISO-8859-1,如下所示。pageEncoding屬性指定JSP頁(yè)面的字符編碼,它的默認(rèn)值為UTF-8。如果設(shè)置了該屬性,則JSP頁(yè)面使用該屬性設(shè)置的字符集編碼;如果頁(yè)面中含有中文,應(yīng)該將該屬性值指定為UTF-8或GB18030,如下所示:1
contentType和pageEncoding屬性<%@pagecontentType="text/html;charset=ISO-8859-1"%<%@pagepageEncoding="UTF-8"%>page指令3.3.1import屬性的功能類似于Java程序的import語(yǔ)句,它是將import屬性值指定的類導(dǎo)入到頁(yè)面中。在轉(zhuǎn)換階段,容器對(duì)使用import屬性聲明的每個(gè)包都轉(zhuǎn)換成頁(yè)面實(shí)現(xiàn)類的一個(gè)import語(yǔ)句??梢栽谝粋€(gè)import屬性中導(dǎo)入多個(gè)包,包名用逗號(hào)分開即可,例如:為了增強(qiáng)代碼可讀性也可以使用多個(gè)page指令,如上面的page指令也可以寫成:由于在Java程序中import語(yǔ)句的順序是沒有關(guān)系的,因此這里import屬性的順序也沒有關(guān)系。另外,容器總是導(dǎo)入java.lang.*、jakarta.servlet.*、jakarta.servlet.http.*和jakarta.servlet.jsp.*包,所以不必明確地導(dǎo)入它們。2
import屬性<%@pageimport="java.util.*,java.text.*,com.boda.xy.*"%><%@pageimport="java.util.*"%><%@pageimport="java.text.*"%><%@pageimport="com.boda.xy.*"%>page指令3.3.1session屬性指示JSP頁(yè)面是否參加HTTP會(huì)話,其默認(rèn)值為true,在這種情況下容器將聲明一個(gè)隱含變量session(將在3.4節(jié)學(xué)習(xí)更多的隱含變量)。如果不希望頁(yè)面參加會(huì)話,可以明確地加入下面一行:3
session屬性<%@pagesession="false"%>page指令3.3.1在頁(yè)面執(zhí)行過程中,嵌入在頁(yè)面中的Java代碼可能拋出異常。與一般的Java程序一樣,在JSP頁(yè)面中也可以使用try-catch塊處理異常。然而,JSP規(guī)范定義了一種更好的方法,它可以使錯(cuò)誤處理代碼與主頁(yè)面代碼分離,從而提高異常處理機(jī)制的可重用性。在該方法中,JSP頁(yè)面使用page指令的errorPage屬性將異常代理給另一個(gè)包含錯(cuò)誤處理代碼的JSP頁(yè)面。在清單3.7的helloUser.jsp頁(yè)面中,errorHandler.jsp被指定為錯(cuò)誤處理頁(yè)面。4
errorPage與isErrorpage屬性page指令3.3.1<%@pagecontentType="text/html;charset=UTF-8"%><%@pageerrorPage="errorHandler.jsp"%><html><body><%if(request.getParameter("name")==null){thrownewRuntimeException("沒有指定name請(qǐng)求參數(shù)。");}%>你好!<%=request.getParameter("name")%></body></html>helloUser.jsp清單3.7page指令3.3.1對(duì)該JSP頁(yè)面的請(qǐng)求如果指定了name請(qǐng)求參數(shù)值,該頁(yè)面將正常輸出,如果沒有指定name請(qǐng)求參數(shù)值,將拋出一個(gè)異常,但它本身并沒有捕獲異常,而是通過errorPage屬性指示容器將錯(cuò)誤處理代理給頁(yè)面errorHandler.jsp。errorPage的屬性值不必是JSP頁(yè)面,它也可以是靜態(tài)的HTML頁(yè)面,例如:顯然,在errorHandler.html文件中不能編寫小腳本或表達(dá)式產(chǎn)生動(dòng)態(tài)信息。isErrorPage屬性指定當(dāng)前頁(yè)面是否作為其他JSP頁(yè)面的錯(cuò)誤處理頁(yè)面。isErrorPage屬性的默認(rèn)值為false。如上例使用的errorHandler.jsp頁(yè)面中該屬性必須明確設(shè)置為true,如下所示。<%@pageerrorPage="errorHandler.html"%>helloUser.jsp清單3.7page指令3.3.1<%@pagecontentType="text/html;charset=UTF-8"%><%@pageisErrorPage="true"%><html><body><table><tr><td><imgsrc="images/error.png"width=150height=100/></td><td>頁(yè)面發(fā)生了下面錯(cuò)誤:<%=exception.getMessage()%><br>
請(qǐng)重試!</td></tr></table></body></html>在這種情況下,容器在頁(yè)面實(shí)現(xiàn)類中聲明一個(gè)名為exception的隱含變量。一般來說,為所有的JSP頁(yè)面中指定一個(gè)錯(cuò)誤頁(yè)面是一個(gè)良好的編程習(xí)慣,這可以防止在客戶端顯示不希望的錯(cuò)誤消息。errorHandler.jsp清單3.8page指令3.3.1代碼的可重用性是軟件開發(fā)的一個(gè)重要原則。使用可重用的組件可提高應(yīng)用程序的生產(chǎn)率和可維護(hù)性。JSP規(guī)范定義了一些允許重用Web組件的機(jī)制,其中包括在JSP頁(yè)面中包含另一個(gè)Web組件的內(nèi)容或輸出。這可通過兩種方式之一實(shí)現(xiàn):靜態(tài)包含或動(dòng)態(tài)包含。include指令用于把另一個(gè)文件(HTML、JSP等)的內(nèi)容包含到當(dāng)前頁(yè)面中,這種包含稱為靜態(tài)包含。靜態(tài)包含是在JSP頁(yè)面轉(zhuǎn)換階段將另一個(gè)文件的內(nèi)容包含到當(dāng)前JSP頁(yè)面中。使用JSP的include指令完成這一功能,它的語(yǔ)法為:file是include指令唯一的屬性,它是指被包含的文件。文件使用相對(duì)路徑指定,相對(duì)路徑或者以斜杠(/)開頭,是相對(duì)于Web應(yīng)用程序文檔根目錄的路徑,或者不以斜杠開頭,它是相對(duì)于當(dāng)前JSP文件的路徑。<%@includefile="relativeURL"%>include指令3.3.2下面是include指令的一個(gè)例子。由于被包含文件的內(nèi)容成為主頁(yè)面代碼的一部分,因此,每個(gè)頁(yè)面都可以訪問在另一個(gè)頁(yè)面中定義的變量,它們也共享所有的隱含變量。清單3.9的hello.jsp頁(yè)面中包含了response.jsp頁(yè)面。<%@includefile="copyright.html"%>include指令3.3.2<%@pagecontentType="text/html;charset=utf-8"%><html><head><title>Hello</title></head><%!Stringusernname="Duke";%><body><imgsrc="images/duke.gif">
我的名字叫Duke,你的名字叫什么?<formaction=""method="post"><inputtype="text"name="username"size="25"><inputtype="submit"value="提交"><inputtype="reset"value="重置"></form>
<%@includefile="response.jsp"%></body></html>
下面代碼是被包含頁(yè)面response.jsp。hello.jsp清單3.9include指令3.3.2在hello.jsp頁(yè)面中聲明了一個(gè)變量username,并使用include指令包含了response.jsp頁(yè)面。在response.jsp頁(yè)面中使用了hello.jsp頁(yè)面中聲明的變量username。程序的運(yùn)行結(jié)果如圖3-5所示。<%@pagecontentType="text/html;charset=utf-8"%><%username=request.getParameter("username");%><h4style="color:blue">你好,<%=username%>!</h4>圖3-5hello.jsp的運(yùn)行結(jié)果清單3.8response.jsp清單3.10include指令3.3.2taglib指令用來指定在JSP頁(yè)面中使用標(biāo)準(zhǔn)標(biāo)簽或自定義標(biāo)簽的前綴與標(biāo)簽庫(kù)的URI,下面是taglib指令的例子。關(guān)于指令的使用需注意下面幾個(gè)問題:標(biāo)簽名、屬性名及屬性值都是大小寫敏感的。屬性值必須使用一對(duì)單引號(hào)或雙引號(hào)括起來。在等號(hào)(=)與值之間不能有空格。<%@taglibprefix="c"uri="/jsp/jstl/core"%>taglib指令3.3.3在JSP頁(yè)面的轉(zhuǎn)換階段,Web容器在頁(yè)面實(shí)現(xiàn)類的_jspService()方法中聲明并初始化一些變量,可以在JSP頁(yè)面小腳本或表達(dá)式中直接使用這些變量。這些變量是由容器隱含聲明的,所以一般被稱為隱含變量或隱含對(duì)象(implicitobjects)。表3-3給出了頁(yè)面實(shí)現(xiàn)類中聲明的全部9個(gè)隱含變量。表3-3JSP隱含變量隱含變量類或接口說明requestjakarta.servlet.http.HttpServletRequest接口引用頁(yè)面的當(dāng)前請(qǐng)求對(duì)象responsejakarta.servlet.http.HttpServletResponse接口用來向客戶發(fā)送一個(gè)響應(yīng)outjakarta.servlet.jsp.JspWriter類引用頁(yè)面輸出流pagejava.lang.Object類引用頁(yè)面的Servlet實(shí)例applicationjakarta.servlet.ServletContext接口引用Web應(yīng)用程序上下文sessionjakarta.servlet.http.HttpSession接口引用用戶會(huì)話pageContextjakarta.servlet.jsp.PageContext類引用頁(yè)面上下文configjakarta.servlet.ServletConfig接口引用Servlet的配置對(duì)象exceptionjava.lang.Throwable類用來處理錯(cuò)誤3.4JSP隱含變量下面來看在JSP頁(yè)面實(shí)現(xiàn)類中是如何聲明這些變量的。以todayDate.jsp頁(yè)面為例,在轉(zhuǎn)換階段,Web容器自動(dòng)將該頁(yè)面轉(zhuǎn)換成一個(gè)名為todayDate_jsp.java的類文件,在該類的_jspService()方法中聲明了這些變量。下面詳細(xì)討論幾個(gè)最常用隱含變量的使用。注意,這些隱含變量只能在JSP頁(yè)面的JSP小腳本和JSP表達(dá)式中使用。3.4JSP隱含變量request和response分別是HttpServletRequest和HttpServletResponse類型的隱含變量,當(dāng)頁(yè)面實(shí)現(xiàn)類向客戶提供服務(wù)時(shí),它們作為參數(shù)傳遞給_jspService()方法。在JSP頁(yè)面中使用它們與Servlet在中使用完全一樣,即用來分析請(qǐng)求和發(fā)送響應(yīng),如下代碼所示??梢栽贘SP小腳本中使用隱含變量,也可以在JSP表達(dá)式中使用隱含變量。<%Stringuri=request.getRequestURI();
response.setContentType("text/html;charset=UTF-8");%>請(qǐng)求方法為:<%=request.getMethod()%><br>請(qǐng)求URI為:<%=uri%><br>協(xié)議為:<%=request.getProtocol()%>request與response變量3.4.1out是jakarta.servlet.jsp.JspWriter類型的隱含變量,JspWriter類擴(kuò)展了java.io.Writer并繼承了所有重載的write()方法。在此基礎(chǔ)上,還增加了其自己的一組print()和println()來打印輸出所有的基本數(shù)據(jù)類型、字符串以及用戶定義的對(duì)象??梢栽谛∧_本中直接使用它,也可以在表達(dá)式中間接使用它產(chǎn)生HTML代碼。對(duì)上面兩行代碼,在頁(yè)面實(shí)現(xiàn)類中都使用out.print()語(yǔ)句輸出。<%out.print("HelloWorld!");%><%="HelloUser!"%>out變量3.4.2application是jakarta.servlet.ServletContext類型的隱含變量,它是JSP頁(yè)面所在的Web應(yīng)用程序的上下文的引用(在第2章中曾討論了ServletContext接口)。在Servlet中,我們可以使用如下代碼訪問ServletContext對(duì)象。在JSP頁(yè)面中,使用下面application對(duì)象的getAttribute()方法檢索存儲(chǔ)在上下文中的數(shù)據(jù)。LocalDatetoday=LocalDate.now();ServletContextcontext=getServletContext();context.setAttribute("today",today);<%=application.getAttribute("today")%>application變量3.4.3session是jakarta.servlet.http.HttpSession類型的隱含變量,它在JSP頁(yè)面中表示HTTP會(huì)話對(duì)象。要使用會(huì)話對(duì)象,必須要求JSP頁(yè)面參加會(huì)話,即要求將JSP頁(yè)面的page指令的session屬性值設(shè)置為true。默認(rèn)情況下,session屬性的值為true,所以即使沒有指定page指令,該變量也會(huì)被聲明并可以使用。下面代碼可在頁(yè)面中輸出當(dāng)前會(huì)話的ID。然而,如果明確將page指令的session屬性設(shè)置為false,容器將不會(huì)聲明該變量,對(duì)該變量的使用將產(chǎn)生錯(cuò)誤,如下所示。會(huì)話ID=<%=session.getId()%><%@pagesession="false"%>session變量3.4.4如果一個(gè)頁(yè)面是錯(cuò)誤處理頁(yè)面,即頁(yè)面中包含下面的page指令。則頁(yè)面實(shí)現(xiàn)類中將聲明一個(gè)exception隱含變量,它是java.lang.Throwable類型的隱含變量,它被用來作為其他頁(yè)面的錯(cuò)誤處理器。為使頁(yè)面能夠使用exception變量,必須在page指令中將isErrorPage的屬性值設(shè)置為true,如下所示。<%@pageisErrorPage="true"%><%@pageisErrorPage="true"%><html><body>
頁(yè)面發(fā)生了下面錯(cuò)誤:<br><%=exception.toString()%></body></html>上述代碼中,將page指令的isErrorPage屬性設(shè)置為true,容器明確定義了exception變量。該變量指向使用該頁(yè)面作為錯(cuò)誤處理器的頁(yè)面拋出的未捕獲的異常對(duì)象。如果去掉第一行,容器將不會(huì)明確定義exception變量,因?yàn)閕sErrorPage屬性的默認(rèn)值為false,此時(shí)使用exception變量將產(chǎn)生錯(cuò)誤。exception變量3.4.5config是jakarta.servlet.ServletConfig類型的隱含變量。在第2章曾討論過,可通過DD文件為Servlet傳遞一組初始化參數(shù),然后在Servlet中使用ServletConfig對(duì)象檢索這些參數(shù)。類似地,也可以為JSP頁(yè)面?zhèn)鬟f一組初始化參數(shù),這些參數(shù)在JSP頁(yè)面中可以使用config隱含變量來檢索。要實(shí)現(xiàn)這一點(diǎn),應(yīng)該首先在DD文件web.xml中使用<servlet-name>聲明一個(gè)Servlet,然后,使用<jsp-file>元素使其與JSP文件關(guān)聯(lián)。對(duì)該命名的Servlet的所有的初始化參數(shù)就可以在JSP頁(yè)面中通過config隱含變量使用。config變量3.4.6<servlet><servlet-name>initTestServlet</servlet-name><jsp-file>/initTest.jsp</jsp-file><init-param><param-name>company</param-name><param-value>BeijingNewTechonologyCO.,LTD</param-value></init-param><init-param><param-name>email</param-name><param-value>smith@</param-value></init-param></servlet><servlet-mapping><servlet-name>initTestServlet</servlet-name><url-pattern>/initTest.jsp</url-pattern></servlet-mapping>config變量3.4.6代碼聲明了一個(gè)名為initTestServlet的Servlet并將它映射到/initTest.jsp文件,同時(shí)為該Servlet指定了company和email初始化參數(shù),該參數(shù)可以在initTest.jsp文件中使用隱含變量config檢索到,如下所示。公司名稱:<%=config.getInitParameter("company")%><br>郵箱地址:<%=config.getInitParameter("email")%>config變量3.4.6pageContext是jakarta.servlet.jsp.PageContext類型的隱含變量,它是一個(gè)頁(yè)面上下文對(duì)象。PageContext類是一個(gè)抽象類,容器廠商提供了一個(gè)具體子類(如JspContext),它有下面三個(gè)作用。(1)存儲(chǔ)隱含對(duì)象的引用。pageContext對(duì)象是作為管理所有在JSP頁(yè)面中使用的其他對(duì)象的一個(gè)地方,包括用戶定義的和隱含的對(duì)象,并且它提供了一個(gè)訪問方法來檢索它們。如果查看JSP頁(yè)面生成的Servlet代碼,會(huì)看到session、application、config與out這些隱含變量是調(diào)用pageContext對(duì)象的相應(yīng)方法得到的。(2)提供了在不同作用域內(nèi)返回或設(shè)置屬性的方便的方法。3.7節(jié)將詳細(xì)說明。(3)提供了forward()和include()實(shí)現(xiàn)將請(qǐng)求轉(zhuǎn)發(fā)到另一個(gè)資源和將一個(gè)資源的輸出包含到當(dāng)前頁(yè)面中的功能。pageContext變量3.4.7例如,從Servlet中將請(qǐng)求轉(zhuǎn)發(fā)到另一個(gè)資源,需要寫下面兩行代碼。在JSP頁(yè)面中,通過使用pageContext變量?jī)H需一行就可以完成上述功能。RequestDispatcherrd=request.getRequestDispatcher("other.jsp");rd.forward(request,response);<%pageContext.forward("other.jsp");%>pageContext變量3.4.7JSP
動(dòng)作(actions)是頁(yè)面發(fā)給容器的命令,它指示容器在頁(yè)面執(zhí)行期間完成某種任務(wù)。動(dòng)作的一般語(yǔ)法為:動(dòng)作是一種標(biāo)簽,在動(dòng)作標(biāo)簽中,prefix為前綴名,actionName為動(dòng)作名,attribute-list表示針對(duì)該動(dòng)作的一個(gè)或多個(gè)屬性/值對(duì)。在JSP頁(yè)面中可以使用三種動(dòng)作:JSP標(biāo)準(zhǔn)動(dòng)作,標(biāo)準(zhǔn)標(biāo)簽庫(kù)(JSTL)中的動(dòng)作和用戶自定義動(dòng)作。<prefix:actionNameattribute-list/>3.5JSP動(dòng)作jsp:include,在當(dāng)前頁(yè)面中包含另一個(gè)頁(yè)面的輸出。jsp:forward,將請(qǐng)求轉(zhuǎn)發(fā)到指定的頁(yè)面。jsp:useBean,查找或創(chuàng)建一個(gè)JavaBean對(duì)象。jsp:setProperty,設(shè)置JavaBean對(duì)象的屬性值。jsp:getProperty,返回JavaBean對(duì)象的屬性值。下面是常用的JSP標(biāo)準(zhǔn)動(dòng)作:下面介紹<jsp:include>和<jsp:forward>兩個(gè)動(dòng)作,3.8節(jié)介紹有關(guān)JavaBean使用的3個(gè)動(dòng)作。3.5JSP動(dòng)作在3.3.2節(jié)討論了使用include指令實(shí)現(xiàn)的靜態(tài)包含。本節(jié)討論使用JSP的<jsp:include>動(dòng)作實(shí)現(xiàn)動(dòng)態(tài)包含。動(dòng)態(tài)包含是在請(qǐng)求時(shí)將另一個(gè)頁(yè)面的輸出包含到主頁(yè)面的輸出中。該動(dòng)作的格式如下:這里page屬性是必須的,其值必須是一個(gè)相對(duì)URL,它指向任何靜態(tài)或動(dòng)態(tài)Web組件,包括JSP頁(yè)面、Servlet等。可選的flush屬性是指在將控制轉(zhuǎn)向被包含頁(yè)面之前是否刷新主頁(yè)面。flush屬性的默認(rèn)值為false。<jsp:includepage="relativeURL"flush="true|false"/><jsp:include>動(dòng)作3.5.1例如,下面一行指示容器把另一個(gè)JSP頁(yè)面copyright.jsp的輸出包含在當(dāng)前JSP頁(yè)面的輸出中:在功能上<jsp:include>動(dòng)作的語(yǔ)義與RequestDispatcher接口的include()的語(yǔ)義相同,因此,在Servlet中使用下面代碼實(shí)現(xiàn)包含。<jsp:includepage="copyright.jsp"flush="true"/>RequestDispatcherrd=request.getRequestDispatcher("other.jsp");rd.include(request,response);<jsp:include>動(dòng)作3.5.1<%@pagecontentType="text/html;charset=UTF-8"%><html><head><title>Hello</title></head><body><imgsrc="images/duke.gif">
我的名字叫Duke,你的名字叫什么?<formaction=""method="post"><inputtype="text"name="username"size="25"><inputtype="submit"value="提交"><inputtype="reset"value="重置">清單3.8hello2.jsp清單3.11<jsp:include>動(dòng)作3.5.1
</form><%StringuserName=request.getParameter("username");request.setAttribute("username",userName);%><jsp:includepage="response2.jsp"/></body></html>
清單3.11產(chǎn)生的輸出結(jié)果與清單3.9相同,但它使用了動(dòng)態(tài)包含。主頁(yè)面hello2.jsp通過調(diào)用request.setAttribute()把userName對(duì)象添加到請(qǐng)求作用域中,然后,被包含的頁(yè)面response2.jsp通過調(diào)用request.getAttribute()檢索該對(duì)象并使用表達(dá)式輸出。清單3.8hello2.jsp清單3.11<jsp:include>動(dòng)作3.5.1這里,在hello2.jsp文件中的隱含變量request與response2.jsp文件中的隱含變量request是請(qǐng)求作用域內(nèi)的同一個(gè)對(duì)象。對(duì)<jsp:forward>動(dòng)作可以使用相同的機(jī)制。<%@pagecontentType="text/html;charset=UTF-8"%><%Stringusername=(String)request.getAttribute("username");%><h4style="color:blue">你好,<%=username%>!</h4>清單3.8response2.jsp清單3.12<jsp:include>動(dòng)作3.5.1page屬性的值為轉(zhuǎn)發(fā)到的組件的相對(duì)URL,它可以使用請(qǐng)求時(shí)屬性表達(dá)式。它與<jsp:include>動(dòng)作的不同之處在于,當(dāng)轉(zhuǎn)發(fā)到的頁(yè)面處理完輸出后,并不將控制轉(zhuǎn)回主頁(yè)面。使用<jsp:forward>動(dòng)作,主頁(yè)面也不能包含任何輸出。下面的<jsp:forward>動(dòng)作將控制轉(zhuǎn)發(fā)到other.jsp頁(yè)面。<jsp:forwardpage="relativeURL"/>使用<jsp:forward>動(dòng)作把請(qǐng)求轉(zhuǎn)發(fā)到其他組件,然后由轉(zhuǎn)發(fā)到的組件把響應(yīng)發(fā)送給客戶,該動(dòng)作的格式為:<jsp:forwardpage="other.jsp"/><jsp:forward>動(dòng)作3.5.2在JSP頁(yè)面中使用<jsp:forward>標(biāo)準(zhǔn)動(dòng)作實(shí)際上實(shí)現(xiàn)的是控制邏輯的轉(zhuǎn)移。在MVC設(shè)計(jì)模式中,控制邏輯應(yīng)該由控制器(Servlet)實(shí)現(xiàn)而不應(yīng)該由視圖(JSP頁(yè)面)實(shí)現(xiàn)。因此,盡可能不在JSP頁(yè)面中使用<jsp:forward>動(dòng)作轉(zhuǎn)發(fā)請(qǐng)求。RequestDispatcherrd=request.getRequestDispatcher("other.jsp");rd.forward(request,response);在功能上<jsp:forward>的語(yǔ)義與RequestDispatcher接口的forward()的語(yǔ)義相同,因此它的功能與在Servlet中實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā)的功能等價(jià)。<jsp:forward>動(dòng)作3.5.2Web應(yīng)用程序界面應(yīng)該具有統(tǒng)一的視覺效果,或者說所有的頁(yè)面都有同樣的整體布局。一種比較典型的布局通常包含標(biāo)題部分、腳注部分、菜單、廣告區(qū)和主體實(shí)際內(nèi)容部分。設(shè)計(jì)這些頁(yè)面時(shí)如果在所有的頁(yè)面中都復(fù)制相同的代碼,這不僅不符合模塊化設(shè)計(jì)原則,將來若修改布局也非常麻煩。使用JSP技術(shù)提供的include指令(<%@include…)包含靜態(tài)文件和include動(dòng)作(<jsp:include…>)包含動(dòng)態(tài)資源就可以實(shí)現(xiàn)一致的頁(yè)面布局。下面的home.jsp頁(yè)面使用<div>標(biāo)簽和include指令實(shí)現(xiàn)頁(yè)面布局。3.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<%@pagecontentType="text/html;charset=UTF-8"%><html><head><title>百斯特電子商城</title><linkhref="css/style.css"rel="stylesheet"type="text/css"/></head><body><divclass="container"><divclass="header"><%@includefile="/WEB-INF/jsp/header.jsp"%></div><divclass="topmenu"><%@includefile="/WEB-INF/jsp/topmenu.jsp"%></div>清單3.8home.jsp清單3.133.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<divclass="mainContent"class="clearfix"><divclass="leftmenu"><%@includefile="/WEB-INF/jsp/leftmenu.jsp"%></div><divclass="content"><%@includefile="/WEB-INF/jsp/content.jsp"%></div></div><divclass="footer"><%@includefile="/WEB-INF/jsp/footer.jsp"%></div></div></body></html>清單3.8home.jsp清單3.133.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局被包含的JSP文件存放在WEB-INF/jsp目錄中,WEB-INF中資源只能被服務(wù)器訪問,這樣可以防止這些JSP頁(yè)面被客戶直接訪問。訪問index.jsp頁(yè)面,輸出結(jié)果如圖3-7所示。圖3-7index.jsp頁(yè)面運(yùn)行結(jié)果該頁(yè)面使用了CSS對(duì)頁(yè)面進(jìn)行布局,樣式表文件style.css代碼如下。清單3.8home.jsp清單3.133.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局@CHARSET"UTF-8";body,div,ul{margin:0;padding:0;}p{text-align:center;}a:link{color:blue;text-decoration:none;}a:hover{ background-color:gray;}.container{width:1004px;margin:0auto;}清單3.8style.css清單3.143.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局.header{margin-bottom:5px;}.topmenu{margin-bottom:5px;}.mainContent{margin:005px0;}.leftmenu{float:left;width:120px;padding:5px05px30px;}.leftmenuul{list-style:none;}清單3.8style.css清單3.143.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局.leftmenup{margin:0010px0;}.content{float:left;width:700px;}.footer{clear:both;height:60px;}下面是標(biāo)題頁(yè)面header.jsp、頂部菜單頁(yè)面topmenu.jsp、左側(cè)菜單頁(yè)面leftmenu.jsp、主體內(nèi)容頁(yè)面content.jsp和頁(yè)腳頁(yè)面footer.jsp。清單3.8style.css清單3.143.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<%@pagecontentType="text/html;charset=UTF-8"language="java"><scriptlanguage="JavaScript"type="text/javascript">functionregister(){open("/helloweb/register.jsp","register");}</script><p><imgsrc="images/head.jpg"/></p>清單3.8header.jsp清單3.153.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<%@pagecontentType="text/html;charset=UTF-8"language="java"><tableborder='0'><tr><td><ahref="/helloweb/index.jsp">【首頁(yè)】</a></td><td><formaction="login.do"method="post"name="login">
用戶名<inputtype="text"name="username"size="13"/>
密
碼<inputtype="password"name="password"size="13"/><inputtype="submit"name="submit"value="登
錄"><inputtype="button"name="register"value="注
冊(cè)"onclick="check();"></form></td><td><ahref="showOrder">我的訂單</a>|</td><td><ahref="showCart">查看購(gòu)物車</a></td></tr></table>清單3.8topmenu.jsp清單3.163.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<%@pagecontentType="text/html;charset=UTF-8"language="java"><p><b>商品分類</b></p><ul><li><ahref="showProduct?category=101">手機(jī)數(shù)碼</a></li><li><ahref="showProduct?category=102">家用電器</a></li><li><ahref="showProduct?category=103">汽車用品</a></li><li><ahref="showProduct?category=104">服飾鞋帽</a></li><li><ahref="showProduct?category=105">運(yùn)動(dòng)健康</a></li></ul>清單3.8leftmenu.jsp清單3.173.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<%@pagecontentType="text/html;charset=UTF-8"language="java"><tableborder="0"><tr><tdcolspan="2"><b><i>${sessionScope.message}</i></b></td></tr><tr><tdcolspan="4">百斯特11.11!手機(jī)價(jià)格真正低,買華為手機(jī)送蘋果13!</td></tr><tr><tdwidth=20%><imgsrc="images/phone.jpg"width=100></td>清單3.8content.jsp清單3.183.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<td><pstyle="text-indent:2em">HUAWEIMate40Pro麒麟90005GSoC芯片
超感知徠卡電影影像8GB+256GB秘銀色5G全網(wǎng)通特價(jià):5288元</p><imgsrc="images/gw.jpg"></td>
<tdwidth=20%><imgsrc="images/comp.jpg"width=120></td><td><pstyle="text-indent:2em">聯(lián)想(Lenovo)G460AL-ITH15.0英寸
筆記本電腦(i3-370M2G500G512獨(dú)顯DVD刻錄攝像頭Win7)特價(jià):3199元!</p><imgsrc="images/gw.jpg"></td></tr></table>清單3.8content.jsp清單3.183.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局<%@pagecontentType="text/html;charset=UTF-8"language="java"><hr/><p>關(guān)于我們|聯(lián)系我們|人才招聘|友情鏈接</p><p>版權(quán)所有©2024百斯特電子商城公司,電話:8899123.</p>在上面這些被包含的文件中,沒有使用<html>和<body>等標(biāo)簽。實(shí)際上,它們不是完整的頁(yè)面,而是頁(yè)面片段,因此文件名也可以完全不使用.jsp作為擴(kuò)展名,而可以使用任何的擴(kuò)展名,如.htmlf或.jspf等。由于被包含的文件是由服務(wù)器訪問的,因此可以將被包含的文件存放到Web應(yīng)用程序的WEB-INF目錄中,這樣可以防止用戶直接訪問被包含的文件。清單3.8footer.jsp清單3.193.6案例學(xué)習(xí):使用包含設(shè)計(jì)頁(yè)面布局
與任何Java程序一樣,Web應(yīng)用程序在執(zhí)行過程中可能發(fā)生各種錯(cuò)誤。例如,網(wǎng)絡(luò)問題可能引發(fā)SQLException異常,在讀取文件時(shí)可能因?yàn)槲募p壞發(fā)生IOException異常。如果這些異常沒有被適當(dāng)處理,Web容器將產(chǎn)生一個(gè)InternalServerError頁(yè)面,給用戶顯示一個(gè)長(zhǎng)長(zhǎng)的棧跟蹤。這在產(chǎn)品環(huán)境下通常是不可接受的。3.7錯(cuò)誤處理
可以在web.xml文件中為整個(gè)Web應(yīng)用配置錯(cuò)誤處理頁(yè)面。使用這種方法還可以根據(jù)異常類型的不同或HTTP錯(cuò)誤碼的不同配置錯(cuò)誤處理頁(yè)面。在web.xml文件中配置錯(cuò)誤頁(yè)面需要使用<error>元素,它有三個(gè)子元素:<error-code>:指定一個(gè)HTTP錯(cuò)誤代碼,如404。<exception-type>:指定一種Java異常類型(使用完全限定名)。<location>:指定要被顯示的資源位置。該元素值必須以“/”開頭。聲明式錯(cuò)誤處理3.7.1下面代碼為HTTP的狀態(tài)碼404配置了一個(gè)錯(cuò)誤處理頁(yè)面。<error><error-code>404</error-code>
<location>/errors/notFoundError.html</location></error>下面代碼聲明了一個(gè)處理SQLException異常的錯(cuò)誤頁(yè)面。<error><exception-type>java.sql.SQLException</exception-type><location>/errors/sqlError.html</location></error>聲明式錯(cuò)誤處理3.7.1還可以像下面這樣聲明一個(gè)更通用的處理頁(yè)面。<error>
<exception-type>java.lang.Throwable</exception-type><location>/errors/errorPage.html</location></error> Throwable類是所有異常類的根類,因此對(duì)沒有明確指定錯(cuò)誤處理頁(yè)面的異常,都將由該頁(yè)面處理。注意,在<error>元素中,<error-code>和<exception-type>不能同時(shí)使用。<location>元素的值必須以斜杠(/)開頭,它是相對(duì)于Web應(yīng)用程序的上下文根目錄。另外,如果在JSP頁(yè)面中使用page指令的errorPage屬性指定了錯(cuò)誤處理頁(yè)面,則errorPage屬性指定的頁(yè)面優(yōu)先。聲明式錯(cuò)誤處理3.7.1在前面例子中,我們使用HTML頁(yè)面作為異常處理頁(yè)面。HTML是靜態(tài)頁(yè)面,不能為用戶提供有關(guān)異常的信息。我們可以使用Servlet或JSP作為異常處理頁(yè)面。下面代碼使用Servlet處理403錯(cuò)誤碼,使用JSP頁(yè)面處理SQLException異常。<error><error-code>403</error-code>
<location>/errorHandler-servlet</location></error><error>
<exception-type>java.sql.SQLException</exception-type><location>/errors/sqlError.jsp</location></error>使用Servlet和JSP頁(yè)面處理錯(cuò)誤3.7.2為了在異常處理的Servlet或JSP頁(yè)面中分析異常原因并產(chǎn)生詳細(xì)的響應(yīng)信息,Web容器在將控制轉(zhuǎn)發(fā)到錯(cuò)誤頁(yè)面前在請(qǐng)求對(duì)象(request)中定義了若干屬性。下面代碼顯示了MyErrorHandlerServlet的doGet()方法,它使用了這些屬性在產(chǎn)生的錯(cuò)誤頁(yè)面中包含有用的錯(cuò)誤信息。publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType("text/html;charset=UTF-8");PrintWriterout=response.getWriter();out.println("<html>");out.println("<head><title>ErrorDemo</title></head>");out.println("<boy>");Stringcode=""+request.getAttribute("jakatar.servlet.error.status_code");使用Servlet和JSP頁(yè)面處理錯(cuò)誤3.7.2if("403".equals(code){out.println("<h3>對(duì)不起,您無權(quán)訪問該頁(yè)面!</h3>");out.println("<h3>請(qǐng)登錄系統(tǒng)!</h3>");}else{out.println("<h3>對(duì)不起,我們無法處理您的請(qǐng)求!</h3>");out.println("請(qǐng)將該錯(cuò)誤報(bào)告給管理員admin@!"+request.getAttribute("jakatar.servlet.error.request_uri"));}out.println("</body>");out.println("</html>");}上述Servlet根據(jù)錯(cuò)誤碼產(chǎn)生一個(gè)自定義的HTML頁(yè)面。除了標(biāo)準(zhǔn)的異常外,Web應(yīng)用程序還可能定義自己的業(yè)務(wù)邏輯異常。使用Servlet和JSP頁(yè)面處理錯(cuò)誤3.7.2在Web應(yīng)用中經(jīng)常需要將數(shù)據(jù)存儲(chǔ)在某個(gè)作用域中,然后在JSP頁(yè)面中使用它們。有4種作用域(scope)對(duì)象,分別稱為應(yīng)用作用域、會(huì)話作用域、請(qǐng)求作用域和頁(yè)面作用域,它們的類型分別是ServletContext、HttpSession、HttpServletRequest和PageContext,這4種個(gè)作用域如表3-5所示。在JSP頁(yè)面中,用戶定義的所有對(duì)象都處
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 安裝工程授權(quán)委托書格式樣本3篇
- 搬運(yùn)裝卸合同3篇
- 安徽離婚協(xié)議書新版本3篇
- 房屋買賣合同法律條例3篇
- 文藝演出服裝道具租賃合同3篇
- 工業(yè)試驗(yàn)設(shè)備安裝工程合同書3篇
- 房屋買賣建筑工程保險(xiǎn)合同3篇
- 體育場(chǎng)館建設(shè)土石方工程施工合同
- 鐵路維修機(jī)械臺(tái)班施工合同
- 創(chuàng)意園區(qū)物業(yè)客服人員聘用合同
- 廣東省異地就醫(yī)備案登記表
- --動(dòng)車所建設(shè)工程施工組織設(shè)計(jì)
- 2022年《藝術(shù)學(xué)概論》知識(shí)點(diǎn)超經(jīng)典總結(jié)
- PICC沖封管的SOP.pptx
- 貝朗標(biāo)準(zhǔn)化課程CRRT治療策略概述
- 渝價(jià)〔2013〕430號(hào)
- 護(hù)士延續(xù)注冊(cè)申請(qǐng)表范本
- ASME標(biāo)準(zhǔn)鋼號(hào)和中國(guó)鋼號(hào)對(duì)照表
- 頸靜脈球體瘤
- 2022年2022年跨欄教案-程璐上交
- 青海省互助豐臺(tái)溝隧道施工組織設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論