java基礎(chǔ)全套課件_第1頁(yè)
java基礎(chǔ)全套課件_第2頁(yè)
java基礎(chǔ)全套課件_第3頁(yè)
java基礎(chǔ)全套課件_第4頁(yè)
java基礎(chǔ)全套課件_第5頁(yè)
已閱讀5頁(yè),還剩596頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第2章學(xué)習(xí)JSPJSP完全來(lái)以Java語(yǔ)言開(kāi)發(fā),是純Java的應(yīng)用。JSP經(jīng)服務(wù)器轉(zhuǎn)換后與一般的Java類完全相同,而這一特性也使JSP具有了Java所具備的所有優(yōu)勢(shì),如面向?qū)ο?、?jiǎn)單性、跨平臺(tái)等等。J2EE提供了良好的框架和指南,在此標(biāo)準(zhǔn)中開(kāi)發(fā)程序?qū)哟胃忧宄_(kāi)發(fā)更有效率,產(chǎn)品的可用性、可移植性更好。本章將詳細(xì)介紹JSP的工作原理和如何使用JSP。2.1環(huán)境準(zhǔn)備這一節(jié)里主要介紹如何安裝一個(gè)JSP運(yùn)行環(huán)境,包括安裝JDK和安裝運(yùn)行JSP的服務(wù)器Tomcat以及安裝開(kāi)發(fā)工具M(jìn)yEclipse。2.1.1安裝JDKJDK(JavaDevelopmentKit)java開(kāi)發(fā)包,又叫做J2SE(Java2SDKStandardEdition),是SUN公司免費(fèi)提供的,可以從SUN的Java網(wǎng)站上下載到,地址:/j2se/downloads.html,JDK當(dāng)前最新的版本是J2SDK1.6,載頁(yè)面中列出了符合多種操作系統(tǒng)的JDK,這里應(yīng)該選擇Windows平臺(tái)的JDK。下載好的JDK是一個(gè)可執(zhí)行安裝程序,可以自定義安裝路徑選擇只安裝某些組件,推薦全部按默認(rèn)值安裝。2.1.2安裝TomcatTomcat是一個(gè)免費(fèi)并且開(kāi)源的JSP服務(wù)器,它是Apache軟件基金會(huì)的Jakarta項(xiàng)目中的一個(gè)核心項(xiàng)目,由Apache、SUN和其他一些公司及個(gè)人共同開(kāi)發(fā)而成。由于有了SUN的參與和支持,最新的Servlet和JSP規(guī)范總是能在Tomcat中得到體現(xiàn)。因?yàn)門omcat技術(shù)先進(jìn)、性能穩(wěn)定,簡(jiǎn)單易用,成為目前應(yīng)用最廣泛的JSP服務(wù)器。本書所有例子都將以Tomcat為JSP服務(wù)器。2.1.3安裝MyEclipseEclipse是一種可擴(kuò)展的開(kāi)放源代碼集成開(kāi)發(fā)環(huán)境。是一款非常受歡迎的Java開(kāi)發(fā)工具,使用它開(kāi)發(fā)人員是最多的。Eclipse的最大特點(diǎn)是它能接受各種開(kāi)放源代碼插件。而MyEclipse是對(duì)Eclipse的擴(kuò)展,集成了很多常用的經(jīng)典插件,支持HTML,Struts,JSF,CSS,Javascript,SQL,Hibernate利用它可以在數(shù)據(jù)庫(kù)和J2EE的開(kāi)發(fā)、發(fā)布,極大的提高工作效率。2.2第一個(gè)JSP程序本節(jié)介紹如何在Tomcat服務(wù)器上創(chuàng)建和發(fā)布JSP程序。這里首先講解Tomcat的目錄結(jié)構(gòu)以及Web應(yīng)用的目錄結(jié)構(gòu),接著介紹如何將JSP部署到Web應(yīng)用中,運(yùn)行第一個(gè)JSP程序并測(cè)試它。2.2.1JSP的工作原理JSP服務(wù)器管理JSP頁(yè)面有兩個(gè)階段:轉(zhuǎn)換階段(translationphase)和執(zhí)行階段(executionphase)。當(dāng)有一個(gè)客戶請(qǐng)求到來(lái)時(shí),JSP服務(wù)器檢驗(yàn)JSP頁(yè)面的語(yǔ)法是否正確,將JSP頁(yè)面轉(zhuǎn)換為Servlet(Servlet就是用Java語(yǔ)言實(shí)現(xiàn)的CGI程序,后面章節(jié)將詳細(xì)介紹)源文件,然后調(diào)用javac工具類編譯Servlet源文件生成class文件,這一階段是轉(zhuǎn)換階段。2.2.2JSP目錄結(jié)構(gòu)在Tomcat上發(fā)布Web應(yīng)用之前,首先要了解Tomcat的目錄結(jié)構(gòu),參見(jiàn)這些目錄都是的子目錄,Tomcat6.0與以前的版本相比較對(duì)目錄結(jié)構(gòu)做了很大改動(dòng),合并和簡(jiǎn)化了一些目錄,現(xiàn)在的結(jié)構(gòu)簡(jiǎn)單而且清晰。2.2.3解讀web.xmlJavaWeb應(yīng)用通過(guò)一個(gè)基于XML的發(fā)布描述符文件來(lái)配置其發(fā)布信息,這個(gè)文件名為web.xml,它存放于WEB-INF子目錄下。在web.xml文件中可主要包含如下配置信息:(1)Servlet的定義。(2)Servlet的初始化參數(shù)。(3)Servlet以及JSP的映射。(4)Filter的定義。(5)安全域配置參數(shù)。(6)welcome文件清單。(7)資源引用。(8)環(huán)境變量的定義。2.2.4編寫第一個(gè)JSP創(chuàng)建兩個(gè)JSP文件,其中一個(gè)是login.jsp如代碼2-2,它顯示登錄頁(yè)面,要求輸入用戶名和口令,這個(gè)頁(yè)面鏈接到另一個(gè)JSP文件是welcome.jsp如代碼2-3,顯示歡迎頁(yè)面。JSP的語(yǔ)法將在以后的章節(jié)詳細(xì)討論,本節(jié)側(cè)重于介紹JSP的發(fā)布過(guò)程。這兩個(gè)JSP文件都應(yīng)放在應(yīng)用jsp_example自己的目錄下。2.2.5發(fā)布與測(cè)試按上一節(jié)中表2-2Web應(yīng)用的目錄結(jié)構(gòu)表,在Tomcat的webapps目錄下創(chuàng)建目錄jsp_example,將寫好兩個(gè)jsp文件和web.xml文件放入指定目錄,重新啟動(dòng)tomcat。訪問(wèn)jsp可以看到結(jié)果。2.3JSP基本的語(yǔ)法JSP網(wǎng)頁(yè)主要分為腳本與網(wǎng)頁(yè)數(shù)據(jù)兩部分。網(wǎng)頁(yè)數(shù)據(jù)就是JSP服務(wù)器不處理的部分,例如:HTML的內(nèi)容,會(huì)直接送到客戶端端執(zhí)行。腳本必須經(jīng)由JSP服務(wù)器處理的部分,而大部分腳本都以XML作為語(yǔ)法基礎(chǔ),并且大小寫必須要一致。腳本有4種類型:編譯指令、JSP腳本、動(dòng)作標(biāo)簽和表達(dá)式語(yǔ)言(ExpressionLanguage),其中表達(dá)式語(yǔ)言又簡(jiǎn)稱為EL是JSP2.0新增的功能,將在后文的Struts2篇來(lái)介紹。2.3.1給JSP加注釋一般批注可分為兩種:一種為在客戶端顯示的批注;另外一種就是客戶端看不到,只給開(kāi)發(fā)程序員專用的批注。(1)客戶端可以看到的批注,以“<!--”開(kāi)頭以“-->”結(jié)尾,如:<!--comment[<%=expression%>]-->(2)開(kāi)發(fā)程序員專用的批注,以“<%--”開(kāi)頭以“--%>”結(jié)尾,如:<%--comment--%>2.3.2在JSP中聲明變量和函數(shù)在JSP程序中聲明是為了在JSP中聲明變量或者函數(shù),是以“<%!”開(kāi)頭以“--%>”結(jié)尾,如:<%!declaration;[declaration;]+...%>2.3.3用JSP表達(dá)式輸出結(jié)果JSP表達(dá)式是以“<%=”為起始以“%>”為結(jié)尾,其中間內(nèi)容包含一段合法的表達(dá)式,如:<%=expression%>前面章節(jié)中曾經(jīng)使用JSP表達(dá)式:<fontsize=<%=i%>>讀者,您好!</font>歡迎:<%=request.getParameter("username")%>2.3.4用JSP腳本實(shí)現(xiàn)程序邏輯JSP腳本又稱為scriptlet是包含一個(gè)有效的程序段。是以“<%”開(kāi)頭以“%>”結(jié)尾,如:<%codefragment%>前面章節(jié)中您好,讀者的例子就兩次用到JSP腳本<HTML><BODY><!—嵌入JSP代碼--><%for(inti=3,i<5,i++){%>//jsp腳本

<fontsize=<%=i%>><strong>讀者,您好!</strong></font><%}%>//jsp腳本<%--這里所在的東西不會(huì)被編譯,客戶端的原文件中也不會(huì)出現(xiàn)--%></BODY></HTML>2.4編譯指令和動(dòng)作標(biāo)簽編譯指令主要用來(lái)提供整個(gè)JSP網(wǎng)頁(yè)相關(guān)的信息,并且用來(lái)設(shè)定JSP網(wǎng)頁(yè)的相關(guān)屬性,例如:網(wǎng)頁(yè)的編碼方式、語(yǔ)法、信息等。起始符號(hào)為“<%@”,終止符號(hào)為“%>”中間部分就是一些指令和一連串的屬性設(shè)定。JSP有3編譯指令:page、include和taglib。動(dòng)作標(biāo)簽又稱為動(dòng)作元素、動(dòng)作指令,也可以理解為JSP自帶的標(biāo)準(zhǔn)標(biāo)簽庫(kù)。動(dòng)作標(biāo)簽利用XML語(yǔ)法格式的標(biāo)記來(lái)控制JSP服務(wù)器的行為。利用動(dòng)作標(biāo)簽可以動(dòng)態(tài)地插入文件、重用JavaBean組件、把用戶重定向到另外的頁(yè)面、為Java插件生成HTML代碼。起始符號(hào)為<jsp:xxx>,終止符號(hào)為</jsp:xxx>。2.4.1使用page指令page指令是最復(fù)雜的編譯指令,它的主要功能為設(shè)定整個(gè)JSP網(wǎng)頁(yè)的屬性和相關(guān)功能。page指令的基本語(yǔ)法如下:<%@pageattribute1="value1"attribute2="value2"attribute3=…%>如:<%@pageimport="java.util.*java.lang.*"%><%@pagebuffer="5kb"autoFlush="false"%><%@pageerrorPage="error.jsp"%>2.4.2用include指令插入其他JSPInclude指令是在JSP中包含一個(gè)靜態(tài)的文件,同時(shí)解析這個(gè)文件中的JSP語(yǔ)句。Include指令只有一個(gè)參數(shù)就是要插入文件的相對(duì)路徑,語(yǔ)法如下:<%@includefile="relativeURL"%>include指令將會(huì)在JSP編譯時(shí)插入一個(gè)包含文本或代碼的文件,當(dāng)使用include指令時(shí),這個(gè)包含的過(guò)程是靜態(tài)的。也可以理解為不管要插入的文件內(nèi)容是什么,簡(jiǎn)單的把其中所有的內(nèi)容拷貝過(guò)來(lái)合并成一個(gè)新文件,然后提交給JSP服務(wù)器做接下來(lái)的工作。由此可以看出,如果兩個(gè)文件中有重復(fù)的Java變量或函數(shù)定義,那么合并之后編譯要出錯(cuò),html的標(biāo)簽也同樣會(huì)相互影響,要避免片段文件中有<html><body>之類的全局標(biāo)簽出現(xiàn)。2.4.3用taglib指令引入標(biāo)簽庫(kù)taglib指令能夠讓用戶自定義新的標(biāo)簽。這里只是先做一個(gè)簡(jiǎn)單介紹,在后面的章節(jié)再詳細(xì)介紹如何自定義標(biāo)簽和如何使用標(biāo)簽。taglib指令的語(yǔ)法如下:<%@tagliburi="tagLibraryURI"prefix="tagPrefix"%>2.4.4用forward標(biāo)簽跳轉(zhuǎn)頁(yè)面forward動(dòng)作把請(qǐng)求轉(zhuǎn)到另外的頁(yè)面。<jsp:forward>標(biāo)簽只有一個(gè)屬性page。page屬性包含的是一個(gè)相對(duì)URL。page的值既可以直接給出,也可以在請(qǐng)求的時(shí)候動(dòng)態(tài)計(jì)算,如下面的例子所示:<jsp:forwardpage="/utils/errorReporter.jsp"/><jsp:forwardpage="<%=someJavaExpression%>"/>2.4.5動(dòng)態(tài)插入文件<jsp:include>標(biāo)簽把指定文件插入正在生成的頁(yè)面。其語(yǔ)法如下:<jsp:includepage="relativeURL"flush="true"/>所謂動(dòng)態(tài)插入正是相對(duì)于前面已經(jīng)介紹過(guò)靜態(tài)include指令,它是在JSP文件被轉(zhuǎn)換成Servlet的時(shí)候引入文件,而這里的<jsp:include>動(dòng)作不同,插入文件的時(shí)間是在頁(yè)面被請(qǐng)求的時(shí)候。這里被插入的文件是一個(gè)完整的JSP文件而非片段,把兩個(gè)JSP輸出到客戶端的結(jié)果結(jié)合在一起,他們分別被JSP服務(wù)器轉(zhuǎn)化為兩個(gè)不同Java類,因此不存在變量定義方面的沖突。用<jsp:include>標(biāo)簽引入文件的效率要稍微差一點(diǎn),而且被引用文件不能包含某些JSP代碼(例如不能設(shè)置HTTP頭),但它的靈活性卻要好得多。2.4.6用標(biāo)簽操作JavaBean本節(jié)將涉及3標(biāo)簽,<jsp:useBean>,<jsp:setProperty>,<jsp:getProperty>。<jsp:useBean>標(biāo)簽用來(lái)裝載一個(gè)將在JSP頁(yè)面中使用的JavaBean。這個(gè)功能非常有用,因?yàn)樗沟瞄_(kāi)發(fā)人員既可以發(fā)揮Java組件重用的優(yōu)勢(shì),同時(shí)也避免了損失直接在JSP實(shí)例化對(duì)象的復(fù)雜操作。<jsp:useBean>標(biāo)簽最簡(jiǎn)單的語(yǔ)法為:<jsp:useBeanid="name"class="package.class"/>2.4.7其他動(dòng)作標(biāo)簽<jsp:plugin>標(biāo)簽用來(lái)根據(jù)瀏覽器的類型,插入通過(guò)Java插件運(yùn)行JavaApplet所必需的OBJECT或EMBED元素。當(dāng)JSP網(wǎng)頁(yè)被編譯后送往瀏覽器執(zhí)行時(shí),<jsp:plugin>將會(huì)根據(jù)瀏覽器的版本替換成<object>標(biāo)簽或者<embed>標(biāo)簽。一般來(lái)說(shuō),<jsp:plugin>會(huì)指定對(duì)象Applet或Bean,同樣也會(huì)指定類的名字和位置,另外還會(huì)指定將從哪里下載這個(gè)Java組件。<jsp:fallback>一段文字用于:當(dāng)不能啟動(dòng)Applet或Bean時(shí),那么瀏覽器會(huì)有一段錯(cuò)誤信息。2.5JSP的內(nèi)置對(duì)象內(nèi)置對(duì)象也稱內(nèi)建對(duì)象、隱含對(duì)象是不需要聲明,直接可以在JSP中使用的Java對(duì)象。JSP基于Java語(yǔ)言,面向?qū)ο笠彩撬囊淮筇厣SP的內(nèi)置對(duì)象就是把最常用最重要的幾個(gè)對(duì)象直接創(chuàng)建然后內(nèi)置了,用戶無(wú)需再顯示的用代碼聲明,用好JSP內(nèi)置對(duì)象是JSP編程的精髓。JSP有以下九個(gè)內(nèi)置對(duì)象:request、response、out、pageContext、session、application、config、page、exception本節(jié)將分別講述如何使用這些對(duì)象。2.5.1使用request對(duì)象獲取請(qǐng)求request是最常用的內(nèi)置對(duì)象。表示javax.servlet.http.HttpServletRequest對(duì)象request對(duì)象包含所有請(qǐng)求的信息,如請(qǐng)求的來(lái)源、標(biāo)頭、cookies和請(qǐng)求相關(guān)的參數(shù)值等。比較常用的方法:(1)ObjectgetAttribute(Stringname):返回由name指定的屬性值,該屬性不存在時(shí)返回null。(2)voidsetAttribute(Stringname,Objectvalue):在屬性列表中添加/刪除指定的屬性。(3)StringgetParameter(Stringname):獲取客戶端發(fā)送給服務(wù)器端的參數(shù)值。(4)String[]getParameterValues(Stringname):獲得請(qǐng)求中指定參數(shù)的所有值。(5)StringgetProtocol():返回請(qǐng)求使用的協(xié)議??梢允荋TTP1.1或者HTTP1.0。(6)StringRequestURI():返回發(fā)出請(qǐng)求的客戶端地址,但是不包括請(qǐng)求的參數(shù)字符串。(7)StringgetRemoteAddr():獲取發(fā)出請(qǐng)求的客戶端IP地址。(8)HttpSessiongetSession():獲取session。2.5.2使用response對(duì)象做應(yīng)答response表示HttpServletResponse對(duì)象,并提供了幾個(gè)用于設(shè)置送回瀏覽器的響應(yīng)的方法,如比較常見(jiàn)的方法:(1)sendRedirect(URL):可以將用戶重定向到一個(gè)不同的頁(yè)面(URL)。(2)setContenType(Stringtype):響應(yīng)設(shè)置內(nèi)容類型頭。(3)addHeader(Stringname,Stringvalue):添加String類型的值到HTTP文件頭2.5.3在session對(duì)象中保存用戶會(huì)話session表示一個(gè)請(qǐng)求的javax.servlet.http.HttpSession對(duì)象。Session可以存貯用戶的狀態(tài)信息。session在第一個(gè)JSP頁(yè)面被裝載時(shí)自動(dòng)創(chuàng)建,完成會(huì)話期管理。從一個(gè)客戶打開(kāi)瀏覽器并連接到服務(wù)器開(kāi)始,到客戶關(guān)閉瀏覽器離開(kāi)這個(gè)服務(wù)器結(jié)束,被稱為一個(gè)會(huì)話。當(dāng)一個(gè)客戶訪問(wèn)一個(gè)服務(wù)器時(shí),可能會(huì)在這個(gè)服務(wù)器的幾個(gè)頁(yè)面之間反復(fù)連接,反復(fù)刷新一個(gè)頁(yè)面,服務(wù)器應(yīng)當(dāng)通過(guò)某種辦法(比如cookie)知道這是同一個(gè)客戶,這就需要session對(duì)象。2.5.4application對(duì)象、pageContext對(duì)象和JSP的Scope服務(wù)器啟動(dòng)后就產(chǎn)生了這個(gè)application對(duì)象,當(dāng)客戶再所訪問(wèn)的網(wǎng)站的各個(gè)頁(yè)面之間瀏覽時(shí),這個(gè)application對(duì)象都是同一個(gè),可以理解為在一個(gè)應(yīng)用中applications對(duì)象是一個(gè)全局的Map。pageContext與application對(duì)象類似有setAttribute()和getAttribute()方法來(lái)保存對(duì)象只是它的范圍只限于本網(wǎng)頁(yè)內(nèi)。這里提到JSP的范圍(scope),分別為Page、Request、Session、Application。在這4個(gè)范圍分別有pageContext,request,session,appliaction4個(gè)內(nèi)置對(duì)象對(duì)應(yīng)用來(lái)保存對(duì)象,方法名都是setAttribute()和getAttribute()。范圍的概念十分重要,很多配置都有范圍這一屬性。2.5.5使用out對(duì)象輸出out對(duì)象是javax.jsp.JspWriter的一個(gè)實(shí)例,是一個(gè)輸出流,用來(lái)向客戶端輸出數(shù)據(jù)。out對(duì)象用于各種數(shù)據(jù)的輸出。常用方法如下:(1)out.print():輸出各種類型數(shù)據(jù)。(2)out.newLine():輸出一個(gè)換行符。(3)out.close():關(guān)閉流。2.5.6在exception對(duì)象中處理異常Exception對(duì)象用作處理JSP文件執(zhí)行時(shí)發(fā)生的錯(cuò)誤和異常只有在錯(cuò)誤頁(yè)面里才可以使用,前提是:在頁(yè)面指令里要有isErrorPage=true的頁(yè)面中;如:<%@pagecontentType="text/html;charset=gb2312"isErrorPage="true"%>則:在此頁(yè)面中頁(yè)面中便可使用exception內(nèi)置對(duì)象,用法如下:<%=exception.getMessage()%>2.5.7page對(duì)象和config對(duì)象page表示從該頁(yè)面產(chǎn)生的一個(gè)Servlet實(shí)例,相當(dāng)于這個(gè)JSP產(chǎn)生Servlet類的this,可以通過(guò)page對(duì)象訪問(wèn)實(shí)例的屬性和函數(shù)config表示一個(gè)javax.servlet.ServletConfig對(duì)象。該對(duì)象用于存取Servlet實(shí)例的初始化參數(shù)。常用方法如下:(1)StringgetInitParameter(Stringname):返回名稱為name的促使參數(shù)的值。(2)EnumerationgetInitParameters():返回這個(gè)JSP所有的促使參數(shù)的名稱集合。(3)ServletContextgetContext():返回執(zhí)行者的Servlet上下文。(4)StringgetServletName():返回Servlet的名稱。2.6Servlet就當(dāng)時(shí)功能來(lái)說(shuō),Servlet所提供的功能就是一個(gè)Java版本的CGI。它依舊是一個(gè)具有跨平臺(tái)特性、100%純Java的Server-Side程序。JavaServletAPI定義了Servlet和服務(wù)器之間的一個(gè)標(biāo)準(zhǔn)接口,這使得Servlet具有跨服務(wù)器平臺(tái)的特性。2.6.1Servlet簡(jiǎn)介Servlet通過(guò)創(chuàng)建一個(gè)框架擴(kuò)展服務(wù)器的能力,采用請(qǐng)求-響應(yīng)模式提供Web服務(wù)。當(dāng)客戶機(jī)發(fā)送請(qǐng)求至服務(wù)器時(shí),服務(wù)器將請(qǐng)求信息發(fā)送給Servlet,Servlet生成響應(yīng)內(nèi)容并將其傳給Server服務(wù)器,然后再由Server服務(wù)器將響應(yīng)返回給客戶端。圖展示了Servlet的生命周期,定義了一個(gè)Servlet如何被加載、初始化,以及它怎樣提供服務(wù)和最后銷毀的過(guò)程。2.6.2創(chuàng)建Servlet所有的Servlet必須直接或間接地實(shí)現(xiàn)javax.servlet.Servlet接口,這樣才能在Servlet服務(wù)器或稱為Servlet容器、Servlet引擎上運(yùn)行,更簡(jiǎn)單的方法是繼承HttpServlet類。功能是在用戶請(qǐng)求中獲取name參數(shù),然后向客戶端輸出一個(gè)HTML網(wǎng)頁(yè)。2.6.3過(guò)濾器(Filter)一個(gè)過(guò)濾器是一個(gè)可以傳送請(qǐng)求或修改響應(yīng)的對(duì)象。過(guò)濾器并不是Servlet,他們并不實(shí)際創(chuàng)建一個(gè)請(qǐng)求。他們是請(qǐng)求到達(dá)一個(gè)Servlet前的預(yù)處理程序,在響應(yīng)離開(kāi)Servlet后的后處理程序。就像你將在后面的例子中看到的,一個(gè)過(guò)濾器能夠做如下工作。(1)在一個(gè)Servlet被調(diào)用前截獲該調(diào)用。(2)在一個(gè)Servlet被調(diào)用前檢查請(qǐng)求。(3)修改在實(shí)際請(qǐng)求中提供了可定制請(qǐng)求對(duì)象的請(qǐng)求頭和請(qǐng)求數(shù)據(jù)。(4)修改在實(shí)際響應(yīng)中提供了可定制響應(yīng)對(duì)象的響應(yīng)頭和響應(yīng)數(shù)據(jù)。(5)在一個(gè)Servlet被調(diào)用之后截獲該調(diào)用。2.6.4監(jiān)聽(tīng)器(Listener)監(jiān)聽(tīng)器可以監(jiān)聽(tīng)客戶端的請(qǐng)求、服務(wù)端的操作等。通過(guò)監(jiān)聽(tīng)器,可以自動(dòng)激發(fā)一些操作,如監(jiān)聽(tīng)在線用戶數(shù)量,當(dāng)增加一個(gè)HttpSession時(shí),給在線人數(shù)加1。監(jiān)聽(tīng)器還有一個(gè)好處是可以在不修改現(xiàn)有系統(tǒng)基礎(chǔ)上,增加Web應(yīng)用程序生命周期事件的跟蹤。編寫監(jiān)聽(tīng)器需要實(shí)現(xiàn)相應(yīng)的接口,常用的監(jiān)聽(tīng)接口:(1)ServletContextAttributeListener監(jiān)聽(tīng)對(duì)ServletContext屬性的操作,比如增加/刪除/修改。(2)ServletContextListener監(jiān)聽(tīng)ServletContext,當(dāng)創(chuàng)建ServletContext時(shí),激發(fā)contextInitialized方法;當(dāng)銷毀ServletContext時(shí),激發(fā)contextDestroyed方法。(3)HttpSessionListener監(jiān)聽(tīng)HttpSession的操作。當(dāng)創(chuàng)建一個(gè)Session時(shí),激發(fā)sessionCreated方法;當(dāng)銷毀一個(gè)Session時(shí),激發(fā)sessionDestroye方法。(4)HttpSessionAttributeListener2.7自定義JSP標(biāo)簽前面的章節(jié)介紹了JSP的動(dòng)作標(biāo)簽,使用標(biāo)簽可以處理定向請(qǐng)求以簡(jiǎn)化JSP頁(yè)面開(kāi)發(fā)與維護(hù)。JSP技術(shù)提供了一種封裝其它動(dòng)態(tài)類型的機(jī)制——自定義標(biāo)簽,它擴(kuò)展了JSP語(yǔ)言。自定義標(biāo)簽通常發(fā)布在標(biāo)簽庫(kù)中,該庫(kù)定義了一個(gè)自定義標(biāo)簽集并包含實(shí)現(xiàn)標(biāo)簽的對(duì)象。一些功能可以通過(guò)自定義標(biāo)簽來(lái)實(shí)現(xiàn),包括對(duì)隱含對(duì)象的操作,處理表單,訪問(wèn)數(shù)據(jù)庫(kù)集其它企業(yè)級(jí)服務(wù),如e-mail,目錄服務(wù),處理流控制。很多JSP開(kāi)發(fā)框架如Struts都提供了豐富的標(biāo)簽庫(kù),本節(jié)將以一個(gè)“helloreader”的例子來(lái)介紹如何自定義JSP標(biāo)簽。2.7.1標(biāo)簽庫(kù)簡(jiǎn)介標(biāo)簽庫(kù)涉及到4個(gè)基本概念:(1)標(biāo)簽(Tag)(2)標(biāo)簽庫(kù)(Taglibrary)(3)標(biāo)簽庫(kù)描述文件(TagLibraryDescriptor)(4)標(biāo)簽處理類(TagHandleClass)2.7.2創(chuàng)建標(biāo)簽的處理類標(biāo)簽處理類必須實(shí)現(xiàn)Tag接口的doStartTag和doEndTag方法。當(dāng)jsp引擎碰到tag標(biāo)簽的開(kāi)頭時(shí),doStartTag被調(diào)用,因?yàn)楹?jiǎn)單的tag沒(méi)有body,所以此方法將返回SKIP_BODY。當(dāng)JSP引擎碰到tag標(biāo)簽的結(jié)尾時(shí),doEndTag被調(diào)用,如果余下的頁(yè)面還要被計(jì)算,那它將返回EVAL_PAGE,否則將會(huì)返回SKIP_PAGE。一般的做法是不必直接實(shí)現(xiàn)Tag接口而是實(shí)現(xiàn)TagSupport類,如代碼此簽的作用是打印字符串“Hello.Reader”。2.7.3創(chuàng)建標(biāo)簽庫(kù)描述文件標(biāo)簽庫(kù)文件(TagLibraryDescrptorFile)簡(jiǎn)稱TLD文件是用xml語(yǔ)言描述的。TLD包括了標(biāo)簽庫(kù)中所有標(biāo)簽的描述,它一般用來(lái)被JSP服務(wù)器用來(lái)校驗(yàn)標(biāo)簽的語(yǔ)法正確性,或者被JSP開(kāi)發(fā)者用來(lái)開(kāi)發(fā)新的標(biāo)簽。TLD的文件擴(kuò)展名必須為.tld,而且必須放在當(dāng)前Web應(yīng)用的WEB-INF目錄或其子目錄中。如代碼與上一節(jié)中的處理類配合形成一個(gè)完整的標(biāo)簽。2.7.4使用自定義標(biāo)簽首先要配置web.xml使用自定義標(biāo)簽<taglib>。<taglib-uri>/WEB-INF/helloreader.tld</taglib-uri><!—加載標(biāo)簽,供頁(yè)面中使用--><taglib-location>/WEB-INF/helloreader.tld</taglib-location></taglib>2.7.5JSP2.0中新增的標(biāo)簽定義方法JSP2.0提供一些較為簡(jiǎn)單的方法,讓開(kāi)發(fā)人員來(lái)撰寫自定義標(biāo)簽。JSP2.0提供兩種新的機(jī)制,分別為SimpleTag和TagFile。SimpleTagSupport類別顧名思義,就是可以處理一些簡(jiǎn)單的自訂標(biāo)簽需求,它是在JSP2.0之后新增的類別,對(duì)于一些簡(jiǎn)單的自訂標(biāo)簽頁(yè)求,您可以繼承它來(lái)實(shí)作標(biāo)簽處理類別,而不用為了處理一些TagSupport、BodyTagSuppourt類別中回傳值的問(wèn)題。2.8小結(jié)本章詳細(xì)介紹JSP開(kāi)發(fā)的基礎(chǔ)知識(shí),包括JSP語(yǔ)法、JSP指令和標(biāo)簽、JSP內(nèi)置對(duì)象、自定義標(biāo)簽。JSP和Servlet是用Java開(kāi)發(fā)Web應(yīng)用的基礎(chǔ),是J2EE的重要的組成部分。在最后兩節(jié)里我們介紹了Servlet、過(guò)濾器和自定義標(biāo)簽,很多開(kāi)發(fā)框架包括后文會(huì)介紹的Struts和Spring都為開(kāi)發(fā)人員提供了很多功能強(qiáng)大的過(guò)濾器和標(biāo)簽庫(kù)。第3章Struts2概述Struts這個(gè)名字來(lái)源于在建筑和舊式飛機(jī)中使用的支持金屬架。顧名思義它給開(kāi)發(fā)者提供了一個(gè)基本框架和眾多組件,那么在此框架下生產(chǎn)出的產(chǎn)品必然大量節(jié)省時(shí)間而且產(chǎn)品趨于標(biāo)準(zhǔn)化的,這也正是Struts項(xiàng)目的目的所在。Struts能充分滿足應(yīng)用開(kāi)發(fā)的需求,簡(jiǎn)單易用,敏捷迅速,成為最成功的J2EE框架之一。3.1Struts項(xiàng)目簡(jiǎn)介Struts是Apache基金會(huì)Jakarta項(xiàng)目組的一個(gè)開(kāi)源項(xiàng)目,它采用MVC模式,能夠很好地幫助Java開(kāi)發(fā)者利用J2EE開(kāi)發(fā)Web應(yīng)用,它能大量減少開(kāi)發(fā)Web應(yīng)用的時(shí)間,提高產(chǎn)品的重用度。Struts主要是采用Servlet和JSP技術(shù)來(lái)實(shí)現(xiàn)的,它把Servlet、JSP、自定義標(biāo)簽和信息資源(messageresources)整合到一個(gè)統(tǒng)一的框架中,Struts它只有一個(gè)中心控制器,他采用XML定制轉(zhuǎn)向的URL,采用Action來(lái)處理邏輯,開(kāi)發(fā)人員利用其進(jìn)行開(kāi)發(fā)時(shí)不用再自己編碼實(shí)現(xiàn)全套MVC模式。Struts跟Tomcat、Velocity等諸多Apache項(xiàng)目一樣是開(kāi)源軟件,這是它的一大優(yōu)點(diǎn),使開(kāi)發(fā)者能更深入的了解其內(nèi)部實(shí)現(xiàn)機(jī)制。3.2Struts2的前世今生經(jīng)過(guò)多年的發(fā)展,Struts已經(jīng)成為一個(gè)高度成熟的框架,不管是穩(wěn)定性還是可靠性,都得到了廣泛的證明。在國(guó)內(nèi)Struts是使用最廣泛的一個(gè)框架,也成為Java程序員一項(xiàng)基本技能。但畢竟Struts誕生于很多年前,近期Ajax、JSF技術(shù)的興起,原有設(shè)計(jì)上的缺陷成為它的硬傷,Struts有點(diǎn)跟不上時(shí)代的步伐一些。大量新的MVC框架成了Struts強(qiáng)大的在競(jìng)爭(zhēng)者,最有代表性的莫過(guò)于WebWork。WebWork是由OpenSymphony組織開(kāi)發(fā)的,也是致力于組件化和代碼重用的J2EEWeb框架。后來(lái)Struts與WebWork兩大社區(qū)決定將兩個(gè)項(xiàng)目合并,稱為Sturts2。3.3Web世界中的MVC本節(jié)將著重講述Web世界中MVC模式是如何應(yīng)用的,與傳統(tǒng)的C/S結(jié)構(gòu)中MVC模式有哪些區(qū)別。另外,以網(wǎng)頁(yè)為視圖也為MVC帶來(lái)了一些變化和發(fā)展,產(chǎn)生了新的處理方式前端控制器和頁(yè)面控制器。3.3.1MVC在Web中的發(fā)展在經(jīng)典MVC中的事件流中,用戶與視圖(View)進(jìn)行交互,填入數(shù)據(jù)并單擊按鈕,控制器(Controller)接收到來(lái)自視圖的事件并對(duì)模型(Model)進(jìn)行操作,根據(jù)用戶提供的數(shù)據(jù)更新模型(Model)。視圖也會(huì)接到“模型改變”的事件通知,因此它會(huì)隨著模型而更新,將模型更新的結(jié)果顯示給用戶。這種模式在單機(jī)且實(shí)時(shí)更新的應(yīng)用程序中可以起到很好的作用。3.3.2前端控制器和頁(yè)面控制器MVC也不是一成不變的,一種稍微有些不同的MVC實(shí)現(xiàn)已經(jīng)通過(guò)一些框架,譬如Microsoft的ASP.NET,流行起來(lái)了。在這種MVC中,并不是令分發(fā)器去尋找一個(gè)控制器并執(zhí)行之,而是直接到達(dá)視圖并且在繼續(xù)生成視圖之前調(diào)用相應(yīng)的控制器。與傳統(tǒng)的MVC模式中的前端控制器對(duì)應(yīng)這種模式成為頁(yè)面控制器。3.4為什么要使用Struts2在Web應(yīng)用中MVC如此的重要,那么在眾多的MVC框架中Struts為何能脫穎而出受到絕大部分程序員的青睞呢?首先是它的技術(shù)水平,Struts2由Struts和webwork共同發(fā)展而來(lái),集中來(lái)兩者的優(yōu)勢(shì)于一身。其次是它在國(guó)內(nèi)的認(rèn)知度最高,在選擇框架的時(shí)候,選擇一個(gè)大家都普遍熟悉的框架來(lái)減少學(xué)習(xí)時(shí)間,無(wú)疑也是一個(gè)很重要的因素。3.4.1框架的意義框架可以極大地提高開(kāi)發(fā)效率。為了能夠滿足用戶的需求并且應(yīng)對(duì)來(lái)自不斷改變的商業(yè)世界的挑戰(zhàn),在構(gòu)建Web應(yīng)用程序的時(shí)候充分發(fā)揮MVC設(shè)計(jì)模式的優(yōu)勢(shì)。絕大多數(shù)的開(kāi)發(fā)人員并不會(huì)自己從零開(kāi)始寫一個(gè)MVC框架,而是在已有框架(譬如Struts)的基礎(chǔ)上進(jìn)行改進(jìn)。RickardOberg(WebWork的創(chuàng)造者和JBoss創(chuàng)始人之一)曾經(jīng)說(shuō)過(guò):“框架的強(qiáng)大之處不是源自它能讓你做什么,而是它不能讓你做什么。”Rickard所說(shuō)的話解釋了什么是框架:框架使混亂的東西變得結(jié)構(gòu)化。而Web應(yīng)用程序框架則鼓勵(lì)開(kāi)發(fā)人員使用一系列框架所提供的基礎(chǔ)類和類庫(kù),從而避免雜亂的JSP所造成的混亂。對(duì)句話可能對(duì)初學(xué)者更有意義,應(yīng)該最先學(xué)習(xí)和了解的應(yīng)該是最普通、最經(jīng)典的應(yīng)用,而用了框架就能保證開(kāi)發(fā)和設(shè)計(jì)不會(huì)偏離正確的方向。3.4.2Struts2的優(yōu)勢(shì)由Struts2的發(fā)展過(guò)程我們可以看出,Struts2是集中了MVC領(lǐng)域最強(qiáng)大的兩個(gè)社區(qū)的力量,其技術(shù)水平可謂是絕無(wú)僅有。Struts2又是一個(gè)嶄新的項(xiàng)目,發(fā)展空間很大,當(dāng)前最新的技術(shù),最新的理念都包含著其中。使用了Struts2就相當(dāng)于站沿了JavaWeb開(kāi)發(fā)的最前沿,將與Struts2共同前進(jìn)。在認(rèn)識(shí)度上Struts無(wú)疑是國(guó)內(nèi)影響力最大的,運(yùn)用到特別廣泛。以至于把Struts作為JavaWeb開(kāi)發(fā)的必選框架來(lái)使用,也是Java開(kāi)發(fā)人員的必備技能之一。另一種考慮,在項(xiàng)目中采用一種比較普遍的框架,也會(huì)免去開(kāi)發(fā)人員的學(xué)習(xí)時(shí)間并降低風(fēng)險(xiǎn)。3.5小結(jié)本章介紹了在開(kāi)發(fā)過(guò)程中運(yùn)用框架的意義,借助框架可以極大的提高效率、降低風(fēng)險(xiǎn)、優(yōu)化結(jié)構(gòu)。簡(jiǎn)要回顧了Struts2的由來(lái)和發(fā)展歷程,Struts是MVC模式在Web應(yīng)用的最佳實(shí)踐,在技術(shù)上處于領(lǐng)導(dǎo)地位,在實(shí)際項(xiàng)目中被最廣泛使用。Struts是最成功的一個(gè)J2EE框架之一,非常值得了解和學(xué)習(xí)。第4章Struts2入門Struts一貫以結(jié)構(gòu)清晰、簡(jiǎn)單易用而著稱,Struts2繼承了這一傳統(tǒng)。雖然復(fù)雜度提高了、功能上增強(qiáng)了,但在安裝和配置上甚至比前面的版本更簡(jiǎn)單。Struts2還提供了豐富的實(shí)例程序,使初學(xué)者很容易上手,在由淺入深的學(xué)習(xí)中一點(diǎn)不會(huì)感覺(jué)困難。4.1下載與安裝Struts2本節(jié)將介紹如何下載和Struts2,并介紹Struts2包內(nèi)都包含哪些文件,各自有什么作用,以及如何在Tomcat中安裝Struts2。最后發(fā)布并測(cè)試Struts2自帶的例子驗(yàn)證Struts2安裝是否成功。4.1.1下載Struts2Struts2的安裝非常簡(jiǎn)單,首先請(qǐng)到/struts下載struts2,應(yīng)該選擇完全發(fā)布版(FullDistribution),它包含必要的jar文件、自帶的例子和文檔,下載后得到的是一個(gè)zip文件,文件名為struts-2.XXX-all.zip,將zip包解開(kāi),可以看到4目錄分別為:(1)src為源代碼目錄,*.java文件在此存放。Struts2是一個(gè)開(kāi)源項(xiàng)目,可在此目錄中所有的代碼。(2)docs為文檔目錄。(3)lib為Struts2提供庫(kù)目錄,里面是提供給開(kāi)發(fā)人員的jar文件,在開(kāi)發(fā)過(guò)程中需要把這些jar加入的CLASSPATH。發(fā)布的時(shí)候需要把這些jar文件拷貝到Web工程的WEB-INF/lib下。(4)apps為例子目錄,里面是Struts2給出的幾個(gè)例子都是*.war文件。4.1.2發(fā)布Struts2自帶的例子把a(bǔ)pps目錄下文件名為struts2-blank-2.0.11.war文件拷貝到Tomcat的webapps下。重新啟動(dòng)Tomcat。直接訪問(wèn)http://localhost:8080/struts2-blank-2.0.11/測(cè)試這個(gè)例子。4.2第一個(gè)Struts2程序本節(jié)將介紹如何使用Struts2來(lái)開(kāi)發(fā)Web應(yīng)用,還是用一個(gè)HelloReader的例子來(lái)說(shuō)明Struts2基礎(chǔ)配置和結(jié)構(gòu)。4.2.1配置web.xmlStruts2的配置非常簡(jiǎn)單,在web.xml中配置Struts2提供的過(guò)濾器并把所有的請(qǐng)求(/*)都要經(jīng)過(guò)這個(gè)過(guò)濾器。如代碼所示。代碼Sturts2示例:web.xml<?xmlversion="1.0"encoding="UTF-8"?><web-app<display-name>StrutsBlank</display-name><filter><!—添加filter--><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>注意:在Struts1.x中web.xml配置了一個(gè)全局的Servlet來(lái)執(zhí)行分發(fā)的,而在Struts2中是一個(gè)過(guò)濾器(Filter)。4.2.2編寫JSP界面在使用Struts2提供的標(biāo)簽庫(kù)之前需要在JSP中引入這個(gè)標(biāo)簽庫(kù),前綴定義為“s”,如代碼所示,例子中用到了一個(gè)“property”標(biāo)簽來(lái)顯示message這個(gè)屬性值。代碼Sturts2示例:helloreader.jsp<!—引入Struts標(biāo)簽--><%@taglibprefix="s"uri="/struts-tags"%><html><head><title>HelloReader!</title></head><body><!—使用property標(biāo)簽來(lái)獲取Action中的屬性,直接顯示在頁(yè)面中-><h2><s:propertyvalue="message"/></h2></body></html>4.2.3編寫Action類Action類是最基本的邏輯處理單元,在MVC模式中分發(fā)器分發(fā)給不同的Action類,來(lái)處理請(qǐng)求。在Struts2中Action類不必再實(shí)現(xiàn)Action接口,可以是任何類。但一般的還是需要繼承ActionSupport類,后文中會(huì)講到,因?yàn)锳ctionSupport提供了很多很好的基本功能如錯(cuò)誤信息處理等。4.2.4添加映射到配置文件Struts2的配置文件是struts.xml,所有請(qǐng)求和分發(fā)以及其他配置都在這個(gè)文件中定義,struts.xml文件應(yīng)該放在WEB-INF目錄下。在Struts1.x中這個(gè)文件的文件名為struts-config.xml,而在Webwork中這個(gè)文件名為xwork.xml。如代碼4-4所示,配置了一個(gè)名稱為HelloReader的action,處理類是tutorial.HelloReader,處理后的結(jié)果轉(zhuǎn)到HelloReader.jsp。4.3發(fā)布與測(cè)試本節(jié)將展示在Tomcat中如何發(fā)布一個(gè)借助Struts2框架開(kāi)發(fā)的應(yīng)用程序,并展示測(cè)試結(jié)果。最后通過(guò)分析這個(gè)例子是如何工作的,說(shuō)明Struts2各個(gè)模塊之間的關(guān)系,請(qǐng)求是如何在其間流轉(zhuǎn)的。4.3.1發(fā)布在Tomcat的webapps目錄下創(chuàng)建一個(gè)Web應(yīng)用目錄struts2,JSP文件應(yīng)該放在這個(gè)目錄下。在此目錄下創(chuàng)建子目錄WEB-INF,web.xml文件應(yīng)該在此目錄下。程序中編寫的類class文件和struts.xml文件應(yīng)該放在WEB-INF/classes目錄下,最重要的是要把Struts2提供的jar文件拷貝到WEB-INF/lib下,這樣在程序中才能引用到Struts2的API。4.3.2測(cè)試結(jié)果重新啟動(dòng)Tomcat,訪問(wèn)http://localhost:8080/struts2/HelloReader.action,4.3.3分析處理流程這個(gè)例子的處理流程如圖所示。4.4小結(jié)本章從Struts2的下載安裝開(kāi)始敘述,以一個(gè)簡(jiǎn)單的例子帶領(lǐng)讀者走入Struts2世界,并詳細(xì)解讀了Struts2最基本的業(yè)務(wù)處理流程:受用戶請(qǐng)求、處理業(yè)務(wù)邏輯和返回結(jié)果頁(yè)面。分析了請(qǐng)求如何在各個(gè)模塊中流轉(zhuǎn)。例子雖然簡(jiǎn)單,但包含了Struts2的幾大要素,Action、標(biāo)簽庫(kù)、過(guò)濾器。下一章將詳細(xì)說(shuō)明Struts2的這些核心概念。第5章Struts2的核心概念本章將深入探討了Struts2的核心概念,首先介紹的是Struts2的體系結(jié)構(gòu)和幾個(gè)重要的配置文件,并會(huì)舉例說(shuō)明Struts2的核心對(duì)象如何配置。然后介紹Struts2最重要的3個(gè)組成部分Action、Result、Interceptor(攔截器)的原理和使用方法。5.1術(shù)語(yǔ)概述Action在Struts2中是負(fù)責(zé)Web應(yīng)用程序中具體邏輯實(shí)現(xiàn)的。Action是一個(gè)Java類,一般的繼承于com.opensymphony.xwork.ActionSupport類,這個(gè)類在Struts2的Dispatcher接受到HTTP請(qǐng)求的時(shí)候被調(diào)用。當(dāng)一個(gè)action執(zhí)行完畢之后,它將返回一個(gè)返回碼,譬如“SUCCESS”“INPUT”或者其他“返回代碼”。這些“返回代碼”通過(guò)查找struts.xml中的定義告訴Struts2下一步該做什么而這個(gè)下一步就稱為result。Struts2支持許多種不同的result類型,比如返回結(jié)果頁(yè)面給用戶。可選擇的顯示模板技術(shù)有JSP、Velocity或者是FreeMarker。5.2Struts2的體系結(jié)構(gòu)Struts2的核心體系結(jié)構(gòu)如圖5.1所示。用戶在Struts2框架下只需編寫自己的Action類來(lái)處理邏輯、編寫JSP頁(yè)面(或者其他方式)來(lái)展示用戶界面和在struts.xml配置映射關(guān)系就可以完成基本的業(yè)務(wù)流程。5.3Struts2的配置文件Struts2框架主要有兩個(gè)核心配置文件:perties和struts.xml。struts.xml與Struts1版本中的struts-config.xml非常類似,主要負(fù)責(zé)管理應(yīng)用中的Action映射,以及該Action包含的Result定義等,而perties文件則定義了Struts2框架的全局屬性。所有的配置文件說(shuō)明見(jiàn)表所示,圖展示了幾個(gè)配置文件所在位置和相互關(guān)系。5.3.1全局配置文件--perties

perties文件是一個(gè)標(biāo)準(zhǔn)的Properties文件,該文件包含了系列的key-value對(duì)象,每個(gè)key就是一個(gè)Struts2屬性,該key對(duì)應(yīng)的value就是一個(gè)Struts2屬性值。perties文件通常放在Web應(yīng)用的WEB-INF/classes路徑下,實(shí)際上,只要將該文件放在Web應(yīng)用的CLASSPATH路徑下,Struts2框架就可以加載該文件。以下是一部分配置片段。struts.enable.DynamicMethodInvocation=false"struts.devMode=false5.3.2核心配置文件--struts.xmlstruts.xml文件主要負(fù)責(zé)管理應(yīng)用中的action映射,以及該action包含的result定義等。在perties配置中的有一項(xiàng)struts.configuration.files,這里可以看出struts.xml這個(gè)文件名不一定是固定的,可以配置為其他文件名的。struts.xml內(nèi)容主要包括:Action、Interceptor、Packages、Namespace等。后面的章節(jié)將詳細(xì)介紹如何配置這些元素。在struts.xml中可以使用<include>標(biāo)簽把內(nèi)容分到幾個(gè)文件中去。這里非常像JSP中的<jsp:include>動(dòng)作標(biāo)簽,可以把其他文件的內(nèi)容導(dǎo)入進(jìn)來(lái),被導(dǎo)入的每個(gè)配置文件必須和struts.xml文件有一樣的格式。<include>標(biāo)簽的格式如下所示。5.3.3struts.xml的缺省實(shí)現(xiàn)struts-default.xml這個(gè)文件被包含在struts2-core.jar中,文件名已經(jīng)可以看出這個(gè)文件的作用是struts.xml的缺省配置,它將自動(dòng)被加載然后導(dǎo)入到struts.xml中去。代碼5-1是struts-default.xml的部分片段。5.3.4Velocity模板規(guī)則文件如果在程序中使用了Velocity(一個(gè)基于java的模板引擎,可以替代JSP作為顯示頁(yè)面)可以把文件perties放到classpath中去,系統(tǒng)將自動(dòng)加載。同時(shí)還要配置struts-default.vm文件,代碼perties#Velocity資源定義.velocimacro.library=action-default.vm,tigris-macros.vm,myapp.vm5.4struts.xml的配置Struts2絕大多數(shù)的配置都是在struts.xml中完成的,學(xué)習(xí)struts.xml文件是學(xué)習(xí)使用struts2的基礎(chǔ)。本節(jié)將詳細(xì)講述如何在struts.xml中定義和配置各種元素。5.4.1action配置action是Struts2的基礎(chǔ)“工作單元”。配置一個(gè)基本的action只需要兩個(gè)信息:action名字和對(duì)應(yīng)的action類,這兩部分就建立了一個(gè)最簡(jiǎn)單的action配置。屬性“method”用來(lái)告訴Struts2調(diào)用action的那個(gè)方法。在action處理之后一般的需要展示處理結(jié)果給用戶,所以還需要把a(bǔ)ction和result映射在一起。如代碼所示。代碼Action配置:struts.xml<!—Strutsaction配置--><actionname="helloWorld"class="example.HelloWorld"method=”doWork”><resultname="failure"path="Error.jsp"/><resultname=”ok”path="HelloWorld.jsp"/></action>5.4.2result配置Struts2定義了一些默認(rèn)result:error,input,login,none和success。開(kāi)發(fā)者當(dāng)然也可以根據(jù)應(yīng)用情況自由的定義結(jié)果。結(jié)果以“名字-值”的形式影射到結(jié)果類型。result標(biāo)簽告訴Strtus2在action被調(diào)用以后下一步做什么。result在struts.xml文件中定義,嵌套在<action>標(biāo)簽里。如果location參數(shù)是唯一的參數(shù),可以這樣簡(jiǎn)單的定義:<!—在result中添加參數(shù)--><actionname="bar"class="myPackage.barAction"><resultname="success"type="dispatcher"><paramname="location">foo.jsp</param></result></action>5.4.3攔截器(interceptor)配置interceptor是能在一個(gè)action執(zhí)行的前后執(zhí)行的代碼。它是做Web應(yīng)用程序時(shí)很有用的工具。最常見(jiàn)的由Interceptor實(shí)現(xiàn)的功能如:安全檢查(確保訪問(wèn)者是登陸用戶)、跟蹤日志(記錄每個(gè)action)、效率瓶頸檢查(記錄每個(gè)action開(kāi)始和結(jié)束的時(shí)間以檢查程序中的瓶頸)。也可以把interceptor連在一起組成interceptor棧(interceptor-stack)。比如在action執(zhí)行前同時(shí)做登陸檢查,安全檢查和記錄日志,可以定義一個(gè)interceptor的棧。interceptor必須事先定義好,然后可以連在一起組成一個(gè)棧。如代碼5-7所示,定義了一個(gè)interceptor和一個(gè)interceptor棧。5.4.4包(package)配置所謂packages就是把a(bǔ)ctions、results、results、types、interceptors這些元素打包到一個(gè)邏輯單元中去,從概念上講,packages就更像一個(gè)程序中的對(duì)象,可以被其他子包從寫,而且可以擁有自己獨(dú)立的部分。Name屬性是packages的必填元素,它作為一個(gè)關(guān)鍵字被后邊的包引用;extends元素是可選的,它允許包擴(kuò)展一個(gè)和多個(gè)前邊定義的包。Abstract元素是可選的,如抽象類和抽象函數(shù)一樣它是必須被繼承的,可以申明一個(gè)不包含actions的package。5.4.5命名空間(Namespace)配置命名空間屬性允許把a(bǔ)ction配置分成不同的命名空間,這樣可以使功能不同action中使用相同的名字。默認(rèn)命名空間用“”(空字符串)表示。如果系統(tǒng)在指定的命名空間中沒(méi)有找到某個(gè)action,就會(huì)到默認(rèn)命名空間中查找??梢栽谒杏?extends"擴(kuò)展的命名空間外配置全局action不指定命名空間。Struts2中有以“/”命名的根命名空間,它是請(qǐng)求直接來(lái)自應(yīng)用程序根路徑的時(shí)候的命名空間。和其他命名空間一樣,如果在根命名空間中沒(méi)有所需的action別名,系統(tǒng)會(huì)回到默認(rèn)命名空間中查找。如代碼5-9所示,這里使用了默認(rèn)命名空間、“/”和聲明了的命名空間“barspace”5.4.6在struts.xml中定義Bean在struts.xml中還可以作JavaBean的定義如下:s<!--在struts.xml中定義Bean><struts><beantype="com.opensymphony.xwork2.ObjectFactory"name="myfactory"class="pany.myapp.MyObjectFactory"/></struts>5.4.7在struts.xml中使用通配符當(dāng)配置文件中actionmapping的數(shù)量很多的時(shí)候,使用通配符是一個(gè)很好的辦法,可以將一些相似的mapping綁在一起,用一個(gè)比較通用的mapping來(lái)表示。在路徑中用*來(lái)代替變化的部分,而action的處理類和JSP中{1}剛好是代替這個(gè)變量。<!--在struts.xml中使用通配符--><actionname="/edit*”class="example.Edit{1}Action"><resultname="failure"path="/mainMenu.jsp"/><resultname=”ok”path="/\{1\}.jsp"/></action>5.5實(shí)現(xiàn)ActionAction是Struts2編程的核心部分,反映了對(duì)Web應(yīng)用程序的功能需求。Action在MVC模式中擔(dān)任控制部分的角色,在Struts2中也使用的最多。每個(gè)請(qǐng)求的動(dòng)作都對(duì)應(yīng)于一個(gè)相應(yīng)的action,action還可以負(fù)責(zé)存儲(chǔ)數(shù)據(jù)/狀態(tài)(以getter和setter的方式)并且執(zhí)行邏輯處理。在本章中將關(guān)注如何實(shí)現(xiàn)action,以及action如何提供Web應(yīng)用程序中所需的通用功能。除了Action接口之外,Struts2的action也可以選擇實(shí)現(xiàn)其他可選擇的接口,從而使action能夠提供諸如國(guó)際化、校驗(yàn)、負(fù)責(zé)工作流和錯(cuò)誤信息處理等功能。ActionSupport基類實(shí)現(xiàn)了Action接口并提供了大部分可選擇口默認(rèn)實(shí)現(xiàn),將在本章深入講述這個(gè)類。除此之外,也將探討action是如何通過(guò)使用JavaBean屬性提供輸入和輸出的,最后將介紹如何處理文件上傳。5.5.1實(shí)現(xiàn)Aciton接口Struts2的Action接口來(lái)源于WebWork,全包名為com.opensymphony.xwork2.Action如代碼5-10所示。在Struts2中定義action類時(shí)已經(jīng)可以不實(shí)現(xiàn)Aciton接口,Struts2會(huì)以反射的方式來(lái)調(diào)用action類。5.5.2擴(kuò)展ActionSupport類ActionSupport是一個(gè)讓action類能夠更快開(kāi)始工作的基類。它包含了action能夠提供的許多可選服務(wù)的默認(rèn)實(shí)現(xiàn),讓開(kāi)發(fā)者更容易地開(kāi)始開(kāi)發(fā)自己的action類,不需要在為這些可選服務(wù)提供具體實(shí)現(xiàn)了。同時(shí)能夠改寫可選擇接口的任意一個(gè)方法實(shí)現(xiàn)并保持其他方法的默認(rèn)實(shí)現(xiàn)。由于ActionSupport預(yù)建了許多開(kāi)箱即用的功能,建議讀者創(chuàng)建自己的action時(shí)都擴(kuò)展ActionSupport類。ActionSupport實(shí)現(xiàn)了以下可選擇接口,5.5.3實(shí)現(xiàn)基本校驗(yàn)通常在執(zhí)行業(yè)務(wù)邏輯之前,校驗(yàn)用戶提供的數(shù)據(jù)是十分表要的。這種字段校驗(yàn)包括“某個(gè)字段是必須的”、“某個(gè)字段必須大于某個(gè)值,小于某個(gè)值“等內(nèi)容。為了自動(dòng)執(zhí)行校驗(yàn),Sturts2提供了一種能夠在excuete()方法被調(diào)用之前調(diào)用其他方法對(duì)action進(jìn)行處理的機(jī)制,這個(gè)機(jī)制由com.opensymphony.xwork2.Validateable接口提供,它包含了一個(gè)方法:publicvoidvalidate()Validateable接口為action增加了一個(gè)標(biāo)記,通過(guò)以上方法使得action能夠自動(dòng)被校驗(yàn)。保存和顯示校驗(yàn)的錯(cuò)誤信息有接口ValidationAware來(lái)負(fù)責(zé),這兩個(gè)接口一般會(huì)同時(shí)使用。5.5.4使用本地的資源文件本節(jié)中將介紹另外兩個(gè)接口TextProvider和LocalProvider,它們都是為了使用本地的資源文件而設(shè)計(jì)的。在Java中用戶語(yǔ)言和地區(qū)的信息被封裝在java.util.Local類中,而action則通過(guò)一個(gè)定義與com.opensymphony.xwork.LocaleProvider接口的方法判斷使用哪個(gè)Locale獲取用于顯示的信息文本,這個(gè)接口中只定義了一個(gè)方法:PublicLocalegetLocale()在ActionSupport中,這個(gè)方法的默認(rèn)實(shí)現(xiàn)為:通過(guò)調(diào)用AcitonContext.getContext().getLocale()方法,利用ActionContext獲得locale的值(關(guān)于ActionContext的使用將在后面的章節(jié)詳細(xì)描述)。Struts2通過(guò)查詢HttpServletRequest對(duì)象并調(diào)用它的getLocale()方法將Local與action調(diào)用聯(lián)系起來(lái)。5.5.5用ActionContext與Web容器發(fā)生聯(lián)系在Action的接口定義中,excute()方法并沒(méi)有HttpServletRequest和HttpServletResponse參數(shù)也就是說(shuō)Struts2的Action不用去依賴于任何Web容器(不像Struts1必須在Web容器中才能運(yùn)行),不用與那些JavaServlet復(fù)雜的請(qǐng)求(Request)、響應(yīng)(Response)關(guān)聯(lián)在一起。但在Web應(yīng)用程序開(kāi)發(fā)中,往往需要在Action里直接獲取請(qǐng)求(Request)或會(huì)話(Session)的一些信息,甚至需要直接對(duì)JavaServletHttp的請(qǐng)求、響應(yīng)操作。Struts2提供了一個(gè)工具,用ActionContext對(duì)象來(lái)與Web容器發(fā)生聯(lián)系。ActionContext(com.opensymphony.xwork.ActionContext)是Action執(zhí)行時(shí)的上下文,上下文可以把它看作是一個(gè)Map,它存放是Action在執(zhí)行時(shí)需要用到的對(duì)象,比如:上下文放有請(qǐng)求的參數(shù)(Parameter)、會(huì)話(Session)、Servlet上下文(ServletContext)、本地化(Locale)信息等。在每次執(zhí)行Action之前都會(huì)創(chuàng)建新的ActionContext,ActionContext是線程安全的,也就是說(shuō)在同一個(gè)線程里ActionContext里的屬性是唯一的,這樣的Action就可以在多線程中使用。5.5.6高級(jí)輸入應(yīng)用程序經(jīng)常使用JavaBean表示一個(gè)域中的對(duì)象,包括User、Address、Block在內(nèi)地的類就是這種JavaBean很好的例子。而在Web程序中很大一部工作都是將信息填充到這些對(duì)象中去和從Bean中獲取數(shù)據(jù)信息在網(wǎng)頁(yè)中表現(xiàn)。本節(jié)將以一個(gè)完整的實(shí)例來(lái)說(shuō)明Sturts2在這些方面提供了那些便利。5.5.7使用Model-DrivenStruts2中,提供了兩種Action驅(qū)動(dòng)模式:Property-Driven(屬性驅(qū)動(dòng)),Model-Driven(模型驅(qū)動(dòng)的)。模型驅(qū)動(dòng)的Action很像Struts1中的FormBean,在傳遞過(guò)程中有一個(gè)單獨(dú)的值對(duì)象來(lái)作為參數(shù)的載體,但在Struts2中這個(gè)值對(duì)象不必再繼承任何接口,只要普通JavaBean就可以充當(dāng)模型部分。很多情況下Bean的定義已經(jīng)存在了,而且是不能修改的(如從外部引入的類或者是已經(jīng)被大量代碼引用的類),如果必須實(shí)現(xiàn)某個(gè)接口才能作為FromBean,不得不再新增一個(gè)類,Struts2的這個(gè)改進(jìn)非常及時(shí)。5.5.8使用Property-DrivenProperty-Driven就是Action將直接用自己的字段來(lái)充當(dāng)FormBean的功能,在Struts2入門一章中,HelloReader這個(gè)例子就是采用的這種方法,在Action中直接包含了message屬性和它set、get方法。它一般用在頁(yè)面表單比較簡(jiǎn)單的情況使用,而且可以直接把屬性作為Action的字段,這樣就不用在另寫FormBean,減少了重復(fù)代碼。上一節(jié)的例子如果使用Property-Driven方法,那就是將User與action類合并定義,把User中的屬性值直接轉(zhuǎn)移到action中去,在配置文件中也不必再增加modelDriven這個(gè)過(guò)濾器。5.6Result類型介紹Result是在Action執(zhí)行完,一個(gè)結(jié)果返回后決定發(fā)生什么事的類。開(kāi)發(fā)者可以自由的根據(jù)他們的應(yīng)用和環(huán)境的需要?jiǎng)?chuàng)建自己的Result類型。例如在Struts2中Servlet和Velocity結(jié)果類型已經(jīng)被創(chuàng)建用來(lái)顯示web應(yīng)用程序的畫面。本節(jié)將介紹Struts2內(nèi)置的幾種Result類型和如何自定義開(kāi)發(fā)Result。5.6.1內(nèi)置Result類型所有的Result類型都實(shí)現(xiàn)了com.opensymphony.xwork.Result接口。這個(gè)接口是所有action執(zhí)行結(jié)果的通用接口,不管這個(gè)結(jié)果是用來(lái)顯示一個(gè)網(wǎng)頁(yè)還是產(chǎn)生一個(gè)E-mail,發(fā)送一個(gè)JMS消息還是別的。在struts-default.xml中定義了系統(tǒng)提供的缺省Result類型,把它們映射為action配置中可以引用的名字,在action配置就就不用再使用長(zhǎng)類名直接使用這些別名就可以了。5.6.2默認(rèn)ResultDispatcherResult是最常用的一種result,它也是Struts2默認(rèn)的result,又稱為通用resut。action執(zhí)行完后,請(qǐng)求會(huì)導(dǎo)向?qū)?yīng)的View,相當(dāng)于<jsp:forword>標(biāo)簽實(shí)現(xiàn)的跳轉(zhuǎn)功能。將同一個(gè)HTTP請(qǐng)求中的內(nèi)容分發(fā)至某一個(gè)頁(yè)面(dispatcher類型的result的使用)只要配置文件包含了struts-default.xml,而且package繼承了struts-default,那么使用dispatcherresult并不需要其他設(shè)置。示例:<resultname="success"type="dispatcher"><paramname="location">foo.jsp</param></result>5.6.3頁(yè)面跳轉(zhuǎn)ResultRedirectResult與DispatcherResult作用類似也是實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)。對(duì)上次的響應(yīng)將重定向到指定的位置,可以理解為在客戶端跳轉(zhuǎn)用戶又重新請(qǐng)求了一個(gè)新的URL。redirect是重新產(chǎn)生一個(gè)新的request,因此原來(lái)request保存的東西將不再有效,比如不能通過(guò)再requet.getAtrribute()取得對(duì)象,也不能取得action的實(shí)例、errors、fielderrors等。RedirectResult與DispatcherResult的區(qū)別于源于JSP篇中<jsp:forward>標(biāo)簽與response.redeiret()的區(qū)別。5.6.4創(chuàng)建action鏈ChainResult是一種result類型,它基于自己的攔截器stack(堆棧)和result調(diào)用一個(gè)action,這樣允許一個(gè)action附帶著原來(lái)的狀態(tài)將請(qǐng)求轉(zhuǎn)到目標(biāo)actionStruts2提供把多個(gè)Action按照預(yù)先定義好的順序或者流程鏈接起來(lái)的能力。這個(gè)特性通過(guò)給指定的Action設(shè)置一個(gè)ChainResult,然后通過(guò)一個(gè)ChainingInterceptor攔截目標(biāo)Action來(lái)實(shí)現(xiàn)。5.6.5整合各種View技術(shù)Velocity、Freemarker、JasperReports、xslt這4種result都是為了整合不同的視圖技術(shù)而設(shè)計(jì)的。1.VelocityResult:Velocity是一個(gè)基于java的模板引擎(templateengine)。2.FreemarkerResult:Freemarker也是一個(gè)模板引擎,允許JavaServlet保持圖形設(shè)計(jì)同應(yīng)用程序邏輯的分離,這是通過(guò)在模板中密封HTML完成的。模板用servlet提供的數(shù)據(jù)動(dòng)態(tài)地生成HTML。3.JasperReportsresult:JasperReports是一個(gè)基于Java的開(kāi)源報(bào)表工具,它可以在Java環(huán)境下像其他IDE報(bào)表工具一樣來(lái)制作報(bào)表。4.XSLTResult:XSLTResult用XSLT來(lái)轉(zhuǎn)換action對(duì)象到XML。5.6.6自定義resultStruts2也允許用戶自定義自己的result類型,只要實(shí)現(xiàn)com.opensymphony.xwork2.Result接口就可以了。如代碼5-29所示,模擬了一種result作用是根據(jù)處理結(jié)果將給指用戶發(fā)送一份E-mail。這個(gè)result需要4個(gè)參數(shù)to、from、subject和body5.7攔截器(Interceptors)介紹攔截器(Interceptor)是Struts2的一個(gè)強(qiáng)有力的工具,有許多功能都是構(gòu)建于它之上,如國(guó)際化、轉(zhuǎn)換器,校驗(yàn)等。Interceptor是Struts2的一大特色,在執(zhí)行action之前和之后可以使請(qǐng)求通過(guò)一個(gè)或多個(gè)Interceptor。多個(gè)連接器組合在一起實(shí)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論