JSP應用開發 -------- 電紙書(未完待續)

 http://www.educity.cn/jiaocheng/j9415.htmljavascript

JSP程序員經常使用的技術

 

第1章 JSP及其相關技術導航html

【本章專家知識導學】前端

JSP是一種編程語言,也是一種動態網頁開發技術,要用它完成實踐項目工程的開發,須要掌握的知識點比較多。爲了讓讀者對JSP這一開發技術的知識體系有個全面、清晰的瞭解,爲後續的學習打下基礎,本章將首先講述做爲一名JSP程序員應該掌握的技術知識體系和本書的內容安排。接着,對JSP技術進行了簡要的介紹,使讀者瞭解JSP技術的功能和優點。讀者在讀完本章後,應當可以瞭解要成爲一個優秀的JSP程序員所要掌握的知識內容,並對JSP技術的要點有了一個總體性的認識,從而在之後的學習中作到有的放矢,完善本身的知識積累。java

1.1 JSP程序員經常使用的技術node

現在,開發Web應用程序的技術已經變得相對成熟與複雜了。構建一個Web應用程序不只僅須要基本的HTML知識,還須要開發者對數據庫訪問、腳本語言和Web應用服務器管理等方面的知識有所瞭解,下面介紹JSP程序員經常使用的一些技術。mysql

1.HTML語言c++

HTML語言(Hypertext Marked Language,超文本標記語言)是一種用來表示網頁中的信息的符號標記語言。經過使用HTML能夠在Web頁面中加入圖片、聲音、動畫、視頻等內容,從一個文件跳轉到另外一個文件,自由連接。用HTML編寫的超文本文檔稱爲HTML文檔,它能獨立於各類操做系統平臺(如UNIX、Windows等)。自1990年以來HTML就一直被用做Internet上的信息表示語言,它是Web程序員須要掌握的基礎知識。git

JSP技術是一種主流的開發動態網頁的技術,JSP程序員理所固然應熟悉HTML。雖然如今製做網頁的可視化開發工具不少,功能也強大,例如Dreamweaver、FrontPage,能夠自動生成HTML文件中的部分代碼,可是在開發過程當中,不少地方仍然要求開發人員手工修改HTML代碼。因此,做爲一個合格的JSP程序員必需要熟練掌握HTML。程序員

2.JavaScript腳本語言web

HTML僅僅是一種標記語言,用它可做的事是有限的。用HTML建立的網頁是靜態的,這種網頁不能處理和應答用戶的客戶端活動。例如,Web頁面可能要求用戶必須輸入用戶名、密碼等信息,若是用戶沒有輸入這些信息,網頁要給出提示信息。若是爲了覈對用戶輸入是否爲空,把數據送到服務器處理,而後服務器再返回處理結果,這樣勢必致使大量的網絡通信量。若是這些工做能夠在客戶端獲得處理,將大大下降服務器的負擔和網絡的通信量。正是Web網頁可交互性的須要致使了腳本語言的出現。腳本語言使網頁變成了可交互式的,它容許開發者獲取客戶端的每一個事件,但無需與服務器交互。因此,掌握一種腳本語言成爲JSP程序員的必備技能。

推薦讀者使用目前最流行的腳本語言JavaScript。JavaScript是一種獨立的編程語言,它與Java沒有任何關係。JavaScript與Java的區別比較大。首先,JavaScript是一種解釋性語言,用JavaScript語言寫出的腳本不用編譯就可在客戶端瀏覽器上執行,而Java語言編寫的程序在執行前是要被編譯的。其次,如JavaScript這樣的解釋語言沒有複雜的語法和規則,所以比Java這種被編譯語言更容易學習。JavaScript編寫的腳本都是集成在HTML當中,用於處理客戶端的交互活動,並且是不可擴展的,而Java應用不與HTML直接集成。總之,JavaScript語言與Java語言是性質徹底不一樣的兩種語言,二者使用的領域範圍不一樣,二者所能實現的功能也有區別。

3.Java語言基礎

Java是JSP的基礎,要學習JSP技術,Java基礎是必不可少的。在用JSP技術編寫Web頁面時,不少時候要用到Java語言和Java編程的思想,因此若是讀者想深刻學習JSP技術,就必須對Java語言有深入的理解。

Java是一種簡單易用、徹底面向對象、具備平臺無關性、安全可靠的主要面向Internet的編程語言。自它問世以來,Java的快速發展和普遍應用已經讓整個Web世界發生了翻天覆地的變化。隨着Java Servlet和Java Server Page技術的推出,Java開發工具的功能不斷強大,Web服務器軟件功能的加強,Java已成爲主流的軟件開發語言之一。

4. SQL和JDBC

現在,大多數Web應用程序須要訪問關係數據庫中的數據。做爲一個JSP程序員,你須要知道如何存儲、獲得並操做數據庫中的數據。有時候,也須要設計數據庫,構建數據庫中的表和其餘結構。SQL(Strutured Query Language,結構化查詢語言)就是用來操做數據庫中數據的語言。程序員一般須要編寫SQL語句(經常是動態的),把它們傳送到數據庫服務器,再由數據庫服務器執行SQL語句並返回SQL語句執行的結果。

Java語言中須要使用JDBC來幫助Web應用程序和數據庫服務器進行通訊。JDBC是用於執行SQL語句的Java應用程序接口,由一組用Java語言編寫的類與接口組成,在JSP中將使用JDBC來訪問數據庫。JDBC是一種規範,它讓各數據庫廠商爲Java程序員提供標準的數據庫訪問類和接口,這樣就使得獨立於數據庫管理系統的Java應用程序統一了開發接口,便於模塊化開發。在Windows操做系統中,還能夠使用JDBC-ODBC橋驅動程序,這樣只要是可以使用ODBC訪問的數據庫系統,也就可以使用JDBC訪問了。

5.Web 服務器管理和應用程序的部署

服務器是對Web瀏覽器檢索信息的請求作出響應,進而將HTML文檔回傳到客戶機的瀏覽器。JSP頁面和Java Servlet必須在特定的Web服務器中運行。所以,你至少須要知道如何配置Web服務器,以及如何爲測試、生產運行應用程序而部署相關的Web資源。例如,若是運用Tomcat,你須要瞭解怎樣安裝配置它,須要瞭解如何映射配置文件(server.xml)中相關的應用程序,使Tomcat知道如何調用JSP頁面、Servlet組件等資源。

推薦讀者使用如今最流行的Web服務器中間件軟件Tomcat、Weblogic或Websphere,其中Tomcat是開源免費的,讀者能夠從http://www.apache.org網站下免費下載獲得,本書也將使用Tomcat做爲Web服務器端的中間件軟件。

6.XML

XML是計算機技術領域中的後起之秀,由World Wide Consortium在1996年開發,如今已是用於數據交換和可擴展數據結構的一個普遍的、公認的標準了。JSP在其發展過程當中也愈來愈強調XML的語言格式,XML在Java Web開發中扮演着愈來愈重要的角色。爲何要用XML的相容語言來架構JSP呢?由於做爲XML文檔的JSP將會獲得不少好處,例如:

一個標準的XML相容的JSP語法將有助於JSP的開發。

JSP文件的XML語法使得JSP文件的內容很容易被組織和管理。

能夠使用XML的開發和分析工具來開發和分析JSP,僅僅須要更換DTD文件就能夠升級到最新版本的JSP。

XML格式統一的語法更容易學習和使用。

7.Java Servlet

Java Servlet是JSP技術的基礎,並且大型的Web 應用程序的開發常使用Java Servlet和JSP結合來實現。

Java Servlet其實和傳統的CGI程序和ISAPI、NSAPI等Web 程序開發工具的做用是相同的,在使用Java Servlet之後,用戶沒必要再使用效率相對低下的CGI技術了,也沒必要使用只能在某個固定Web 服務器平臺運行的API方式來動態生成Web 頁面。許多Web 服務器都支持Servlet,即便不直接支持Servlet的Web 服務器也能夠經過附加的應用服務器和模塊來支持Servlet。得益於Java的跨平臺的特性,Servlet也是平臺無關的,實際上只要符合Java Servlet規範,Servlet是徹底平臺無關且是Web 服務器無關的。因爲Java Servlet內部是以線程方式提供服務,沒必要對於每一個請求都啓動一個進程,而且利用多線程機制能夠同時爲多個請求服務,所以Java Servlet效率很是高。

但Java Servlet也不是沒有缺點,和傳統的CGI、ISAPI、NSAPI方式相同,Java Servlet是利用輸出HTML語句來實現動態網頁的,若是用Java Servlet來開發整個網站,動態部分和靜態頁面的整合過程會給程序員帶來至關大的工做量,對程序員要掌握的知識水平和深度也要求比較高,這就是爲何SUN還要推出JSP的緣由。JSP編寫起來簡單多了,但最終在執行時會先由Web容器先轉換成Java Servlet,再由Web容器編譯執行,因此一個JSP頁和一個Java Servlet是一一對應的。

8.JavaBean和JSTL

在複雜的Web應用程序中,JSP頁面只用於顯示數據,而JavaBean和標籤用來實現業務邏輯。

什麼是JavaBean?

JavaBean就是Java中的可重用組件。

ASP.NET經過COM來擴充複雜的功能,如文件上載、發送email等業務處理功能或複雜的計算功能,能夠將它們分離出來成爲獨立的可重複利用的模塊。

JSP經過JavaBean實現了一樣的功能擴充。JSP爲在Web 應用中集成JavaBean組件提供了完善的支持。這種支持不只能縮短開發時間(能夠直接利用經測試和可信任的已有組件,避免了重複開發),也爲JSP應用帶來了更多的可伸縮性。JavaBean組件能夠用來執行復雜的計算任務,負責與數據庫的交互等。

和傳統的ASP或PHP頁面相比,JSP頁面將會是很是簡潔的,因爲JavaBean開發起來簡單,又能夠利用Java語言的強大功能,許多動態頁面處理的過程實際上被封裝到了JavaBean中。

什麼是JSTL呢?JSTL(JSP Standard Tag Libraries,JSP標準標籤庫)就是存儲了可複用代碼的標準標籤庫。爲了提升應用程序的開發效率,就能夠使用JSTL中已有的標籤。此外,經過擴展程序員也能夠編寫自已的標籤;一些框架技術也提供了一些用在JSP頁面中的標籤,如Struts提供的Struts HTML標籤。

 
 
 
 
 

第 1 章:JSP及其相關技術導航做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP概述

 

隨着Internet的出現,總體應用架構被改變爲多層次的「客戶機/服務器」架構。Sun公司在1999年推出了JSP技術。此後,JSP很快引發了人們的關注,目前已經成爲開發動態網頁的主流技術之一。下面咱們將對JSP技術進行一個全面、清晰的介紹。

 
 
 
 

第 1 章:JSP及其相關技術導航做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Web開發技術的發展

 

1990年11月,Tim Berners-Lee在本身編寫的圖形化Web瀏覽器「WorldWideWeb」上看到了最先的Web頁面。1991年,CERN(European Particle Physics Laboratory,歐洲粒子物理研究中心)正式發佈了Web技術標準。目前,與Web相關的各類技術標準大多由著名的W3C組織(World Wide Web Consortium)進行管理和維護。

Web服務器端的開發技術是由靜態向動態逐漸發展、完善起來的。最先的Web服務器簡單地響應瀏覽器發來地HTTP請求,並將存儲在服務器上的HTML文件返回給瀏覽器。當時只有一種名爲SSI(Server Side Includes)的技術可讓Web服務器在返回HTML文件前,更新HTML文件的某些內容,但其功能很是有限。第一種真正使服務器能夠動態生成HTML頁面的技術是CGI(Common Gateway Interface,公共網關接口)。1993年,CGI1.0的標準草案由NCSA(National Center for Supercomputing Application)提出;1995年,NCSA又開始制定CGI1.1標準;1997年,NCSA又開始討論CGI1.2標準。CGI技術容許服務器端的應用程序根據客戶端的請求動態生成HTML頁面,這使客戶端和服務端的動態信息交換成爲了可能。隨着CGI技術的普及,聊天室、論壇、電子商務、信息查詢、全文檢索等Web應用蓬勃發展起來,人們終於能夠享受到信息檢索、信息交換、信息處理等更爲便捷的信息服務了。

早期的CGI程序大可能是編譯後的可執行程序,其編程語言能夠是C、C++、Pascal等任何通用的程序設計語言。爲了簡化CGI程序的修改、編譯和發佈過程,人們開始探尋用腳本語言實現CGI應用的可行方式。在此方面,不能不提的是Larry Wall於1987年發明的Perl語言。Perl語言結合了C語言的高效以及SH、AWK等腳本語言的便捷,彷佛天生就適合於編寫CGI程序。1995年,第一個用Perl語言編寫的CGI程序問世。很快,Perl在CGI編程領域的風頭就蓋過了它的前輩C語言。隨後,Python等著名的腳本語言也陸續加入了CGI編程語言的行列。

1994年,Rasmus Lerdorf發明了專用於Web服務器端編程的PHP(Personal Home Page Tools)語言。與以往的CGI程序不一樣,PHP語言將HTML代碼和PHP指令合成爲完整的服務端動態頁面,Web應用的開發者能夠用一種更加簡便、快捷的方式實現動態Web功能。1996年,Microsoft借鑑PHP的思想,在其Web服務器IIS3.0中引入了ASP技術。ASP使用的腳本語言編程時使用的是咱們熟悉的VBScript和JavaScript。藉助Microsoft Visual Studio等開發工具在市場上的成功,ASP迅速成爲Windows系統下Web服務端的主流開發技術。

固然,以Sun公司爲首的Java陣營也不會示弱。1997年,Servlet技術問世,1999年,JSP技術誕生。Servlet、JavaBean技術和JSP的組合讓Java開發者同時擁有了相似CGI程序的集中處理功能和相似PHP的HTML嵌入功能,此外,Java的運行時編譯技術也大大提升了Servlet和JSP的執行效率,這正是Servlet和JSP被後來的J2EE平臺吸納爲核心技術的緣由之一。

 
 
 
 

第 1 章:JSP及其相關技術導航做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP技術概述

 

做爲一種動態網頁表現層的開發技術,JSP提供了Java Servlet 的全部好處,而且,當與一個JavaBean類結合在一塊兒時,提供了一種使內容和顯示邏輯分開的簡單方式。分開內容和顯示邏輯的好處是,更新頁面外觀的人員沒必要懂得Java代碼,而編寫JavaBean類代碼的人員也沒必要是設計網頁的行家裏手,就能夠用帶JavaBean類的JSP頁面來定義Web 模板,以創建一個由具備類似的外觀的頁面組成的網站。JavaBean類完成數據處理邏輯,這樣在頁面模板中就能夠只書寫少許的Java代碼,這意味着這些模板能夠由一個HTML 編寫人員來維護。固然,也能夠利用Java Servlet來控制網站的邏輯,經過Java Servlet調用JSP文件的方式來將網站的邏輯和內容分離。

然而,Java Servlet最適用於不須要頻繁修改的網頁,而JSP頁面則經過以顯示爲中心的描述性的方法將動態內容和邏輯結合在一塊兒。經過JSP頁面還能夠使用定製標記或者Scriptlet,而不是使用JavaBean類來將內容與應用邏輯結合起來。定製標記被打包到一個標記庫中,並被引入到一個JSP頁面中。Scriptlet是直接嵌入在JSP頁面中的Java代碼段。

在JSP引擎中,JSP頁面在執行時是編譯式,而不是解釋式的。解釋式的動態網頁開發工具如ASP、PHP等因爲效率不高、編寫不便等緣由已經知足不了當前大型電子商務應用的須要了,傳統的開發技術都在向編譯執行的方式改變,如ASP→ASP.NET。JSP頁面被編譯爲Servlet的Java源文件,再通過Java編譯器編譯爲Servlet的class文件。在JSP文件轉譯爲Servlet之後,每次客戶機(一般是用戶的Web 瀏覽器)向服務器請求這一個JSP文件的時候,服務器將檢查自上次編譯後JSP文件是否有改變,若是沒有改變,就直接執行Servlet,而不用再從新編譯,其效率是至關高的。通常地,Web服務器還能夠做出設置,使JSP文件在第一個用戶訪問以前就預先編譯好,這樣執行的效率就更高了。

 
 
 
 

第 1 章:JSP及其相關技術導航做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP的優點及與其餘Web開發語言的比較

 

和傳統的CGI相比較,JSP有至關的優點。首先,在速度上對於CGI來講,每個訪問就須要新增長一個進程來處理,進程不斷地創建和銷燬對於做爲Web 服務器的計算機將是不小的負擔。JSP能夠用線程的方式來應對客戶端的訪問,這樣須要消耗的系統資源更小。JSP是專門爲Web開發而設計的,其目的是爲了創建基於Web的應用程序,包含了一整套的規範和工具。

和ISAPI和NSAPI相比較,JSP的開發速度要快得多,開發難度也要小得多。並且ISAPI和NSAPI這種和Web 服務器過於緊密結合的技術在使用時的一旦出現錯誤,有可能致使Web 服務器崩潰,而JSP是線程安全的,且沒有諸如C語言中的指針之類的操做內存的機制,所以編寫出來的程序顯得更加安全和可靠。

JSP的競爭對手是ASP.NET和PHP,在Web 技術方面ASP.NET、PHP和JSP的比較見表1-1。

表1-1 ASP.NET、JSP、PHP比較

 

1. Web 服務器和運行平臺

ASP.NET主要應用於Windows平臺,在添加組件後也能夠用於Linux平臺。儘管有第三方的插件號稱能夠在UNIX下使用ASP.NET,但ASP.NET常常須要使用COM組件封裝已有的程序模塊,而UNIX平臺並不支持COM。

JSP得益於Java的跨平臺性,它能夠在許多平臺下使用。

Apache Web Server是世界上佔有率最高的Web 服務器產品,能夠在包括SUN Solaris、IBM AIX、Linux和Windows在內的許多操做系統下運行。Apache Web Server下JSP的實現能夠經過免費的Apache Jserv 和GNUJSP、Jakarta-Tomcat實現,也能夠使用商業的JRUN (LiveSoftware)、WebLogic(BEA)、Websphere(IBM)來實現。

還能夠使用應用服務器添加JSP支持的Netscape Enterprise Server及由之發展而來的能夠直接支持JSP的iPlanet Web Server等等。

PHP自己就對各類操做系統和Web 服務器作了支持,PHP目前能夠做爲Apache的一個附加模塊直接編譯進入Apache中去,因爲Apache支持多種操做系統,PHP相應地也就能夠在各類操做系統上實現。PHP也能夠CGI方式或ISAPI方式插入到IIS或PWS中去。

2. 組件技術

ASP.NET和JSP對組件技術的支持已經比較完善了,而PHP直到前不久纔開始支持COM,但支持能力還不夠強,若是PHP不能在未來完善對組件技術的支持,在大型Web 應用程序方面將很難與JSP和ASP競爭。但因爲PHP技術自己的易學易用,加上衆多的函數支持和開放源代碼的特性,在中小型Web 站點的開發上,PHP仍是會佔有一席之地的。

JSP自己相對於ASP.NET和PHP並無明顯的優點,JSP的強大是由於其後面有強大的Java技術作支持。包括JavaBean和EJB技術在內的J2EE技術體系是JSP強大生命力的所在。

有理由認爲,在未來的Web 開發中,中小型站點將出現JSP、ASP.NET和PHP三分天下的局面,可是對於大型的電子商務站點,JSP與ASP.NET技術將成爲首選。

 
 
 
 

第 1 章:JSP及其相關技術導航做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

用JSP開發Web應用程序的幾種主要方式

 

JSP做爲J2EE的一部分,既能夠用於開發小型的Web 站點、也能夠用於開發大型的、企業級的應用系統,本節將講述對於不一樣規模的Web 系統,使用JSP進行開發的不一樣方式。

1.直接使用JSP

對於最小型的Web 站點,能夠直接使用JSP來構建動態網頁,這種站點最爲簡單,所須要的僅僅是簡單的留言板、動態日期等基本的功能。對於這種開發模式,通常能夠將全部的動態處理部分都放置在JSP的Scriptlet中,這有些相似於使用PHP或ASP開發動態網頁。

2.JSP+JavaBean

中型站點面對的是數據庫查詢、用戶管理和少許的商業業務邏輯。對於這種站點,不能將全部的程序都編寫在JSP頁面中。利用JavaBean,將很容易完成如數據庫鏈接、用戶登陸與註銷、購物車等商業業務邏輯封裝的任務。如:將經常使用的數據庫鏈接寫爲一個JavaBean,既方便了使用,又能夠使JSP文件簡單而清晰,經過封裝,還能夠防止通常的開發人員直接得到數據庫的控制權。

3.JSP+JavaBean+Servlet

不管用ASP仍是PHP開發動態網站,長期以來都有一個困擾着的問題,就是網站的邏輯關係和網站的顯示頁面不容易分開。經常能夠看見一些夾雜着if......then......、case select或是if{......}和大量顯示用的HTML代碼的ASP、PHP頁面,即便是有着良好的程序寫做習慣的程序員,其做品也幾乎沒法閱讀。另外一方面,動態Web的開發人員也在抱怨,將網站美工設計的靜態頁面和動態程序合併的過程是一個異常痛苦的過程。

如何解決這個問題呢?有了JSP後,表現數據的任務由JSP完成,而Servlet再也不擔負動態頁面生成的任務,卻開始擔負起決定整個網站邏輯流程的任務。在邏輯關係異常複雜的網站中,藉助於Servlet和JSP良好的交互關係和JavaBean的協助,徹底能夠將網站的整個邏輯結構放在Servlet中,而將動態頁面的輸出放在JSP頁面中來完成。在這種開發方式中,一個網站能夠有一個或幾個核心的Servlet來處理網站的邏輯,經過調用JSP頁面來完成客戶端(一般是Web瀏覽器)的請求。

 
 
 
 

第 1 章:JSP及其相關技術導航做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

小結

 

目前JSP技術已經成爲了開發Web應用的主流技術,在國內外獲得了普遍的應用。本章主要是對JSP的知識體系和技術特色做歸納性的介紹,使讀者對JSP有一個總體的瞭解。

JSP技術不是一項孤立的技術,若是僅僅掌握了JSP技術自己將難以知足實際開發的須要。想成爲一名優秀的JSP開發人員,必須掌握與JSP技術密切聯繫的HTML、數據庫開發、應用服務器的安裝與配置、XML等知識。

JSP、ASP.NET和PHP是當今主流的Web開發技術。JSP與ASP.NET和PHP相比有許多優點,例如跨平臺、能夠利用J2EE分佈式計算能力、使業務邏輯與頁面分離。另外,JSP開發Web應用程序時主要有3種方式,分別是直接使用JSP、JSP+JavaBean、JSP+JavaBean+Servlet。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Java開發工具

 

第2章 開發環境的安裝與配置

【本章專家知識導學】

開發環境的安裝與配置是學習jsp程序開發的第一步。本章將講述目前比較流行開發環境的基礎知識以及安裝、配置方法,諸如JDK、Eclipse等。讀者要融會貫通地掌握它,若是已經比較熟悉的讀者可跳過本章的學習。Eclipse和Tomcat的安裝與配置是本章的重點,但願讀者能熟練掌握。

本章還將引入配置管理工具和中間件的概念。軟件配置用來保證全部配置項的完整性和可跟蹤性。配置管理是對工做成果的一種有效保護,對複雜、大型的軟件項目開發具備很強的實用意義。

2.1 Java開發工具

本節主要介紹JDK和Eclipse。JDK是開發Java程序所須要的基本開發工具,Eclipse是目流程的Java集成開發工具。

 

 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JDK

 

Sun公司在推出Java語言的同時,推出了一套開發工具JDK,JDK提供了Java開發經常使用的類庫。JDK開發工具備Solaris、Windows NT、Windows 95等多種版本,本節介紹JDK1.5版,包括javac、ja-va、jdb、javah、javap、javadoc和appletview等工具,涵蓋了對Java源文件的編譯,執行Java字節碼文件等工具。

讀者能夠從Sun公司的網站http://www.sun.com上免費下載獲得JDK的安裝文件,也能夠從以下的網址下載獲得JDK1.5:

http://jvm.cn/soft/jdk-1_5_0_08-windows-i586-p.exe

javac,即Java語言編譯器,是JDK提供的重要工具之一,可以把由Java語言書寫的程序編譯成字節代碼。 

(1)javac使用的語法格式

javac [選項] 文件名.java 

(2)javac的功能

javac命令把Java語言源碼編譯成字節碼,字節碼文件的擴展名爲.class。Java源程序文件名後綴必須是java。javac編譯器對每個Java源文件中定義的類,生成一個保存編譯結果字節碼的文件,其後綴爲class。若是程序中須要引用另外一個類,則須要使用classpath環境變量指明存放路徑。若是在源程序中引用了一個在該目錄下其它文件中都沒定義的類,則javac搜尋classpath指明的類路徑。 

【專家提示】若是沒有指定-classpath參數,系統老是把系統變量CLASSPATH中設置的類路徑附加到類路徑中。 

(3)語法中有關[選項]的說明

-classpath類路徑:指定javac搜尋類的路徑,覆蓋CLASSPATH環境變量指定的類路徑。目錄名由冒號(:)分開,如:home/awh/classes:/usr/local/java/classes。

-d 目錄:指定存放編譯結果的類根目錄。

-g :生成調試表。調試表包含調試工具使用的行號和局部變量信息。缺省時只有行號信息。

-nowarn:關閉警告錯誤。使用該選項後編譯器不生成任何警告錯誤。 

-O:經過嵌入靜態、final、私用方法優化編譯代碼。注意,使用該選項後結果文件的大小會增長。 

-verbose:使編譯器和連接器顯示出正被編譯的文件名和正被裝載的類名。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Eclipse

 

2001年11月IBM出資4千萬美金開發的軟件開放源碼項目——Eclipse問世。Eclipse 是替代IBM Visual Age for Java(如下簡稱IVJ)的下一代IDE開發環境,但它將來的目標不只僅是成爲專門開發Java程序的IDE環境,還能經過開發插件,擴展到任何語言的開發。目前,Eclipse已經開始提供C語言開發的功能插件。Eclipse是一個開放源代碼的項目,也就是說將來只要有人須要,就會有創建在Eclipse之上的COBOL、Perl、Python等語言的開發插件出現。

Eclipse是開放源代碼的項目,讀者能夠到http://www.eclipse.org去免費下載Eclipse的最新版本,這個網站上提供了幾個下載版本:Release,Stable Build,Integration Build和Nightly Build,建議下載Release或Stable版本。Eclipse自己是用Java語言編寫,但下載的壓縮包中並不包含Java運行環境,須要用戶本身另行安裝JRE。

圖2-1 Eclipse顯示的缺省界面

下面將分別對Eclipse的各類特性做簡單介紹,包括:文件存放,開發環境,編譯與運行,版本管理,使用插件。 

(1)文件存放 

Eclipse把全部的源代碼都存儲到一個reponsitory庫文件中,想要獲得文本格式的源代碼必須用Export功能從reponsitory中導出以文本方式保存的源代碼。安裝Eclipse以後,在安裝路徑的下一層路徑中會有一個叫workspace的文件夾。每當在Eclipse中新生成一個項目,缺省狀況下都會在workspace中產生和項目同名的文件夾以存放該項目所用到的所有文件。能夠用Windows資源管理器直接訪問或維護這些文件。 

將已有的文件加入到一個項目中目前有三種方式:第一種是用IDE的「File」菜單中的「Import」功能將文件導入到項目中。第二種是從Windows的資源管理器中直接拖動文件到項目中。第三種就是直接將文件拷貝到項目文件夾中,而後在Eclipse的資源瀏覽窗口中選擇項目或文件夾並執行從本地刷新功能(Refresh from locate)。須要說明的一點是,項目文件夾能夠放在計算機的任何位置,而且能夠在Eclipse中用新建項目的方法將項目路徑指定到已經存在的項目文件夾,而後在Eclipse中刷新便可。

(2)Eclipse開發環境 

Eclipse的開發環境被稱爲Workbench,它主要由三個部分組成:視圖(Perspective),編輯窗口(Editor)和觀察窗口(View)。

圖2-2 關係結構略圖

文件的顯示和編輯包含在編輯窗口裏。缺省狀況下打開的多個文件是以標籤(TagTable)方式在同一個窗口中排列,能夠用拖動方式將這些文件排列成各類佈局。

文件被加入到項目中後,在資源瀏覽或Java包瀏覽窗口雙擊文件,Eclipse會試圖打開這個文件:其中Eclipse內嵌的編輯器能缺省打開一些文件,如*.java,*.txt等等。若是是其它類型的文件,Eclipse會調用操做系統相應的缺省編輯器打開,如word文檔。例如在Eclipse項目中雙擊HTML文件時,可能但願是用Notepad打開,而不是用系統缺省的IE瀏覽器打開。實現的方法是打開菜單欄中的「Windows」→「Preferences」對話框,以後在對話框中選擇「WorkBench」→「File Associations」,而後添加文件類型,再爲其指定編輯器便可。 

瀏覽窗口和Java瀏覽窗口是觀察窗口核心部分。後者用來瀏覽項目中的Java包,包中的類,類中的變量和方法等信息。類中的編譯出錯信息能夠在任務窗口中查到,同時它也能夠成爲名符其實的任務窗口:向其中添加新的任務描述信息,來跟蹤項目的進度。控制檯則主要用來顯示程序的輸出信息。

一個視圖包括一個或多個編輯窗口和觀察窗口。視圖是Eclipse的最靈活的部分,能夠自定義每一個視圖中包含的觀察窗口種類,也能夠自定義一個新視圖。這些功能都被包括在"Perspective" 菜單中。在Eclipse的Java開發環境中提供了幾種缺省視圖,如資源視圖(Resource Perspective),Java視圖(Java Perspective),調試視圖(Debug Perspective),團隊視圖(Team Perspective)等等。每一種視圖都對應不一樣種類的觀察窗口。能夠從菜單欄中的「Windows」→「Show View」看到該視圖對應的觀察窗口。

(3)編譯與運行 

在Java視圖中,工具欄中有兩個按鈕如圖2-3所示,分別用來進行調試和運行程序。因爲安裝的插件不一樣Eclipse可能會存在多種運行和調試程序的方式,爲了肯定當前項目用那一種方式運行,須要在「Run」菜單中設置「Run As…」或「Debug As…」選項。一般咱們須要用的是「Java Applicantion」方式。在這種方式下,若是當前位置是包含main()方法的Java程序,點擊調試或運行按鈕就會當即開始執行調試或運行功能。若是當前位置是在包或項目上,Eclipse會搜索出當前位置所包含的全部可執行程序,而後由程序員本身選擇運行哪個。 

圖2-3  Eclipse的工具欄中的運行與調試按鈕

(4)版本管理 

Eclipse的版本管理分爲我的(或稱爲本地)和團隊兩種。 

Eclipse提供了強大的我的版本管理機制,每一次被保存的更改均可以獲得恢復。並且能夠精確到每個方法的版本恢復。操做也十分方便,在任何一個能看到所要操做文件的觀察窗口中,例如資源瀏覽窗口,選中該文件,點擊右鼠標鍵,選擇「Compare with」或「Replace with」,按照你的需求找到相應的版本就能夠了。強大的我的版本管理功能爲程序員提供了更多的安全保障。

Eclipse缺省爲版本管理工具CVS提供了接口,能夠很是方便的鏈接到CVS服務器上。CVS的指示咱們後面還會遇到。經過CVS版本管理,Eclipse爲團隊開發提供良好的環境。要鏈接CVS服務器須要先打開團隊視圖(Team Perspective),而後在Reponsitories觀察窗口中點擊鼠標右鍵並選擇新建(New),在打開的對話框中能夠填入要鏈接的CVS庫所須要的信息,如CVS服務器類型,還要填入用戶名,主機名,密碼,reponsitory地址等信息。 

(5)使用插件 

使用插件能夠豐富Eclipse的功能。下面將介紹如何應用插件來嵌入Tomcat服務器。這個插件是一家叫sysdeo的公司開發的,很是小巧。讀者能夠到http://www.sysdeo.com/eclipse/tomcatPlugin.html去免費下載。另外,這個插件只支持Tomat4.0以上的版本,讀者能夠在www.apache.org獲得Tomcat的最新版本。 

只需將下載的zip文件解壓縮,並將其中的plgins目錄中的內容拷貝到Eclipse的安裝路徑的plugins目錄下面,而後從新啓動Eclipse。啓動後在菜單欄上選擇「Windows」「Customize Perspective…」菜單,在打開的對話框中選中「Other Tomcat」。以後立刻會發現Eclipse有了兩處變化:菜單欄中多了一個Tomcat選項,工具欄中多了兩個按鈕,如圖2-3所示。

圖2-3 Eclipse 界面

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

配置管理工具

 

CVS是目前比較流行的一款優秀的版本管理與控制工具,是用來管理其它平常文檔(如word工做文檔之類)的一個強有力的工具。WinCVS是CVS的一個客戶端軟件,它運行在Windows上。企業內部能夠採用Linux/Unix/Windows作服務器,用Windows作客戶端,因此WinCVS與CVS服務器是目前應用最普遍的版本控制與管理的組合。下面主要介紹WinCVS的平常操做。

(1)第一步:安裝Wincvs

執行setup.exe按提示完成安裝。.安裝完畢後運行wincvs。

(2)第二步:配置WinCVS參數

「Preferences」→「 General」:普通參數設置。

圖2-4 Wincvs 配置界面

Authentication:驗證方式,CVS默認採用pserver。

Path:CVS服務器的路徑,就是Repository(倉庫)。

Host address:CVS服務器的IP地址或者域名。

User name:用戶名。

CVSROOT:CVSROOT,由上面4項生成的字符串,用於鏈接服務器。

「Preferences」→「Globals」:全局參數設置。

checkout read-only: 檢出只讀,wincvs默認導出文件爲只讀狀態。去掉該選項。

Prune(remove)empty directories剪除(刪除)空目錄,去掉該選項。

「Preferences」→「WinCVS」:WinCVS參數設置。

圖2-5   WinCVS參數設置

(3)第三步:登陸。

圖2-6 登錄界面

   正常登陸後便可開始使用CVS了。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Java Web中間件

 

傳統的HTML已經知足不了現在web系統的諸多的功能需求,創建一個交互式的Web,便誕生了各類Web開發語言,如ASP,JSP,PHP等,這些語言與傳統的語言有着密切的聯繫,如JSP基於Java語言。 JSP是在普通的HTML代碼中嵌入了特定的Java代碼後造成的源代碼文件。JSP源文件由JSP容器(如Tomcat)首先將其轉化爲Servlet,而後再調用Javac將Servlet編譯爲.class文件,最終,服務器執行的是class文件。 

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Tomcat

 

Tomcat是一個免費的開源的JSP容器,它是Apache基金會的一個核心項目,由Apache、Sun和其它一些公司及我的共同開發而成。因爲有了Sun的參與和支持,最新的Servlet和JSP規範總能在Tomcat中獲得體現。

在Tomcat中,應用程序的部署很簡單,只需將你的war文件(Java Web應用系統的包文件)放到Tomcat的webapp目錄下,Tomcat會自動檢測到這個文件,並將其解壓。在瀏覽器中訪問這個應用的JSP文件時,一般第一次會慢一點,由於Tomcat要將JSP轉化爲Servlet文件,而後編譯。編譯之後再次訪問將會很快了,由於無需再行編譯了。另外Tomcat也提供了一個應用—manager,訪問這個應用須要用戶名和密碼,用戶名和密碼存儲在一個xml文件中。經過manager這個應用,能夠遠程以Web方式部署和撤銷應用。

Tomcat不只僅只是一個JSP容器,也具備傳統的Web服務器的功能:處理Html頁面。可是與Apache相比,它的處理靜態HTML的能力就不如Apache。能夠將Tomcat和Apache集成到一塊,讓Apache處理靜態HTML,而讓Tomcat來處理JSP和Servlet。 

Tomcat也提供其它的一些特徵,如與SSL集成到一塊,實現安全傳輸。還有Tomcat也提供JNDI支持。然而Tomcat只是一個輕量級的Web服務器,並不象諸如Weblogic之類的J2EE應用服務器功能那麼強大。一般所說的J2EE應用服務器(如WebLogic)與Tomcat又有何區別呢?應用服務器提供更多的J2EE特性,如EJB,JMS,JAAS等,同時也支持JSP和Servlet,而Tomcat則功能沒有那麼強大,它不提供EJB等支持。但Tomcat若是與JBOSS(一個開源的應用服務器)集成到一塊,也能夠實現J2EE的許多功能。在不少中小型應用場合中不須要採用EJB等複雜的技術,JSP和Servlet的組合已經可以勝任,這時若是採用J2EE應用服務器就沒有必要了。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

WebLogic

 

BEA  WebLogic是用於開發、集成、部署和管理大型分佈式Web應用、網絡應用和數據庫應用的Java應用服務器,能將Java的動態功能和Java企業級標準的安全性引入大型網絡應用的開發、集成、部署和管理之中。BEA WebLogic Server擁有處理關鍵Web應用系統問題所需的性能、可擴展性和高可用性。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

WebSphere

 

WebSphere是IBM的一套軟件產品,包括WebSphere應用服務器,WebSphere Studio和 WebSphere Performance Pack。WebSphere可在30多種操做系統平臺上運做,除計算機外,還可用於PDA、信息家電等產品,跨平臺能力較強。WebSphere目前在全球已有超過35000家企業採用。近期,IBM力推的中間件(middleware)平臺WebSphere將推出新版本,預計將進一步提高IBM在應用服務器市場上的份額,對市場龍頭BEA Systems構成威脅。目前WebSphere在全球應用服務器產品中排名第二,僅次於BEA Systems的WebLogic,但在亞太區已排名第一。該產品包括一個基於 Java 的 Servlet 引擎,獨立於 Web 服務器和它所基於的操做系統。WebSphere應用服務器提供了服務器插件的選項,與大多數流行的應用程序設計接口(API)兼容。

WebSphere因爲面向專業人員,要掌握它的管理與使用有必定的難度。此外,WebSphere自己須要佔用2G多的磁盤空間,須要256M以上內存支持,系統配置相對要求較高。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

本書開發環境的安裝與配置

 

本書使用JDK1.5+Tomcat5.5來做爲開發環境,下面來看這兩個工具的安裝與配置方法。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

安裝JDK

 

(1)安裝JDK

從http://www.sun.com或從以下地址可下載獲得JDK1.5:

http://jvm.cn/soft/jdk-1_5_0_08-windows-i586-p.exe

雙擊jdk-1_5_0_08-windows-i586-p.exe即會開始安裝,界面如圖2-7所示。安裝過程當中,還會提示安裝JRE1.5,這裏單擊安裝JRE1.5界面中的「更改…」按鈕,更改JRE1.5的安裝目錄,這裏更改成「c:\jre15」,再單擊「下一步」按鈕會繼續安裝,直至安裝完畢。JDK1.5的安裝目錄與JRE1.5的安裝目錄要設置同樣,不然可能會互相沖突,而致使Web應用服務軟件Tomcat5.5在啓動時不能識別JDK的版本而沒法啓動。

圖2-7 JDK安裝界面

在Windows操做系統的桌面上使用鼠標右擊「個人電腦」,打開「屬性」對話框,在「高級」選項卡上單擊「環境變量」,打開「環境變量」設置對話框,進行以下操做:

系統變量->新建->變量名:JAVA_HOME(JDK的安裝目錄,如「c:\jre15」 )。

系統變量->新建->變量名:CLASSPATH(類的路徑,如「.;%JAVA_HOME%\lib」)。 

系統變量->編輯->變量名:Path(尋找應用程序的目錄,能夠在最前面加入「%JAVA_HOME%\bin;」)。  

【專家提示】CLASSPATH中有一個英文句號「.」後跟一個分號,表示當前路徑的意。以上變量中,若是變量名已經存在則無需新建,編輯變量的值便可。

(2)測試JDK安裝是否正確 

進入命令窗口(在Windows桌面上單擊「開始」「運行」,輸入cmd進入命令窗口(Windows95/98下輸入command)。 

執行以下的命令: 

javac -version 

窗口會回顯如圖2-8的信息:

圖2-8 查看JDK的版本信息

若是能顯示JDK的版本信息(不必定與以上文字徹底相同),則說明JDK環境安裝成功。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

安裝與配置Tomcat

 

(1)安裝Tomcat

從http://tomcat.apache.org上能夠下載到Tomcat的安裝程序、源代碼及相關的文檔,本書使用的Tomcat5.5。Tomcat不能單獨使用,安裝以前必須先行安裝JDK。在如圖2-9所示的網站,在左邊的Download區中點擊Tomcat版本的超連接能夠下載相應版本的Tomcat。

圖2-9  Tomcat的下載地址

獲得Tomcat5.5的壓縮文件後,將其用解壓縮軟件,如WinZip或WinRar,解壓至指定的目錄,這裏咱們解壓至d:\tomcat55,實際應用可根據須要而定。

Tomcat5.5發佈的程序版本有三種:zip版、tar.gz版和Windows Executable版。在Windows操做系統中,Windows Executable版本的安裝可根據嚮導提示安裝,再也不敘述;zip版無須安裝,直接拷貝解壓縮目錄下的全部文件至指定目錄便可。這裏推薦使用zip版,由於Windows Executable版雖然安裝簡單,但在安裝過程當中會修改系統的註冊表,當通過屢次安裝Tomcat後,會出現一些不可預料的錯誤;而zip版無需設置,解壓便可使用。

執行Tomcat安裝目錄bin子目錄下的startup.bat程序就可啓動Tomcat5.5服務器。結果如圖2-10所示。

圖2-10  運行Tomcat5.5

(2)測試是否安裝成功

接下來,測試一下Tomcat服務器。打開瀏覽器,在地址欄中輸入http://localhost:8080或http://127.0.0.1:8080,127.0.0.1與localhost均表明本機,會出現如圖2-11所示的頁面。

圖2-11   測試Tomcat5.5

(3)配置Tomcat

Tomcat默認的Web服務端口號是8080,IE瀏覽器默認的HTTP服務端口號是80,若是將Tomcat的Web服務端口號改成80,則在訪問服務器時沒必要再輸入端口號了。若是是在系統自帶了IIS(Windows 2000 server、Windows XP等操做系統自帶的支持ASP技術的Web服務器軟件),要注意IIS默認的HTTP服務端口號也是80,容易產生衝突。固然讀者也能夠把Tomcat的Web服務端口號改成你所要設置的數值。下面講解怎麼更改Tomcat的Web服務端口號。

在Tomcat的安裝目錄中有個叫config的子目錄,進入後打開其中的server.xml文件,能夠使用任一文本編輯器,通常使用記事本便可。在server.xml找到以下的一段文字。

 <!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->

<Connector port="8080" maxHttpHeaderSize="8192"

maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

enableLookups="false" redirectPort="8443" acceptCount="100"

connectionTimeout="20000" disableUploadTimeout="true" />

<!-- Note : To disable connection timeouts, set connectionTimeout value

to 0 -->

若是以爲目視查找比較困難,可用記事本「編輯」菜單下的「查找」工具,查找「8080」,以進行定位查找,很快就能夠找到上述的文字。將這段文字中的port=「8080」更改成port=「80」便可。從新啓動Tomcat服務器,再次測試Tomcat服務器時將不須要輸入端口號。

虛擬目錄是針對提供Web服務的目錄而言的。能夠把硬盤中的一個目錄映射成Web服務目錄的一個子目錄,但它事實上並不在Web服務目錄中,這樣用戶訪問這個目錄時實際上訪問的並不是是Web服務目錄中的文件,但給他的感受就好象是Web服務目錄中的文件,這個被映射成Web服務目錄的子目錄就稱爲虛擬目錄。

使用虛擬目錄能夠提升Web服務器的安全,即使是Web服務器被攻破,黑客也沒法獲得程序的源代碼;此外,當Web服務目錄的磁盤空間不夠時,能夠用配備在其它磁盤上的虛擬目錄來解決這個問題。

在Tomcat5.5中配置虛擬目錄的方法是編寫一個xml文件,內容以下:

<Context path="/jsp" docBase="e:/jsp" debug="0"

reloadable="true" crossContext="true">

</Context>

其中「path="/jsp"」表示配置的虛擬目錄的名稱,「docBase="e:/jsp"」是虛擬目錄指向的事實目錄。將此文件保存於Tomcat5.5安裝目錄的「conf/Catalina/localhost」文件夾下,文件名爲jsp.xml。保存後,Tomcat5.5會自動更新配置。

【專家提示】配置虛擬目錄的xml文件的命名規則是:虛擬目錄的名稱爲xml文件的文件名,如此處,虛擬目錄的名稱爲「/jsp」,則xml文件名稱爲jsp.xml。

 
 
 
 

第 2 章:開發環境的安裝與配置做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

小結

 

 在本章中,介紹了Java開發須要使用到的開發工具JDK,以及流行的IDE開發工具—Eclipse;初步領略了配置管理工具CVS,還介紹瞭如今應用較爲普遍的三種JSP的服務器。Tomcat因爲佔用系統資源少,而被較多地應用於程序編寫與調試,以及被小型Web信息系統做爲Web服務器軟件。接着還學習了本書的運行環境的安裝與配置,包括JDK1.5和Tomcat5.5的安裝與配置,講解了Tomcat上HTTP服務端口號與虛擬目錄的配置。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP程序的結構

 

第3章  JSP語法

【本章專家知識導學】

JSP是創建在Java語言基礎上的一種Web程序設計語言,具備本身特有的用法和指令。本章首先介紹JSP頁面的程序結構,而後講述JSP程序中常常用到基本的面向對象Java語言程序基礎知識,最後講在JSP中特有的JSP指令和JSP動做指令。

經過本章的學習,應當深刻了解JSP語法,並能靈活運用JSP語法編寫簡單的JSP頁面和其中的Java程序。

3.1  JSP程序的結構

JSP頁面的文件名以「.jsp」爲後綴,在一個JSP頁面中,除了基本的HTML語言元素外,主要還包含三種基本元素:JSP指令、JSP動做指令和JSP代碼。JSP指令用於告訴JSP的Web引擎(如Tomcat)須要在編譯時作什麼動做,好比引入一個其它的類,設置JSP頁面使用什麼語言編碼等。JSP動做指令則是在JSP頁面被請求時動態執行的,好比能夠根據某個條件動態跳轉到另一個頁面。JSP代碼指的就是嵌入在JSP頁面中的Java代碼,即Java程序片,它一般包含JSP表達式、變量和方法的聲明以及Java語句。全部HTML文件能夠在瀏覽器中直接打開查看運行效果,可是JSP文件必須先放到Web服務器中,而後經過HTTP的方式訪問。

【例3-1】一個簡單的JSP程序結構示例

3-1.jsp

<%@ page contentType="text/html;charset=gb2312" %>

<html> 

<head><title>

一個簡單的JSP程序結構示例

</title></head>

<body>

生成並顯示一個從0~9的字符串:

<%! String str="0"; %>

<% for (int i=1; i <10; i++) {

str = str + i;

%>

<p> <%= str %> 

</p> 

</body>

</html>

這個簡單JSP頁面的基本結構程序包含了三部分:普通的HTML標記、JSP指令和JSP代碼。經過一個for語句生成並顯示一個從0~9的字符串,程序的執行結果如圖3-1所示。

圖3-1  一個簡單的JSP程序結構示的運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Java程序片

 

在JSP中,在「<%」和「%>」包含的程序代碼稱爲Java程序片,它能夠是JSP表達式、JSP的腳本代碼以及JSP中變量和方法的聲明。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP表達式

 

JSP表達式包含一個符合JSP語法的表達式,JSP表達式使用的方法以下:

<%=表達式%>

其中:「<%=」和「%>」之間爲JSP表達式,一對錶達式標誌「<%=」和「%>」中只能有一個表達式。例如:

<%="Hello World!" %>

<%= 1+1 %>

表達式中的變量須要在腳本程序中事先聲明,表達式運行後的結果會被自動地轉化爲字符串,而後插入到這個表達式在JSP文件中的位置,顯示在網頁上。由於這個表達式的值自動地轉化爲字符串,因此能在一行文本中插入這個表達式,Web引擎遇到「<%=」符號後,就會把「<%=」和「%>」中的內容做爲表達式來解析。

【專家提示】JSP表達式標誌不能用一個分號「;」來做爲表達式的結束符,可是一樣的表達式用在Java腳本代碼中就須要以分號來結尾了。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Java腳本代碼

 

Java腳本代碼(Java Scriptlet)是指在JSP頁面中的「<%」和「%>」之間插入的Java程序代碼。Java腳本代碼使用的語法格式以下:

<% Java腳本代碼%>

其中「<%」和「%>」之間爲Java腳本代碼。

「<%」和「%>」是Java腳本代碼標誌。Java腳本代碼中能夠包含多個JSP語句、方法、變量、表達式,它能夠訪問JSP對象、操做數據庫、使用Java類庫中的類等,利用這些能夠在JSP頁面內實現較複雜的邏輯功能。有了Java腳本代碼,便能作如下的事:

(1)聲明將要用到的變量或方法。

(2)編寫JSP表達式。

(3)使用任何隱含的對象和任何用<jsp:useBean>聲明過的對象。

(4)編寫Java語句。

Java腳本代碼由服務器負責把它轉化成對應的Servlet的Service方法。當JSP服務器收到客戶的請求時,Scriptlet就會被執行,若是Java腳本代碼中有顯示的內容(即向瀏覽器頁面的輸出),這些顯示的內容就被輸出到out對象流中,造成網頁的動態部分。

【例3-2】JSP腳本代碼示例

3-2.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<%@page language="java" %>

<html>

<head><title> JSP腳本代碼示例</title>

</head>

<body>

<h3> Java Scriptlet</h3>

<%

   for (int i =1;i <=5;i ++)

   {

%>

<p>

 i=<%= i %>

</p>

<%

   }

%>

</body>

</html>

例3-2是使用循環語句在網頁中顯示i值(1 2 3 4 5)的JSP頁面代碼,其中的一個腳本代碼段如:<% for (int i =1;i <=5;i ++) { %>。

它不是完整的Java代碼語句,可是它和隨後的其餘腳本代碼段一塊兒構成完整的Java腳本代碼語句。不一樣的腳本代碼段之間能夠按須要添加HTML文本。其運行結果如圖3-2。

圖3-2 JSP腳本代碼示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

聲明變量或方法

 

聲明變量或方法的語法格式:

<%!聲明變量或方法的代碼%>

其中:「<%!」和「%>」之間爲Java腳本程序聲明的變量或方法。聲明的代碼不產生輸出,而只聲明瞭供訪問的方法和變量,所以一般要將其和Java表達式、Java腳本程序結合使用。

聲明的代碼用於聲明目標Servlet類的方法和變量(在處理HTTP請求的「service」方法以外)。在程序中也能夠一句聲明語句聲明多個變量和方法,只要以「;」結尾就行。固然這些聲明語句要合乎Java語法。

【專家提示】當聲明方法或變量時,要注意如下的一些規則:

(1)聲明必須以「;」結尾(Java腳本有一樣的規則,可是表達式就不一樣了)。

(2)能夠直接在<%@page%>語句中使用聲明語句,包含已經聲明瞭的變量和方法,不須要對它們從新聲明。

(3)一個聲明僅在一個頁面中有效。若是想每一個頁面都用到一些聲明,最好把它們寫成一個單獨的文件,而後用<%@include%>或<jsp:include>語句包含進來。

【例3-3】Java程序片綜合應用示例—一個簡單的計數器

3-3.jsp

<%@ page contentType="text/html;charset=gb2312"%>

<html>

<body>

<%!int counter=0;

 synchronized void counterFunction()

  {

   counter++;

  }

%>

<%counterFunction();%>

  網站計數器<br>

  您是第<%=counter%>位訪問者

</body>

</html>

本例的代碼是一個簡單的計數器程序,它前後聲明瞭一個計數器變量和計數的方法。計數器變量在客戶間共享,直到服務器關閉;而計數方法只作簡單的加1處理。Synchronized保留字表示串行化處理,即表示counterFunction()方法在某個時刻只能由一個語句調用。上述程序的其運行的結果如圖3-3所示。

圖3-3  Java程序片綜合應用示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP程序註釋

 

JSP頁面中經常使用的程序註釋主要有3種:JSP隱藏註釋、HTML註釋和Java語言中的註釋。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP隱藏註釋

 

JSP隱藏註釋寫在JSP程序中,但並不發送給客戶端,所以在客戶端瀏覽器中是看不到JSP隱藏註釋的。JSP隱藏註釋使用的語法格式以下:

<%--隱藏註釋語句--%>

其中:「<%--」和「--%>」之間的內容爲隱藏註釋語句。該標誌所包含的內容將被JSP編譯器忽略。該註釋在但願隱藏註釋JSP程序時是頗有用的,它不會對 「<%--」和「--%>」之間的語句進行編譯的,也不會顯示在客戶的瀏覽器中,固然也不會在客戶端源代碼中看到,並方便了程序員調試程序。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

使用HTML註釋

 

HTML註釋是在客戶端能夠顯示的註釋。HTML註釋語法格式以下:

<!-- HTML註釋語句 -->

其中:「<!--」和「-->」之間的爲HTML註釋。該語句包含內容將被插到相應輸出的HTML文本中。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Java語言提供的三種類型註釋

 

(1)單行註釋:以「 // 」開始,並以換行符結束。

(2)單行或多行註釋:以 「/* 」開始,並以「 */ 」結束。

(3)文檔註釋:以「 /** 」開始,並以「 */」結束,註釋中的每一行都必須以 * 開始。使用JavaDoc工具能夠從源代碼和文檔註釋中將註釋的文字信息取出,而後轉換爲HTML文件。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Java的基本數據類型

 

 Java語言包括簡單數據類型和引用數據類型,以下圖3-4所示。

圖3-4  Java語言的數據類型

這一節咱們主要介紹簡單數據類型和數組,類和接口放在後面3.7和3.11節來具體講解。

表3-1  簡單數據類型表

 

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

標識符

 

Java語言標識符用來表示變量、方法或類等的名字。Java語言標識符的組成規則爲:

(1)標識符必須以字母、下劃線(_)或美圓符($)開頭,

(2)標識符第一個字符後面能夠跟任意數目的字母、數字、下劃線(_)或美圓符($)。標識符的長度沒有限制。

(3)在聲明和使用標識符時須要注意,Java語言是大小寫敏感的。 

(4)標識符的命名應遵循Java編碼慣例,而且應使標識符能從字面上反映出它所表明的變量或類型的用途,但不能是關鍵字。全部Java關鍵字都是小寫的,true、false、null等都不是Java關鍵字;goto和const 雖然從未使用,但也做被爲Java關鍵字保留;true、false、null雖用作專門用途,但不是Java關鍵字。

Java語言的關鍵字包括9大類:

(1)原始數據類型:byte、short、int、long、float、double、char、boolean。

(2)循環關鍵字:do、while、for、break、continue。

(3)分支關鍵字:if、else、switch、case、default、break。

(4)方法、變量和類修飾符:private、public、protected、final、static、abstract、synchronized、volatile、strictfp。

(5)異常處理:try、catch、finally、throw、throws。

(6)對象相關關鍵字:new、extends、implements、class、instanceof、this、super。

(7)字面值常量:false、true、null。

(8)方法相關關鍵字:return、void。

(9)包相關關鍵字:package、import。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

簡單數據類型

 

(1)常量和變量 

常量是指在程序運行過程當中其值不變的量。常量有字面常量和符號常量兩種。常量在表達式中用文字串表示,它區分不一樣類型,如整型常量12三、-15,實型常量12.1f,字符常量' x ',布爾常量true,字符串類型常量"Test"。而符號常量聲明的通常格式以下:

<final> <數據類型> <符號常量標識符>=<常量值>;

例如:final double PI=3.141593;

final int COUNT=1000; 

變量是用來存放指定類型的數據,其值在程序運行過程當中是可變的。按變量聲明的位置Java的變量分爲兩種:類成員變量和局部變量。變量聲明的通常格式以下:

<數據類型> <變量標識符>=<值>

例如 double x=1.2345; 

(2)整型數據 

Java整型數據多爲十進制數形式,也可爲八進制或十六進制形式。Java整型數都爲帶符號數。整型缺省爲int型,若爲長整型需在數據後加字母l或L。

按照長度分爲:byte、short、int、long。int類型最爲經常使用,可知足大多數場合應用的須要,若是須要更大的整數就能夠使用long類型。byte類型範圍很小,數據範圍在-255到+255之間。short類型不多用,限制數據的存儲爲先高字節,後低字節,有時會引起錯誤,不提倡使用。

例如:byte b;      short s;

      int i;        long l;

(3)實型數據 

實型用十進制數形式表示,由數字和小數點組成,例如:3.25。也能夠用科學計數法形式表示,例如,123E-3。數後加f或F爲float,加d或D爲double,沒有後綴修飾的則缺省爲double類型。 

實型變量按長度分爲:float和double。雙精度浮點型double比單精度浮點型float的精度更高,表示數據的範圍更大,詳見表3-1。 

例如,float c;

      double d;

(4)字符型數據

字符型常量是用單引號括起來的一個字符,如:'J'、'*'。Java中的字符型數據是16位的Unicode字符,漢字和英文字母佔的內存空間相同。如「JAVA你好」共12個字節。

變量的聲明以下:

char ch='c';

Java中有以反斜槓(\)開頭的字符,反斜槓將其後面的字符轉變爲另外的含義,稱爲轉義字符。

表3-2  轉義字符

 

【專家提示】字符串常量是使用雙引號括起來的字符序列,注意,最後字符不是「\0」,這與C語言中不一樣。例如:"Let’s learn Java! "。Java中的字符串變量是做爲對象來處理的,經過String和StringBuffer類的構造方法來聲明,後續內容中還會有詳細的介紹。

(5)布爾型數據

布爾型常量值只有2個:true和false。布爾型變量爲boolean類型,取值爲true或false。

例如: 

boolean b=true;

(6)類型轉換

整型、實型、字符型數據能夠混合運算。運算過程當中,不一樣類型的數據會自動轉換爲同一類型,而後進行運算。自動類型轉換的規則是,低優先級的數據自動會轉換爲高優先級的數據。

而優先級高的數據類型要轉換成優先級低的數據類型,須要用到強制類型轉換。其通常形式爲:

(類型名)表達式 或

類型名(表達式)

例如:double d=3.14159d;

      int a=(int)d;

【例3-4】簡單數據類型應用示例

3-4.jsp

<%@ page contentType="text/html;charset=gb2312"%><!--JSP指令標籤-->

<%@ page import="java.util.*"%>                 <!--JSP指令標籤-->

<html><!--HTML標記符-->

<body>

<%//如下爲Java程序片

  boolean booleanTemp=true;

  byte byteTemp=100;

  char charTemp='x';

  int intTemp=234;

  short shortTemp=456;

  long longTemp=12345678;

  int changlong=(int)longTemp;

  float floatTemp=1.234F;

  double changfloat=floatTemp;

  double doubleTemp=1.23E-8;

  out.println("布爾變量booleanTemp值爲:"+booleanTemp+"<br>");

  out.println("字符型變量charTemp值爲:"+charTemp+"<br>");

  out.println("整型變量intTemp值爲:"+intTemp+"<br>");

  out.println("短整型變量shortTemp值爲:"+shortTemp+"<br>");

  out.println("字節型變量byteTemp值爲:"+byteTemp+"<br>");

  out.println("長整型變量longTemp值爲:"+longTemp+"<br>");

  out.println("強制類型轉化changlong 值爲:"+changlong+"<br>");

  out.println("單精度型變量floatTemp值爲:"+floatTemp+"<br>");

  out.println("自動類型changfloat值爲:"+changfloat+"<br>");

  out.println("雙精度型變量doubleTemp值爲:"+doubleTemp+"<br>");

%>

</body><!--HTML標記符-->

</html>

</body>

</html>

簡單數據類型應用示例程序聲明瞭幾個簡單數據類型,對其中的幾個進行了自動轉換和強制轉化,並輸出全部的值。其運行結果如圖3-5所示。

圖3-5 簡單數據類型應用示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

數組

 

數組是相同類型的數據元素按順序組成的一種複合數據類型,元素在數組中的相對位置由下標來指定。數組中的每一個元素經過數組名加下標進行引用。

(1)一維數組

一維數組的聲明格式以下: 

數組類型   數組名[ ] ;

或  

數組類型[ ]  數組名;

數組類型能夠是Java中的任何數據類型。數組名必須符合標識符聲明規則。「[]」指明該變量是一個數組類型的變量,可放到數組名後面,也可放到數組名前。 

在說明數組時,若是不直接指出數組中元素的個數(即數組長度),則在數組說明以後尚不能當即被訪問,還須要使用new操做來構造數組,爲數組元素分配內存空間,同時對數組元素進行初始化。其格式以下:

數組名=new類型[數組長度];

如:

int student[ ];

student=new int[10];

int student[]=new int[10];

數組初始化就是爲數組元素指定初始值。用new關鍵字爲一個數組分配內存空間後,系統將爲每一個數組元素都賦予一個缺省的初值,全部數值型數組元素的初值爲0,字符型數組元素的初值爲一個不可見的ISO控制符(\u000),布爾型數組元素的初值爲false,字符串數組和全部其餘對象數組在構造時元素的初值爲null。數組一旦建立以後,就不能再改變其長度。但在許多狀況下,並不但願數組的初始值爲默認值,此時,就須要用賦值語句來對數組的每一個元素賦值進行初始化。

數組的初始化還有一種方式是像初始化簡單類型同樣自動初始化數組,即在聲明數組的同時進行初始化,這個時候不須要使用new關鍵字。例如

int a[ ]={1,2,3,4,5};

【專家提示】注意數組的下標的取值範圍從0開始,一直到「數組的長度減1」。例如

int a[]=new int[10];

int b=a[0]+a[9];

數組下標爲從0到9。若是調用了a[10],程序運行時將提示越界錯誤:

java.lang.ArrayIndexOutOfBoundsException  

(2)二維數組

在Java中並不直接支持多維數組,因此,多維數組的聲明是經過對一維數組的嵌套形式聲明來實現的,即用「數組的數組」來聲明多維數組。例如,二維數組爲一個特殊的一維數組,其每一個元素又是一個一維數組。二維數組的聲明、初始化和引用與一維數組基本相同,只是二維數組比一維數組多了一個下標。例如:

int a[][]=new int[3][2]; 

int b[][]={{1},{2,3},{4,5,6}}; 

數組a被聲明爲一個3行2列的二維整數數組,並分配存儲空間,全部的數據元素都初始化爲0;數組b聲明瞭一個3行3列的二維整數數組,並同時給每一個數據元素賦初值。

【例3-5】數組應用示例

3-5.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<html>

<head>

<title>

數組應用示例

</title>

</head>

<body>

<%

int a[][]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};

int b[][]=new int[3][4];

int i,j'

System.out.println("數組a各元素的值爲:");

for (i=0;i<4;i++){

   for(j=;j<3;j++)

      System.out.print(a[i][j]+"\t");

      System.out.println();

}

for(i=0;i<4;i++)

   for(j=0;j<3;j++)

       b[j][i]=a[i][j];   //矩陣轉置

System.out.println("數組b各元素的值爲:");

for(i=0;i<=3;i++){

   for(j=0;j<4;j++)

System.out.print(b[i][j]+"\t");

System.out.println();

    }

%>

<html>

<body>

上述代碼聲明瞭一個二維整數數組a,輸出數組a的全部元素,而後把數組a轉置成數組b,並輸出數組b的全部元素。程序在瀏覽器中的運行結果如圖3-6所示。

圖3-6 數組應用示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

運算符與表達式

 

Java的運算符比較豐富,有算術運算符、關係運算符、布爾邏輯運算符、位運算符、賦值運算符、條件運算符等,一塊兒運用時又有必定的優先順序,下面來一一介紹Java的運算符。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

算術運算符

 

算術運算符用於對整型數和實型數的運算。如:+(加,取正值)、-(減,取負值)、++ (自加)、--(自減)以及+(加)、-(減)、*(乘)、/(除)、%(取餘數或取模)。

【專家提示】其中運算符++、--能夠位於操做數的前面,如++x 或--x,也能夠位於操做數的後面,如x++、x--。不管運算符++、--位於操做數的前面或後面,操做數完成其運算並把結果賦於操做數變量。可是注意,如把++x或x++總體參加表達式運算時,表達式的運算結果可能不一樣。

後綴++:變量首先進行操做再自身進行加1運算。y= x++等價於:

y= x;

x=x+1;

例如:

int a=2;     

int b=a++;   

運算結果:a=3,b=2

前綴++:變量自身首先加而後再進行操做。y=++x等價於:

x=x+1;

y= x;

例如:

int a=2;     

int b=++a;   

運算結果:a=3,b=3

【例3-6】算術運算符應用示例

3-6.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<html>

<head><title>算術運算符應用示例</title></head>

<body>

<%

int a=10;

out.println("a="+a+"<br>");

int b=++a;

out.println("a="+a+"<br>");

out.println("b="+b+"<br>");

int c=a++;

out.println("a="+a+"<br>");

out.println("c="+c+"<br>");

int d=--a;

out.println("a="+a+"<br>"); 

out.println("d="+d+"<br>");

int e=a--;

out.println("a="+a+"<br>");

out.println("e="+e+"<br>");

%>

</body>

</html>

上述程序代碼對運算符++、--的前綴和後綴算術符的運算結果進行了比較,其運行結果如圖3-7所示。

圖3-7 算術運算符應用示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

關係運算符

 

關係運算符完成操做數的比較運算,結果爲布爾類型值。關係運算符優先級低於算術運算符,同爲關係運算符則優先執行順序自左向右。

關係運算符有= =(等於)、!=(不等於)、<(小於)、<=(小於等於)、>(大於)、>=(大於等於)及instanceof (對象運算符)7種,在一個關係運算符兩邊的數據類型應一致,一個關係表達式的結果類型爲布爾型,即關係式成立爲true,不成立爲false。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

布爾邏輯運算符

 

布爾邏輯運算符有六個,它們是:!(非)、&(與)、&&(簡潔與)、|(或)、||(簡潔或)、^(異或)。這些運算符要求的操做數和結果值都是布爾型。

【專家提示】注意區別簡潔與&&(或||)和非簡潔與&(或|):&&,若是其前面的表達式爲假,則再也不計算其後面的表達式,整個表達式爲false;而&,無論其前面的表達式爲何,都計算其後面表達式。例如,

int a=6,b=8,c=10,d=12; 

boolean x=++a>b++&&c++>d--;

(a=7,b=9,c=10,d=12,x=false)

boolean x=++a>b++&c++>d--;

(a=7,b=9,c=11,d=11,x=false)

兩個表達式x都爲false,但它們最後的c、d的值不同。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

位運算符

 

Java位運算符用來對二進制的位進行運算。位運算符主要有按位取反~,按位與&,按位或|,按位異或^,左移<<,右移>>,無符號右移>>>等。在JSP應用程序設計中位運算符通常不多使用。

【專家提示】注意區分佈爾邏輯運算符中的&、|與位運算中的&、|,若是運算符的兩邊爲布爾值則爲布爾邏輯運算符,不然爲位運算符。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

賦值運算符

 

賦值運算符「=」用來把右邊表達式的值賦給左邊的變量,即將右邊表達式的值存放在變量名所表示的存儲單元中,這樣的語句又叫賦值語句。賦值運算符使用的語法格式以下:

變量名=表達式;

【專家提示】賦值運算符「=」與數學的等號含義不一樣。

賦值運算符還包括不少變體,如+=,-=,*=,/=,%=等。

例如,int a=b=c=3;

a+=b;

等價於:

a=a+b;

 

條件運算符是「?:」,它是Java 中唯一的三目運算符。它要求三個操做數,其格式以下:

<布爾表達式> ? <表達式1> : <表達式2>

第一個操做數必須是布爾表達式,其餘兩個操做數能夠是數值型或布爾型表達式。

條件運算符的含義是:當<布爾表達式>爲真時,整個表達式值爲<表達式1>的值,不然爲<表達式2>的值。例如:

int x=20,y=30,max; max =x>y ? x : y;

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

表達式

 

表達式是由操做數和運算符按照必定的語法格式組成表達某種表達式或含義的符號序列。例如,如下都是合法的表達式。

(a+b)*(c-d)    a=8-2*3<4&&5<2          a + b < c&&d= =e

每一個表達式通過運算後都會產生一個肯定的值,即表達式的值。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

運算符的優先級

 

表達式的運算次序取決於表達式中各類運算符的優先級。優先級高的先運算,優先級低的後運算,此外還能夠使用括號「()」改變表達式的運算次序。

Java語言規定的運算符優先級如表3-3所示,表中排在上面的運算符有較高的優先級,同一行中的運算符的優先級相同。若是在表達式中有括號(表達式中只使用圓括號),又有函數,則優先計算括號中的內容,再進行函數運算。

表3-3  Java語言的運算符優先級

 

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

程序控制邏輯

 

控制邏輯用來控制程序中語句的執行順序。Java程序設計語言提供瞭如下幾種流程控制語句:選擇控制、循環控制、跳轉控制和異常處理。這裏咱們主要簡單介紹選擇控制和循環控制語句。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

選擇控制語句

 

包括if-else和 switch兩種形式。

(1)if-else 結構

If-else 結構的控制邏輯如圖3-8。語句的執行過程是:首先計算布爾表達式,若布爾表達式的值爲true,則程序執行語句1,不然執行語句2,而後執行if語句的後續語句。

圖3-8 if-else語句的流程圖

if-else 結構選擇控制語句其格式爲:

if (條件) {

      語句1;

}else{

      語句2;

}

【專家提示】在使用if-else 結構選擇控制語句應該注意:

else子句不能做爲語句單獨使用,它必須是if語句的一部分,與if配對使用。

語句一、語句2後必定要有「;」號。

語句1和語句2能夠是複合語句。

if-else 結構選擇控制語句能夠嵌套使用,這時要注意花括號「{}」匹配問題,當分支較多時建議採用switch 結構,這樣程序代碼可讀性更強一些。

(2)switch 結構

switch語句根據表達式的結果來執行多個可能操做中的一個,其控制邏輯如圖3-9所示。語句的執行過程是:switch語句將表達式的值依次與每一個case子句中的常量值相比較。若是匹配成功,則執行該case子句中常量值後的語句;若是沒有找到,則執行default語句,直到遇到break語句爲止退出switch語句。

    

圖3-9 switch語句流程圖

switch語句的語法形式以下:

switch (表達式){

case 常量1: 

語句1

[break;]

case 常量2: 

語句2

[break;]

case 常量n: 

語句n

[break;]

[default: ]   

缺省處理語句

[break;]

}

switch語句中的每一個「case 常量n:」稱爲一個case子句,表明一個case分支的入口。

switch語句中表達式必須爲byte,short,int或char類型,常量值必須是與表達式類型兼容的特定的一個常量,不容許有重複的case值。

經過if-else語句能夠實現switch語句全部的功能。但一般使用switch語句更簡練,且可讀性強,程序的執行效率也高。

if-else語句能夠基於一個範圍內的值或一個條件來進行不一樣的操做,但switch語句中的每一個case子句都必須對應一個單值。

【例3-7】選擇控制應用示例

3-7.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<html>

<head><title>

選擇控制應用示例

</title></head>

<body>

2003年6月有多少天?

<%

int month = 6;

int year = 2003;

int numDays = 0;

switch (month) {

 case 1:

 case 3:

 case 5:

 case 7:

 case 8:

 case 10:

 case 12:

 numDays = 31;

 break;

 case 4:

 case 6:

 case 9:

 case 11:

 numDays = 30;

 break;

 case 2:

 if((year%4 ==0)&&(year%100 ==0)||(year%400==0))

 numDays = 29;

 else

 numDays = 28;

 break;

 }

 out.print("<br/>");

 out.println("答:2003年6月有 "+ numDays+"天。");

 %>

</body>

</html>

上述程序代碼經過switch語句根據給的年、月,輸出該月的天數。其程序運行結果如圖3-10所示。

圖3-10  選擇控制應用示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

循環控制語句

 

循環語句的做用是反覆執行同一段代碼直到知足結束條件。許多問題中須要用到循環控制。Java循環語句有while、do-while和for三種。

(1)while 循環 

while語句形式以下:

while (布爾表達式) <語句>;

其中:

while是while語句的關鍵字;布爾表達式是循環條件;語句爲循環體,當循環體爲多個語句時構成複合語句。

while語句執行的過程爲:首先判斷布爾表達式的值,當布爾表達式的值爲true,則執行循環體,而後再判斷條件,直到布爾表達式的值爲false,中止執行語句。

【專家提示】使用while語句應注意如下兩點:

(1)該語句是先判斷後執行,若一開始條件就不成立,則不執行循環體。

(2)在循環體內必定要有改變條件的語句,不然是死循環。

while語句的流程圖如圖3-11所示。

圖3-11  while語句的流程圖

(2)do-while循環 

Java還提供了另外一個與while語句相似的語句——do-while語句。do-while語句的語法形式以下:

do

語句;

while(布爾表達式);

do-while語句執行的過程爲:先執行一次循環體中的語句,而後測試布爾表達式的值,若是布爾表達式的值爲true,則繼續執行循環體。do-while語句將不斷地測試布爾表達式的值並執行循環體中的內容,直到布爾表達式的值爲false爲止。do-while語句的流程圖如圖3-12所示。

圖3-12  do-while 語句的流程圖

do-while語句和while語句的不一樣之處:do-while語句老是先進入循環,而後檢測條件,再決定是否繼續循環,而while語句是先測試條件,再斷定是否進入循環。因此,用do-while語句時,循環體至少執行一次。

(3)for 循環

圖3-13   for語句的流程圖

for語句是循環的另外一種表示形式。for語句的語法形式爲:

for(變量初始化表達式1;條件表達式2;對變量的值做遞增或遞減處理) {

語句組; 

}

for是for語句的關鍵字,語句組爲for語句的循環體。

for語句中循環控制變量必須是有序類型,經常使用的有整型、字符型、布爾型。循環控制變量初值和終值一般是與控制變量類型相一致的一個常量,也能夠是表達式。循環次數由初值和終值決定。

for語句的執行過程如圖3-13:

(1)按表達式1將初值賦給循環控制變量。

(2)按表達式2判斷循環是否成立,即判斷控制變量的值是否越過終值(未越過終值爲條件成立,越過終值爲條件不成立),若條件不成立,則轉步驟(6)。

(3)若條件成立,則執行循環體。

(4)按表達式3修改控制變量。對於遞增型爲原控制變量值的後續;對於遞減型爲原控制變量值的前導。

(5)返回步驟(2)。

(6)結束循環。

【例3-8】循環應用綜合示例

3-8.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<html>

<head><title>循環應用示例

</title></head>

<body>

<%

int sum,i;

i = 1;

sum = 0;

while (i<=2000) {

if(i%2!=0)

sum+=i;

 i++;

}

out.println("用while循環求2000內的奇數和:" +sum);

out.print("<br/>"); 

i = 1;

sum = 0;

do{

sum+=i;

i+=2;

}while (i<=2000);

out.println("用do-while循環求2000內的奇數和:"+sum);

out.print("<br/>"); 

for(sum=0,i=1;i<=2000;i+=2) 

sum+=i;

out.println("用for循環求2000內的奇數和:"+sum);

out.print("<br/>"); 

%>

</body>

</html>

上述程序代碼用while、do-while和for語句分別求2000內的奇數的和。從代碼上看while和do-while語句查很少,只是do-while至少會執行一次,而while卻不必定。for語句使用簡單明瞭,使用靈活,常常被程序員所使用。其程序運行結果如圖3-14所示。

圖3-14 選擇控制應用示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

 

類是複雜的數據類型,是組成面向對象Java程序語言的核心要素。它描述了一類對象的屬性和行爲。進行Java程序設計時咱們既能夠使用Java系統類庫中提供的許多標準的類,也能夠本身根據應用須要定義知足應用需求的類。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

類的基本概念

 

類是一種複雜的數據類型,它描述了一類對象的屬性和行爲。類是對象的抽象,對象是類的實例化,要進行面向對象Java程序設計,先要定義類,而後建立對象,再使用對象。來看下面的代碼示例。

Class MyDateClass {

private int day;

private int month;

private int year;

public MyDateClass(){

day = 1;

month = 1;

year = 1900;

}

public MyDateClass(int d,int m,int y){

day = d;

month = m;

year = y;

}

public void display(){

System.out.println(day + "-" + month + "-" + year);

}

public static void main(String args[]){

MyClass m1 = new MyDateClass();

MyClass m2 = new MyDateClass(25,12,2005);

m1.display();

System.out.println("m2 是 "+m2.year+"年");

m2.display();

}

}

類的定義要使用關鍵詞class,類體包括數據和操做兩部分。數據是類的成員變量,表示對象的屬性;操做是類的成員方法,表示對象的行爲。在上面的例子中定義了一個MyDateClass類,有day、month、year3個數據,以及MyDateClass()和display()方法,在main(String args[])方法中經過new聲明和建立了兩個實例對象m一、m2。在Java中全部的對象的內存空間都是動態分配的,因此要用new運算符聲明和建立它們。對象的使用經過運算符「.」能夠實現對象的成員變量和成員方法的使用,m1.display()和m2.display()是對成員方法的調用,而m2.year是對成員變量的訪問。

從MyDateClass()、display()和main(String args[])方法,能夠看出類的方法代碼編寫格式爲:

返回的數據類型 方法名 ([參數列表]){

//方法體,實現對象的行爲的代碼

}

其中MyDateClass()和MyDateClass(int d,int m,int y)兩個方法與類MyDateClass同名,稱之爲構造函數。構造函數名稱與類名稱相同,構造函數沒有返回類型,其任務是在建立對象時初始化其內部狀態。若是類中沒有定義構造函數,則表示默認有一個無參數構造方法。MyDateClass()和MyDateClass(int d,int m,int y)兩個方法同名,只是參數列表中參數個數和類型不一樣,這就是所謂的方法重載。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

this

 

this表明了當前對象的一個引用,當一個方法須要引用調用它的方法時,能夠經過this順利的訪問對象、修改對象的數據成員和調用對象的方法。MyDateClass的構造函數能夠修改以下:

public MyDateClass(){

this.day = 1;

this.month = 1;

this.year = 1900;

}

public MyDateClass(int d,int m,int y){

this.day = d;

this.month = m;

this.year = y;

}

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

類的繼承

 

被繼承的類稱爲父類,繼承父類的類稱爲子類。執行繼承時,子類將得到父類的屬性,並具備自身特有的屬性。extends關鍵字用於繼承類,聲明一個繼承父類的類的一般形式以下:

class 子類名 extends 父類名 {

//子類程序代碼

若是類的聲明中在沒有extends,則默認父類爲Object。Java語言中子類只能有一個父類,具備單繼承性,要用到多繼承時能夠經過後文中講解的接口來實現。

class A{

int value = 3;

int getValue(){return value;}

}

class B extends A{

int value = 6;

int getValue() {return value;}

int getValue2(){return super.value;}

int getValue3(){return getValue();}

int getValue4(){return super.getValue();}

}

A類是父類,B類是子類,B類繼承了A類的數據和方法,同時也增長了一個數據和四個方法。在B類中還用到了關鍵字super。super指這個對象的父類,關鍵字super可用於訪問父類中定義的屬性,調用父類中定義的成員方法,在子類構造方法中調用父類的構造方法。以上程序表示使用父類的構造方法生成實例,super必須是子類構造方法的第一條語句。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

抽象類和抽象方法

 

用abstract關鍵字來修飾一個類時,該類叫作抽象類;抽象類必須被繼承。抽象類不能被直接實例化,它只能做爲其它類的超類,這一點與最終類(final類)正好相反。

用abstract來修飾一個方法時,該方法叫作抽象方法。抽象方法只有聲明,不能有實現。抽象方法必須被重寫。定義了抽象方法的類必須是抽象類。下面是一個抽象類的例子。

abstract class Shape{

    abstract float area( );

}

class Circle extends Shape{

    public float r; 

    Circle(float r){

    this.r = r;      //this指「這個對象的」

    }

    public float area( ){

    return 3.14*r*r;

    }

}

抽象類Shape中聲明瞭一個抽象方法area( ),該方法在子類中實現。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

Java的標準類庫

 

Java提供了豐富的標準類來幫助程序員更方便快捷地編寫程序,這些標準類組成了類包,主要有:

(1)java.lang

本類包中的類構成Java語言核心的類,任何java程序都將自動引入這個包。其中的類包括:

Object類:java中最原始、最重要的類,每一個java類都是它的子類,它實現了每一個類都必須具備的基本方法。

基本數據類型的包裝類:Boolean、Character、Number、Double、Float、Integer、Long。

String類:字符串類。

Math類:數學函數的集合。

執行線程:Thread類、ThreadGroup類、Runable接口。

異常和錯誤:Exception類、Error類、Throwable接口。

運行環境相關類:還能夠經過Runtime類和System類訪問外部系統環境。System類的兩個經常使用功能就是訪問標準輸入/輸出流和錯誤流、退出程序。

其餘類:接口Cloneable、運行時的類等。

(2)java.applet

java.applet類包提供了Applet的運行機制以及一些編寫Applet很是有用的方法。

(3)java.awt

此本類包是各類窗口環境的統一界面AWT(Abstract Windows Toolkit,即抽象窗口工具包),其中的類使得程序員建立諸如窗口、菜單、滾動條、文本區、按鈕以及複選框等圖形用戶界面(GUI)的元素變得很是容易。

(4)java.awt.image

該類包中的類可以以獨立於設備的方式加載並過濾位圖圖象。

(5)java.awt.peer

java.awt.peer是所有awt組件的對等對象接口的集合法,awt使用這些方法來實現GUI,而沒必要關心是何種機器或操做系統。

(6)java.io

Java的輸入/輸出模式是徹底創建在流的基礎之上的。流是一種字節從一個地方到另外一個地方的單向流動,能夠把流附加於文件、管道和通訊鏈路等。java.io類包中定義的許多種流類經過繼承的方式進行組織,其中也包括一些用來訪問本地文件系統上的文件的流類。

(7)java.net

java.net類包用來完成與網絡相關的功能:URL、WWW鏈接以及更爲通用的Socket網絡通訊。

(8)java.util

java.util類包包含了一些實用類和有用的數據結構,如字典(Dictionary)、散列表(Hashtable)、堆棧(Stack)、向量(Vectro)以及枚舉類(Enumeration)等。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

包裝類

 

所謂包裝類,就是能夠直接將簡單類型的變量表示爲一個類。Java共有六個包裝類,分別是Boolean、Character、Integer、Long、Float和Double,從字面上咱們就能夠看出它們分別對應於簡單數據類型中的 boolean、char、int、long、float和double。

簡單類型的變量轉換爲相應的包裝類,能夠利用包裝類的構造函數。即:

Boolean(boolean value)、Character(char value)、Integer(int value)、Long(long value)、Float(float value)、Double(double value)

而在各個包裝類中,總有形爲××Value()的方法,來獲得其對應的簡單類型數據。利用這種方法,也能夠實現不一樣數值型變量間的轉換,例如,對於一個雙精度實型類,intValue()能夠獲得其對應的整型變量,而doubleValue()能夠獲得其對應的雙精度實型變量。

在進行簡單數據類型之間的轉換(自動轉換或強制轉換)時,老是能夠利用包裝類進行中間過渡。通常狀況下,首先聲明一個變量,而後生成一個對應的包裝類,就能夠利用包裝類的各類方法進行類型轉換了。例如,當但願把float型轉換爲double型時:

float f1=100.00f;

Float F1=new Float(f1);

double d1=F1.doubleValue();

【例3-9】包裝類示例

3-9.jsp

<%@ page contentType="text/html;charset=gb2312"%><!--JSP指令標籤-->

<%@ page import="java.util.*"%>                 <!--JSP指令標籤-->

<html><!--HTML標記符-->

<body>

<%//如下爲Java程序片

  boolean booleanTemp=true;

  Boolean BooleanTemp=new Boolean(false);

  byte byteTemp=80;

  Byte ByteTemp=new Byte(byteTemp);

  char charTemp='c';

  Character CharacterTemp=new Character(charTemp);

  int intTemp=234;

  Integer IntegerTemp=new Integer(intTemp);

  short shortTemp=235;

  Short ShortTemp=new Short(shortTemp);

  long longTemp=1234567;

  Long LongTemp=new Long(longTemp);

  float floatTemp=1.234F;

  Float FloatTemp=new Float(floatTemp);

  double doubleTemp=1.23E-8;

  Double DoubleTemp=new Double(doubleTemp);

  out.println("布爾型包裝對象BooleanTemp值爲:"+BooleanTemp.booleanValue()+"<br>");

  out.println("字符型包裝對象CharacterTemp值爲:"+CharacterTemp.charValue()+"<br>");

  out.println("整型變包裝對象IntegerTemp值爲:"+IntegerTemp.intValue()+"<br>");

  out.println("短整型包裝對象ShortTemp值爲:"+ShortTemp.shortValue()+"<br>");

  out.println("字節型包裝對象ByteTemp值爲:"+ByteTemp.byteValue()+"<br>");

  out.println("長整型包裝對象LongTemp值爲:"+LongTemp.longValue()+"<br>");

  out.println("單精度型包裝對象FloatTemp值爲:"+FloatTemp.floatValue()+"<br>");

  out.println("雙精度型包裝對象doubleTemp值爲:"+doubleTemp+"<br>");

%>

</body><!--HTML標記符-->

</html>

上述代碼主要應用了包裝類進行數據轉換,其運行的結果如圖3-15所示。

圖3-15  包裝類應用示例

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

字符串處理

 

字符串是字符的序列,它是組織字符的基本數據結構。在Java中,字符串被看成對象來處理。程序中須要用到的字符串能夠分爲兩大類,一類是建立以後不會再作修改和變更的字符串常量String類;另外一類是建立以後容許再作更改和變化的字符串變量StringBuffer類。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

String類字符串

 

String類用來表示字符串常量,用它建立的每一個對象都是字符常量,一經創建就不能修改。建立String的一個對象並進行初始化,須要調用類String的構造方法,主要有如下創造方法:

String(String s):經過String對象或字符串常量傳遞給構造方法。

String(char value[]):將整個字符數組賦給String構造方法。

String(char value[],int offset,int count):將字符數組一部分賦給String構造方法,offset 爲起始下標,count爲字符數組從offset開始的字符個數。

String類的方法比較多,主要有如下幾種:

(1)求字符串長度

public int length( ):返回字符串長度。

(2)字符串比較

public boolean equals(Object anObject):比較兩個字符串對象,相等返回true,反之,返回false。

public int compareTo(String s):比較兩個字符串的字典順序,相等返回0,s大於當前串返回一個負值,s小於當前串返回一個正值。

public boolean startsWith(String prefix):從當前字符串的起始位置開始尋找字符串prefix。看當前字符串是否以prefix開頭,如發現匹配,返回true,不然,返回false。

public boolean endsWith(String suffix):如當前字符串的結尾子串與suffix匹配,返回true,不然,返回false。

boolean regionMatches(int toffset,String other,int ooffset,int len):從當前字符串位置toffset開始尋找字符串other中起始位置爲ooffset、長度爲len的子串。如發現匹配,返回true,不然,返回false。

(3)字符串的檢索和求子串

public char  charAt(int index):返回當前字符串位置index處的字符。

public int indexOf(String str):在當前字符串中尋找與str匹配的子串,返回首次匹配的起始下標值,無匹配返回-1。

public String substring(int beginIndex,int endIndex):在當前字符串中,求從起始位置beginIndex到結束位置endIndex的子串。

【例3-10】String類字符串的檢索和求子串應用示例

3-10.jsp

<%@ page contentType="text/html;  charset=gb2312" %>

<html>

<head>

<title>String類字符串的檢索和子串應用示例</title>

</head>

<body>

<%

String str="I like JSP programming!";

int il=str.indexOf('J');

String s1=str.substring(il);

String s2=str.substring(il,il+4);

int i2=str.lastIndexOf('J');

String s3=str.substring(i2-5);

out.println("s1="+s1);

out.print("<br/>");

out.println("s2="+s2);

out.print("<br/>");

out.println("s3="+s3);

%>

</body>

</html>

上述程序代碼應用了String類的檢索方法和求子串的方法,修改後的字符串存儲在新的String類字符串對象中。該程序運行結果如圖3-17所示。

圖3-17  String類字符串的檢索和求子串應用示例運行結果

(4)字符串的修改

public String toLowerCase():將當前字符串中的字符所有轉換爲小寫形式。

public String toUpperCase():將當前字符串中的字符所有轉換爲大寫形式。

public String replace(char oldChar,char newChar):將字符newChar替換當前字符串中全部的字符oldChar,並返回替換後的新字符串。

public String concat(String str):將當前字符串與str鏈接,返回鏈接後的字符串。

(5)字符串類與其餘類型的轉換

public Static String valueOf(type variable) 把variable轉換爲字符串。

public String toString():把一個對象轉化爲String類型。

【例3-11】String類字符串的綜合應用示例

3-11.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<html>

<head>

<title>

String類字符串的綜合應用示例

</title>

</head>

<body>

<%

String s1="Hello Java!";

String s2="GOOD!";

out.println("字符串s1爲:"+s1);

out.print("<br/>");

out.println("字符串s1的長度爲:"+s1.length());

out.print("<br/>");

out.println("字符串s1的大寫形式爲:"+s1.toUpperCase());

out.print("<br/>");

out.println("字符串s2的小寫形式爲:"+s2.toLowerCase());

out.print("<br/>");

for(int i=0; i<s1.length(); i++){

out.println("s1中的第"+ i +"個字符是:"+s1.charAt(i));

out.print("<br/>");

}

out.println("s1+s2="+s1+s2);

out.print("<br/>");

if(s1.compareTo(s2)= =0)

out.println("字符串s1與s2相等");

else

out.println("字符串s1與s2不相等");

out.print("<br/>");

if(s1.indexOf(s2)!=-1){

out.println("字符串s2是s1的子串");

out.print("<br/>");

out.println("字符串s2在s1中的位置是:"+s1.indexOf(s2));

}

else

out.println("字符串s2不是s1的子串");

out.print("<br/>");

out.println("通過上述操做:");

out.print("<br/>");

out.println("字符串s1仍然爲:"+s1);

out.print("<br/>");

out.println("字符串s2仍然爲:"+s2);

%>

</body>

</html>

上述程序代碼使用String類的修改方法對原有的字符串進行修改,修改後的字符串存儲在新的String類字符串對象中,原有的字符串對象不變。其程序運行結果圖3-18所示。

圖3-18 String類字符串的綜合應用示例

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

StringBuffer類字符串

 

String類的實例用於表示不能改變的靜態字符串,StringBuffer類的實例卻用來表明動態可變的字符串。StringBuffer類還能夠用於建立String類,StringBuffer一旦創建,便可用toString()方法將其轉換爲String類。

StringBuffer類的構造函數有如下的形式:

(1)StringBuffer():建立默認的空字符串對象,緩衝區大小爲16個字符。

(2)StringBuffer(int len):創建緩衝區大小爲len的字符串對象。

(3)StringBuffer(String str):建立一個初始化爲str的字符串對象。

StringBuffer類的主要方法有以下的幾類:

(1)分配/獲取字符串的長度

void setLength(int newLength):指定字符串的長度。

int length():返回緩衝區的字符個數,即字符串的長度。

(2)分配/獲取字符串的容量

void ensureCapacity(int minCapacity):分配字符緩衝區的大小,分配的字符緩衝區的容量至少爲指定的值minCapacity。若是當前的緩衝區容量小於minCapacity,則應該分配較大的緩衝區。

int capacity():返回緩衝區剩餘空間。

【專家提示】長度length和容量capacity是兩個不一樣的概念,長度是指StringBuffer類對象中包含字符的個數,而容量是隻緩衝區的大小。

(3)字符串的檢索和子串

void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin):將StringBuffer對象字符串中的字符複製到目標數組中去。

public String substring(int beginIndex,int endIndex):當前StringBuffer類字符串中,求從起始位置beginIndex到結束位置endIndex的子串。

(4)字符串的修改

public synchronized StringBuffer append(type variable):把variable轉換爲字符串,而後與當前字符串鏈接。

StringBuffer insert(int index,String str):將一個字符串str從當前字符串的index位置開始插入到當前StringBuffer類字符串對象中。

StringBuffer delete(int starts,int end):當前StringBuffer類字符串從starts開始到end-1位置刪除子字符串,並返回當前StringBuffer類字符串。

StringBuffer deleteCharAt(int index):刪除當前StringBuffer類字符串index處的字符。

StringBuffer reverse():對StringBuffer類字符串進行翻轉。

StringBuffer replace(int starts,int end,String str):將字符串str替代當前緩衝字符串的starts開始到end-1位置的子字符串。

void setCharAt(int index,char ch)設置指定位置index處的字符爲ch。

(5)字符串類型轉換

toString():把StringBuffer轉換爲字符串String。

【例3-12】Stringbuffer類字符串的綜合應用示例

3-12.jsp

<%@ page contentType="text/html; charset=gb2312" %>

<html>

<head>

<title>

Stringbuffer類字符串的綜合應用示例

</title>

</head>

<body>

<%

StringBuffer s=new StringBuffer("Hello");

out.println("s:"+s);

out.print("<br/>");

out.println("字符串s的長度:" +s.length());

out.print("<br/>");

out.println("字符串s的容量:"+ s.capacity());

out.print("<br/>");

s.append("Stringbuffer");

out.println("向字符串s中加入了字符串Stringbuffer:"+s);

out.print("<br/>");

out.println("字符串s的位置4-5的子串:"+s.substring(3,5));

out.print("<br/>");

out.println("字符串s的第6個字符:"+s.charAt(5));

out.print("<br/>");

out.println("將字符串的位置6-15的子串替換爲java:"+s.replace(5, 16, "java"));

%>

<html>

<body>

上述程序代碼首先建立初始化了的StringBuffer對象s,而後顯示這個字符串,求其容量和長度,而後在字符串s後追加一個字符串「lo」,並用一個新的字符串替代s的子字符串。其運行結果如圖3-19所示。

圖3-19 Stringbuffer類字符串的綜合應用示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

日期型數據處理

 

在Java中日期型數據處理用Date類,即日期類。Date類構造函數的經常使用的有四種形式:

(1)Date()

(2)Date(int year, int month, int date):以int型表示年、月、日。

(3)Date(int year, int month, int date, int hrs, int min):以int型表示年、月、日、時、分。

(4)Date(int year, int month, int date, int hrs, int min, int sec):以int型表示年、月、日、時、分、秒。

在長整型和Date類之間有一個對應關係,就是將一個時間表示爲距離格林尼治標準時間1970年1月1日0時0分0秒的毫秒數。對於這種對應關係,Date類也有其相應的構造函數:Date(long date)。

獲取Date類中的年、月、日、時、分、秒以及星期讀者能夠使用Date類的getYear()、getMonth()、getDate()、getHours()、getMinutes()、getSeconds()、getDay()方法。

而Date類的getTime()方法能夠獲得前文中所說的一個時間對應的長整型數,與包裝類同樣。此外,Date類也有一個toString()方法能夠將其轉換爲String類。

【例3-13】日期型數據處理示例

3-13.jsp

<%@ page import="java.util.*" %>

<%@ page contentType="text/html;  charset=gb2312" %>

<HTML>

<head><title>日期型數據處理示例</title></head>

<BODY>

你好,今天是

<%

Date today=new Date();

%>

<%=today.getDate()%>號,

星期<%=today.getDay()%>

<h1>如今是北京時間: <%=today.toString() %> 

</h1>

</BODY>

</HTML>

上述程序代碼建立一個Date類的對象,用getDate()方法獲取對象的時間,並getDay()求當天的日期。其程序運行結果如圖3-20所示。

圖3-20 日期型數據處理示例運行結果

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

接口

 

接口是面向對象的程序設計中的一個重要概念,利用接口能夠使設計與實現相分離,使用接口的用戶程序不受不一樣接口實現的影響,不受接口實現改變的影響。接口和類不一樣,一個接口能夠是一個或多個其餘接口的直接繼承。同時,一個類也能夠實現一個或多個接口,但在這個類中必須實現接口中的全部抽象方法。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

接口的聲明

 

[修飾符] interface  接口名稱{

    [public] [static] [final] 變量名=初值; //靜態常量

    [public] [abstract] [native]返回值 方法名([參數表])throws [異常列表] //方法

}

因爲接口中聲明的方法是抽象、公有的,常量都是靜態、公有的,因此修飾符能夠省略。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

接口的實現

 

在類的聲明中使用implements關鍵字來實現接口,一個類能夠同時實現多個接口,各接口間用「,」隔開。

class classname implements interfacename{

   //重寫接口中的方法;

}

(1)若實現接口的類不是抽象類,則必須實現接口的全部方法,即爲全部的抽象方法聲明方法體。

(2)一個類在實現某接口的抽象方法時,必須使用徹底相同的方法名和參數列表。

(3)接口的抽象方法的訪問控制符已指定爲public,因此類在實現時,必須顯式的使用public修飾符,不然被警告縮小了接口中聲明的方法的訪問控制範圍。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

JSP指令

 

「<%@」和「%>」之間爲JSP指令,經常使用下列三種指令:

<%@ page import="java.util.*" language="java" session="true" %>

<%@include file="包含文件的URL"%>

<%@taglib uri="URIToTagLibrary" prefix="tagPrefix"%>

其中:JSP指令的關鍵詞page、include、taglib賦予指令不一樣類型的語義。每一個JSP指令的關鍵詞後面是「KEY=VALUE」形式的值對,其中KEY是屬性名,VALUE是字符串類型的屬性值。這裏咱們介紹最爲經常使用的page和nclude指令,taglib指令在後面的章節還會進行講解。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

page指令

 

page指令用於定義JSP頁面中的全局屬性。<%@page%>指令做用於整個JSP頁面,包括被靜態包含的文件,可是<%@page%>指令不能做用於被動態包含的文件。page指令語法格式以下:

<%page [language="java"] [extends="package.class"] 

[import="{package.class │package.*}, … …"] [session="true │false"]

[buffer="none│8kb│sizekb"] [isThreadSafe="true │false"]

[info="text"] [errorPage="relativeURL"]

[contentType="mimeType[;charset=characterSet]"│"text/html;charset=ISO-8859-1"]

[isErrouPage="true│false"]

%>

在一個頁面中能夠使用多個<%@page%>指令,除import屬性之外的其它屬性只能設置一次。頁面中的import屬性和Java中的import語句相似,能夠屢次設置。JSP頁面指令是一種功能比較複雜的指令,這主要與它所要支持的繁多的屬性有關。下面對page指令中能夠包含的各個屬性進行詳細說明。

(1)language

language屬性告訴服務器在文件中將採用哪一種編程語言做爲腳本語言,默認爲Java。

(2)extends

extends 屬性定義了由JSP 頁面產生的servlet 的父類。通常來講,這個屬性不會用到,只有須要實現一些特殊功能時纔會用到。

(3)import

import屬性用來聲明輸入引用的Java包(package)或(class) 。這是惟一能夠在同一個JSP頁面中重複出現的屬性設置。

import屬性的值是一系列用逗號分開的列表,指明想要引入的包和類。例如:

<%@ page import="java.util.*" %>

能夠在程序中引入多個須要的包和類,包和類之間用逗號分隔。例如:

<%@ page import="java.util.*,java.io.*" %>

也能夠將須要引入的多個包和類寫在多個page指令中。例如,上面的語句等價於:

<%@ page import="java.util.*" %>

<%@ page import=" java.io.*" %>

當使用import引入了包和類後,就能夠使用與這些包和類相關的方法和對象了。

【專家提示】java.lang.*、javax.servlet.*、javax.servlet.jsp.*和javax.servlet.http.*包已經做爲缺省值被JSP引入,因此不須要在網頁中再次引入。

(4)session

session 屬性表示當前頁面是否加入會話期間的管理,其缺省值爲true, 代表內建對象session存在(若是沒有session對象,則會新建一個),由session對象來管理會話。若是設session屬性值爲false,則內建對象session不存在,這樣頁面中任何使用到session 的語句都會產生編譯錯誤。

(5)buffer

buffer決定輸出流(out 對象)是否須要緩衝區,缺省值是8KB, 也能夠設置爲none(沒有緩衝區)或所指定大小的緩衝區,例如: 

<%@page buffer ="12kb" %>

上面的語句指定輸出流緩衝區爲12KB。

buffer 屬性一般與autoFlush屬性配合使用。 

(6)autoFlush

autoFlush屬性用於指定是否自動刷新輸出緩衝,若是設成true,則當輸出緩衝區滿的時候,自動刷新緩衝區而不是拋出一個異常,缺省值爲true。

【專家提示】同時設置autoFlush爲false和buffer爲none是不合法的,編譯時將會出錯。 

(7)isThreadSafe

isThreadSafe屬性指示JSP 引擎,網頁在處理對象存取時是否要引入ThreadSafe( 線程保護)機制,缺省值爲true,此時若是多個客戶向JSP 引擎發送請求,就能夠同時被處理。這時JSP 程序員要處理同步時的共享狀態,以保證同步確實是安全的。若是isThreadSafe 被設成false,則採用單線程模式控制客戶端訪問該頁面。 

(8)info

info屬性用於設置頁面的說明信息文字,能夠經過頁面的Servlet.getServletInfo() 方法訪問該信息。例如: 

<%@page info="JSP 教程" %>

(9)ErrorPage

ErrorPage 屬性用於指示一個JSP 文件的相對路徑,以便在頁面出錯時,轉到這個JSP 文件來進行處理。相應的,須要將這個JSP 文件的isErrorPage 屬性設爲true。

當ErrorPage 屬性被設置後,JSP 網頁中的異常仍然會產生,只不過此時捕捉到的異常將不禁當前網頁進行處理,而是由 ErrorPage 屬性所指定的網頁去進行處理。 

(10)isErrorPage

isErrorPage 屬性指示一個頁面是否爲錯誤處理頁面。設置爲true 時,在這個JSP 頁面中的內建對象exception 將被定義,其值將被設定爲呼叫此頁面的JSP 頁面的錯誤對象,以處理該頁面所產生的錯誤。isErrorPage 屬性缺省值爲false,此時將不能使用內建對象exception來處理異常,不然將產生編譯錯誤。 

(11)contentType

contentType屬性用於設置JSP 文件和最終文件的MIME 類型和字符集的類型。這一項必須在文件的頂部。可用的MIME類型有text/plain、text/html、text/html 和image/gif、image/jpeg等。contentType屬性缺省值爲「text/html;charset = ISO8859_1」,爲了讓JSP頁面能夠正常地顯示中文須要設置爲「text/html;charset = GBK」或「text/html;charset =gb2312」。

 
 
 
 

第 3 章:JSP語法做者:鄧子云赫斌等    來源:希賽網    2014年02月28日

 

include指令

 

include指令指定在JSP文件中包含的一個靜態的文件,即在JSP文件被編譯時須要插入的文本或代碼。include指令語法格式以下:

<%@include file="relativeURL"% >

若是這個路徑以「/」開頭,那麼這個路徑主要參照JSP應用的上下文關係路徑,若是路徑是以文件名或目錄名開頭,那麼這個路徑就是正在使用JSP文件的當前路徑。

<%@include %>指令將會在JSP編譯時輸入一個包含文本或代碼的文件,當使用 <%@include %> 指令時,包含的過程是靜態的。靜態的包含就是指這個被包含的文件將會被導入到JSP文件中去,這個被包含的文件能夠是JSP文件、HTML 文件、文本文件。若是被包含的是JSP文件,這個被包含JSP的文件的代碼將會被執行。

【專家提示】包含文件能夠是html文件、jsp文件、文本文件、或者只是一段Java代碼,可是注意在這個包含文件中不能使用<html>、</html>、<body>、</body>標誌,由於這將會影響在原 JSP文件中一樣的標誌,這樣作有時會致使錯誤。

在JSP頁面中,包含指令最多見的用途就要數網頁導航條了,因爲一個網站的主導航條欄每每是統一的,因此主導航欄通常被寫成一張單獨的網頁,而後經過框架結構與其餘網頁拼接。因爲框架可能帶來的諸多的不便。如用戶難以對框架內網頁作書籤等,包含指令就成了實現導航欄的最佳機制。

【例3-14】include指令應用示例

3-14.jsp

<%@page contentType="text/html;charset=GB2312"%>

<html>

<head>

<title>JSP指令示例</title>

</head>

<body>

<h1>**金字塔**</h1>

<%@ include file="Ta.jsp" %>

</body>

</html>

Ta.jsp源程序以下,功能是輸出一個數字構成的金字塔。

<% out.print("<pre>");

int i=7,j,k;

for(j=1;j<i;j++){ 

for(k=0;k<2*(i-j-1);k++)

out.print(" ");

for(k=0;k<j;k++)

out.print(j+"   ");

%>

<P></P>

<% 

}

out.print("</pre>");

%>

這裏將兩個程序放在同一目錄下面,3-14.jsp包含Ta.jsp,實現了靜態文件的插入。include指令應用示例運行結果如圖3-21所示。

圖3-21 include指令應用示例

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

隱含對象概述

 

第4章  隱含對象解析

【本章專家知識導學】

JSP提供了一些隱含對象,以方便在JSP頁面中快速方便地編寫程序,這些對象沒必要再用類來聲明創建類的實例,能夠直接使用。本章旨在引導讀者學習運用request、response、session、application、pageContext、out、page和pageContext等這些隱含的對象來進行JSP編程。

4.1  隱含對象概述

JSP隱含對象是Web容器加載的一組類的實例,它不一樣於通常的Java類的實例那樣要用「new」關鍵字去獲取實例,而是能夠直接在JSP頁面使用的對象。

JSP提供的9個隱含對象分爲4個主要類別,如圖7-1所示:

與「I/O」(input/output,輸入/輸出)有關的隱含對象:用於控制頁面的輸入和輸出,包含request、response、out。

JSP執行時,提供有關上下文(Context)有關的隱含對象:用於控制JSP頁面之間的信息傳遞,包含session、application、pageContext。

與Servlet有關的隱含對象:提供有關頁面環境的信息,包含page、config。

與Error有關的隱含對象:處理頁面中的錯誤的exception。

圖 7-1 JSP隱含對象

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

與I/O有關的隱含對象

 

本節中將介紹和I/O有關的隱含對象——request、response和out對象。request對象表示客戶端請求的內容;response對象表示響應客戶端的結果;而out對象負責把數據的結果顯示到客戶端的瀏覽器。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

request對象:取得請求參數值

 

request對象包含全部請求信息,如請求的來源、請求頭信息、cookies和請求相關的參數值等等。在JSP網頁中,request對象是實現了javax.servlet.http.HttpServletRequest接口的實例。

request對象主要用於取得客戶在表單中提交的數據信息。request對象經常使用的取得客戶表單中提交的數據信息的方法有:

String getParameter(String name):根據頁面表單域的名稱取得請求頁面提交到服務端的數據。例如,在requestDemo.jsp頁面中有一個輸入用戶名稱的文本框,它的名稱是「name」,頁面提交請求到頁面requestDemo1.jsp,那麼在requestDemo1.jsp中能夠利用語句request.getParameter("name")來獲取用戶輸入的用戶名。

String[] getParameterValues(String name):獲取頁面請求中一個表單域對應多個值的用戶請求數據。例如,在requestDemo.jsp頁面中有一個興趣愛好選擇的複選框,用戶能夠選擇多項內容,複選框的名稱都是「interest」,它提交請求到頁面requestDemo1.jsp,那麼在requestDemo1.jsp中能夠利用語句request.getParameterValues("interest")來獲取用戶選擇的多個興趣愛好。

public void setCharacterEncoding(java.lang.String env):設置請求對象的字符集編碼,此方法必須在取得request對象參數的值前調用。

【例4-1】取得請求中的參數值 

requestDemo.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>

請求參數輸入頁面

</title>

</head>

<body bgcolor="#ffffff">

<h1>

請求參數輸入頁面

</h1>

<form action="requestDemo1.jsp" method="POST">

  <table border="1">

    <tr>

      <td>用戶名:</td>

      <td><input  type="text" name="name"/></td>

    </tr>

    <tr>

      <td>性別:</td>

      <td>

        <input  type="radio" name="sex" value="男"/>男

        <input  type="radio" name="sex" value="女"/>女

      </td>

    </tr>

    <tr>

      <td>興趣愛好:</td>

      <td>

        <input  type="checkbox" name="interest" value="上網"/>上網

        <input  type="checkbox" name="interest" value="旅遊"/>旅遊

        <input  type="checkbox" name="interest" value="閱讀"/>閱讀

      </td>

    </tr>

  </table>

  <input  type="submit" name="submit" value="提交"/>

</form>

</body>

</html>

requestDemo1.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="java.util.*" %>

<html>

<head>

<title>

接收請求參數

</title>

</head>

<body bgcolor="#ffffff">

<h1>

接收客戶端請求數據

</h1>

<%

request.setCharacterEncoding("GBK");

String name=request.getParameter("name");

String sex=request.getParameter("sex");

String[] interest=request.getParameterValues("interest");

%>

<table border="1">

  <tr>

    <td>用戶名:</td>

    <td><%=name%></td>

  </tr>

  <tr>

    <td>性別:</td>

    <td><%=sex%></td>

  </tr>

  <tr>

    <td>興趣愛好:</td>

    <td>

      <%

      for (int i = 0; i < interest.length; i++) {

        out.print(interest[i]);

        out.print(",");

      }

      %>

    </td>

  </tr>

</table>

</body>

</html>

requestDemo.jsp運行結果以下圖所示。

圖4-1 requestDemo.jsp顯示結果

輸入用戶名、性別和興趣愛好等信息後,點擊「提交」按鈕後將數據信息提交到requestDemo1.jsp頁面,運行結果以下圖所示。

圖4-2 requestDemo1.jsp顯示結果

【專家提示】requestDemo1.jsp在接收處理中文信息時,採用了方法request.setCharacterEncoding("GBK")進行編碼轉換,但這種方式只是當requestDemo.jsp表單提交方式爲method="post"方式纔有效。若是表單的提交方式爲method="get"方式requestDemo1.jsp代碼應該改寫爲以下所示。

requestDemo1.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="java.util.*" %>

<html>

<head>

<title>

接收請求參數

</title>

</head>

<body bgcolor="#ffffff">

<h1>

接收客戶端請求數據

</h1>

<%

//request.setCharacterEncoding("GBK");

String name=request.getParameter("name");

String sex=request.getParameter("sex");

String[] interest=request.getParameterValues("interest");

//對GET請求的額外處理

name=new String(name.getBytes("ISO-8859-1"),"GBK");

sex=new String(sex.getBytes("ISO-8859-1"),"GBK");

for (int i = 0; i < interest.length; i++) {

  interest[i]=new String(interest[i].getBytes("ISO-8859-1"),"GBK");

}

%>

<table border="1">

  <tr>

    <td>用戶名:</td>

    <td><%=name%></td>

  </tr>

  <tr>

    <td>性別:</td>

    <td><%=sex%></td>

  </tr>

  <tr>

    <td>興趣愛好:</td>

    <td>

      <%

      for (int i = 0; i < interest.length; i++) {

        out.print(interest[i]);

        out.print(",");

      }

      %>

    </td>

  </tr>

</table>

</body>

</html>

參見代碼中的以下語句:

String name=request.getParameter("name");

name=new String(name.getBytes("ISO-8859-1"),"GBK");

這兩句就將字符的編碼方式做了轉換,這樣中文字符就能夠正確地顯示了。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

request對象:請求轉送

 

有時須要訪問一組網絡資源(如其餘Servlet和JSP頁面)以知足客戶端請求,JSP能夠經過請求URL對Web服務器上的活動資源做出請求。Servlet API規範支持在服務器中運行的Servlet直接訪問服務器的資源。JSP和Servlet能夠將請求轉發到其餘資源,或包括資源在其響應中建立的響應。屬於同一個Web應用程序的JSP或Servlet能夠使用javax.servlet.RequestDispatcher接口的forward和include方法來共享數據

有時須要訪問一組網絡資源(如其餘Servlet和JSP頁面)以知足客戶端請求,JSP能夠經過請求URL對Web服務器上的活動資源做出請求。Servlet API規範支持在服務器中運行的Servlet直接訪問服務器的資源。JSP和Servlet能夠將請求轉發到其餘資源,或包括資源在其響應中建立的響應。屬於同一個Web應用程序的JSP或Servlet能夠使用javax.servlet.RequestDispatcher接口的forward和include方法來共享數據。

RequestDispatcher getRequestDispatcher(String path):取得一個相對於當前路徑的請求轉發器,以便於請求轉發。

void forward(SerletRequest request,ServletResponse response):用於將請求從一個JSP或Servlet轉發到同一服務器上的另外一個JSP或Servlet。

void include(SerletRequest request,ServletResponse response):用於包括另外一個Servlet的內容。

【例4-2】利用forward()方法做轉移控制

接下來介紹使用forward()在JSP或Servlet間轉移控制的方法。將例4-1的requestDemo.jsp更改代碼爲requestDemo2.jsp。將requestDemo1.jsp修改代碼保存爲requestDemo3.jsp,新生成一個dispatcherDemo.jsp。代碼分別以下:

requestDemo2.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>

請求參數輸入頁面

</title>

</head>

<body bgcolor="#ffffff">

<h1>

請求參數輸入頁面

</h1>

<form action="requestDemo3.jsp" method="POST">

  <table border="1">

    <tr>

      <td>用戶名:</td>

      <td><input  type="text" name="name"/></td>

    </tr>

    <tr>

      <td>性別:</td>

      <td>

        <input  type="radio" name="sex" value="男"/>男

        <input  type="radio" name="sex" value="女"/>女

      </td>

    </tr>

    <tr>

      <td>興趣愛好:</td>

      <td>

        <input  type="checkbox" name="interest" value="上網"/>上網

        <input  type="checkbox" name="interest" value="旅遊"/>旅遊

        <input  type="checkbox" name="interest" value="閱讀"/>閱讀

      </td>

    </tr>

  </table>

  <input  type="submit" name="submit" value="提交"/>

</form>

</body>

</html>

requestDemo3.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="java.util.*" %>

<%@ page import="javax.servlet.*" %>

<html>

<head>

<title>

接收請求參數

</title>

</head>

<body bgcolor="#ffffff">

<h1>

接收客戶端請求數據

</h1>

<%

request.setCharacterEncoding("GBK");

String name=request.getParameter("name");

String sex=request.getParameter("sex");

String[] interest=request.getParameterValues("interest");

%>

<table border="1">

 <tr>

   <td>用戶名:</td>

   <td><%=name%></td>

 </tr>

 <tr>

   <td>性別:</td>

   <td><%=sex%></td>

 </tr>

 <tr>

   <td>興趣愛好:</td>

   <td>

     <%

     for (int i = 0; i < interest.length; i++) {

       out.print(interest[i]);

       out.print(",");

     }

     %>

   </td>

 </tr>

</table>

<%

//轉發以前不能使用out.flush()或out.close()向客戶端提交響應

//forward轉發

RequestDispatcher rd=request.getRequestDispatcher("dispatcherDemo.jsp");

rd.forward(request,response);

%>

</body>

</html>

requestDemo3.jsp頁面在接收requestDemo2.jsp頁面的請求參數後進行forward轉發至dispatcherDemo.jsp頁面。

dispatcherDemo.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>

dispatcher轉發結果顯示頁面

</title>

</head>

<body bgcolor="#ffffff">

<h1>

dispatcher轉發結果顯示頁面

</h1>

name參數的值是:<%=request.getParameter("name")%>

</body>

</html>

dispatcherDemo.jsp繼續從request對象中取得客戶端請求參數「name」。requestDemo2.jsp運行顯示結果如圖4-3所示。

圖4-3 requestDemo2運行顯示結果

填寫數據點擊「提交」按鈕後,requestDemo3.jsp運行顯示結果如圖4-4所示。

圖4-4 requestDemo3.jsp運行顯示結果

requestDemo3.jsp並無顯示咱們代碼編寫顯示請求數據的表格,僅僅只顯示dispactherDemo.jsp頁面的內容。讀者能夠注意到IE地址欄URL並無發生改變用戶雖然請求的網絡資源是requestDemo3.jsp,但實際上給客戶端的響應是由dispatcherDemo.jsp呈現的,說明頁面響應控制權已經徹底移交給dispactherDemo.jsp。

【專家提示】調用forward()方法時必須注意下列兩點: 

1.調用forward()方法後,原先存放在HttpResponse對象中的內容將會自動被清除,在此以前requestDemo3.jsp再多的輸出也不會在頁面顯示輸出。

2.在HTTP迴應被「確認」(committed)之前才能調用forward()方法(這裏的「確認」是指將HTTP迴應的內容主體送回用戶端),若是在代碼註釋處所說明的使用out.flush()或out.close()方法,不然將拋出IllegalStateException異常。

【例4-3】用include()在一個JSP包含另外一個JSP或Servlet的響應輸出

將例4-2中的requestDemo3.jsp改寫成以下的代碼。

requestDemo3.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ page import="java.util.*"%>

<%@ page import="javax.servlet.*"%>

<html>

<head>

<title>接收請求參數</title>

</head>

<body bgcolor="#ffffff">

<h1>接收客戶端請求數據</h1>

<%

request.setCharacterEncoding("GBK");

String name = request.getParameter("name");

String sex = request.getParameter("sex");

String[] interest = request.getParameterValues("interest");

%>

<table border="1">

<tr>

<td>用戶名:</td>

<td><%=name%></td>

</tr>

<tr>

<td>性別:</td>

<td><%=sex%></td>

</tr>

<tr>

<td>興趣愛好:</td>

<td>

<%

for (int i = 0; i < interest.length; i++) {

out.print(interest[i]);

out.print(",");

}

%>

</td>

</tr>

</table>

<%

//forward轉發

//RequestDispatcher rd=request.getRequestDispatcher("dispatcherDemo.jsp");

//rd.forward(request,response);

//include轉發

out.flush();

RequestDispatcher rd = request

.getRequestDispatcher("dispatcherDemo.jsp");

rd.include(request, response);

%>

<h2>轉發後的頁面輸出:我仍是有主權的</h2>

</body>

</html>

圖4-5 requestDemo2運行顯示結果

填寫數據點擊「提交」按鈕後,requestDemo3.jsp運行顯示結果如圖所示。

圖4-6 requestDemo3運行顯示結果

RequestDispatcher接口的include()方法與forward()方法很是相似,唯一的不一樣在於:利用include()方法將HTTP請求轉送給其餘JSP頁面後,被調用的JSP頁面雖然能夠處理這個HTTP請求,可是最後的主導權仍然是在原來的JSP頁面,如requestDemo3.jsp輸出處理requestDemo2.jsp請求數據信息結果後,顯示dispatcherDemo.jsp頁面要求輸出的內容,最後仍然由requestDemo3.jsp掌握主動輸出權。換言之,被調用的JSP頁面若是產生任何HTTP迴應,將會併入原來的HttpResponse對象。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

request對象:請求頭信息

 

request對象還有其餘一些的經常使用方法來取得客戶端請求頭中的一些詳細信息,如:

String getRemoteAddr() 取得客戶端訪問IP。

String getRequestURL() 取得客戶端請求的URL串。

Enumeration getHeaderNames() 取得全部的請求頭名。

String getHeader(String head) 取得指定的請求頭信息的值。

其它更多方法使用詳情請查看API幫助。

【例4-4】獲得請求頭信息

接下一塊兒來編寫一個例子演示request對象取得請求頭信息的幾個方法的使用,爲了簡單起見咱們直接修改requestDemo3.jsp的代碼。

requestDemo3.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ page import="java.util.*"%>

<%@ page import="javax.servlet.*"%>

<html>

<head>

<title>接收請求參數</title>

</head>

<body bgcolor="#ffffff">

<h1>接收客戶端請求數據</h1>

<%

request.setCharacterEncoding("GBK");

String name = request.getParameter("name");

String sex = request.getParameter("sex");

String[] interest = request.getParameterValues("interest");

%>

<table border="1">

<tr>

<td>用戶名:</td>

<td><%=name%></td>

</tr>

<tr>

<td>性別:</td>

<td><%=sex%></td>

</tr>

<tr>

<td>興趣愛好:</td>

<td>

<%

for (int i = 0; i < interest.length; i++) {

out.print(interest[i]);

out.print(",");

}

%>

</td>

</tr>

</table>

<%

//forward轉發

//RequestDispatcher rd=request.getRequestDispatcher("dispatcherDemo.jsp");

//rd.forward(request,response);

//include轉發

out.flush();  

RequestDispatcher rd = request

.getRequestDispatcher("dispatcherDemo.jsp");

rd.include(request, response);

%>

<h2>轉發後的頁面輸出:我仍是有主權的</h2>

<b>HTTP請求方式:</b><%=request.getMethod()%><br>

<b>客戶端IP:</b><%=request.getRemoteAddr()%><br>

<b>請求的URL是:</b><%=request.getRequestURL()%><br>

<b>更多關於請求對象的信息:<br>

<%

Enumeration em=request.getHeaderNames();

while(em.hasMoreElements()){

  String header=(String)em.nextElement();

  out.print("<b>");

  out.print(header);

  out.print(":<b>");

  out.print(request.getHeader(header)+"<br>");

}

%>

</body>

</html>

運行顯示結果如圖所示。

圖4-7 requestDemo3.jsp運行顯示結果

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

response對象:設置響應類型

 

response對象主要將JSP處理數據後的結果傳回到客戶端。response對象是實現javax.servlet.http.HttpServletResponse接口。response的方法有不少,下面列出幾個經常使用的方法。

void setContentType (String name) 設置做爲響應生成的內容的類型和字符編碼。

void sendRedirect (String name) 發送一個響應給瀏覽器,指示其應請求另外一個URL。

void setHeader(String name,String value) 設置HTTP響應的參數使客戶自動產生相應的動做。

設定response對象的contentType屬性能夠指定JSP頁面生成響應MIME的類型和JSP文件的字符編碼方式,它們都是最早傳送給客戶端。圖4-7中的accept描述指明當前客戶端瀏覽器所能支持的MIME類型。

【專家提示】MIME的含義是「多用途的網際郵件擴充協議」。它不是一種郵件傳輸協議,相反,它定義傳輸的內容:消息的格式、附件等。許多文檔都定義了MIME協議,包含:RFC 82二、RFC 204五、RFC 2046和RFC 2047。做爲通常程序員,通常不須要擔憂這些格式。可是,這些格式確實存在,併爲您的程序所用。例如:text/plain表示輸出內容是未格式化的文本文檔(txt)格式的, 當MIME的包頭是text/plain時,瀏覽器將直接顯示而不關心它的什麼字體,顏色之類的參數;image/gif或image/jpeg內容將以圖片的形式顯示。

【例4-5】將JSP頁面顯示成Excel表單

一塊兒來看看如何經過設置response對象的contentType屬性將一個JSP頁面顯示成爲一個EXCEL表單的形式。

responseExcel.jsp

<html>

<head>

<title>顯示成爲EXCEL報表</title>

</head>

<body>

<h1>

將HTML表格數據,顯示成爲EXCEL表格

</h1>

<%

response.setContentType("application/vnd.ms-excel");

%>

<table border="1">

  <tr>

    <td>用戶名</td>

    <td>李四</td>

  </tr>

  <tr>

    <td>性別</td>

    <td>女</td>

  </tr>

  <tr>

    <td>興趣</td>

    <td>

   上網,閱讀,旅遊

    </td>

  </tr>

</table>

</body>

</html>

responseExcel.jsp運行結果如圖4-8所示。

圖4-8 IE瀏覽器的提示框

點擊「打開」按鈕,運行結果如圖4-9所示。

圖4-9 頁面顯示結果

【例4-6】生成圖形驗證碼

本例經過設置response對象的contentType屬性爲「image/jpeg」以圖片的形式顯示一個隨機驗證碼。login.jsp和verifycode.jsp代碼分別以下。

login.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html><head>

<title>用戶登陸頁面</title>

</head>

<body bgcolor="#ffffff">

<h1>

請輸入用戶登陸信息

</h1>

<form name="userinfo" action="checklogin.jsp"

 method="POST" onsubmit="return(checkinfo())">

<table border="1">

  <tr>

    <td>用戶名:</td>

    <td><input  type="text" name="username"/></td>

    <td><a href="register.jsp">用戶註冊</a></td>

  </tr>

  <tr>

    <td>密碼:</td>

    <td><input  type="password" name="password"/></td>

    <td><a href="forgetpassword.jsp">忘記密碼了</a></td>

  </tr>

  <tr>

    <td>驗證碼:</td>

    <td><input  type="text" name="verifycode"/></td>

    <td><img alt="" src="verifycode.jsp" /></td>

  </tr>

  <tr>

    <td><input  type="submit" value="登陸"/></td>

    <td><input  type="reset" value="重置"/></td>

    <td></td>

   </tr>

</table>

</form>

<script >

function checkinfo(){

  var oObject = document.all.item("userinfo");

  for (i = 0; i < oObject.length; i++){

    if (oObject(i).value.length==0) {

      alert("必填項的值不能爲空");

      oObject(i).focus();

      return false;

    }

  }

 return true;

}

</script>

</body>

</html>

verifycode.jsp

<%@ page import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>

<%@ page  import="java.io.OutputStream" %>

<%

response.setContentType("image/jpeg");

response.addHeader("Content-Disposition","attachment;filename=verifycode.jpg" );

//定義一個整型變量用於存放生成的隨機數

int icode=0;

//在內存中生成一個圖片以及寬、高、類型

BufferedImage image=new BufferedImage(50,16,BufferedImage.TYPE_INT_RGB);

//生成一個2D的圖形

Graphics g =image.getGraphics();

//設置圖形爲白色

g.setColor(Color.white);

//填充圖象

g.fillRect(0,0,50,16);

//新建一個隨機對象

Random random=new Random();

//取出4位整數

while(icode<=1000){

  icode=random.nextInt(10000);

};

//把隨機整數轉換成字符串

String scode=icode+"";

//將生成隨機校驗碼存入session中

session.setAttribute("verifycode",scode);

//設置圖形的顏色爲黑色

g.setColor(Color.BLACK);

//把生成的隨機數作爲字符串寫到圖形中

g.drawString(scode,12,12);

//從response.getOutputStream()獲得一個輸出流對象

ServletOutputStream os=response.getOutputStream();

//輸出到頁面(不知道個人理解是否正確)

ImageIO.write(image,"JPEG",os);

//關閉輸出流對象

os.flush();

os.close();%>

login.jsp和verifycode.jsp的運行結果如圖所示。

圖4-10 login.jsp運行顯示結果

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

response對象:頁面重定向技術

用response.sendRedirect()方法能夠將頁面重定向至其它頁面,重定向後在瀏覽器地址欄上會出現重定向頁面的URL。

【例4-7】頁面重定向

繼續使用例4-6中的login.jsp,用戶在輸入用戶名和密碼後將數據提交至checklogin.jsp頁面,checklogin.jsp檢查密碼是否等於「000000」,若是等於則顯示用戶登陸成功,不然跳轉至前面示例的dispatcherDemo.jsp頁面。

checklogin.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>responseDemo</title>

</head>

<body bgcolor="#ffffff">

<h1>

用戶登陸信息

</h1>

<%

String name=request.getParameter("name");

String password=request.getParameter("password");

if (password.equalsIgnoreCase("000000")){

%>

用戶登陸成功

<%}else{

  response.sendRedirect("dispatcherDemo.jsp");

}   

%>

</body>

</html>

首先運行login.jsp,如圖-11所示。

圖4-11 login.jsp運行顯示結果

輸入用戶名「orion」、密碼「000000」和驗證碼「2071」點擊「登陸」按鈕提交至checklogin.jsp頁面運行結果如圖4-12所示。

圖4-12 checklogin.jsp運行顯示結果

若是輸入密碼不等於「000000」時,checklogin.jsp將執行以下語句:

response.sendRedirect("dispatcherDemo.jsp");

顯示結果如圖4-13所示。

用response.sendRedirect()方法能夠將頁面重定向至其它頁面,重定向後在瀏覽器地址欄上會出現重定向頁面的URL。

【例4-7】頁面重定向

繼續使用例4-6中的login.jsp,用戶在輸入用戶名和密碼後將數據提交至checklogin.jsp頁面,checklogin.jsp檢查密碼是否等於「000000」,若是等於則顯示用戶登陸成功,不然跳轉至前面示例的dispatcherDemo.jsp頁面。

checklogin.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>responseDemo</title>

</head>

<body bgcolor="#ffffff">

<h1>

用戶登陸信息

</h1>

<%

String name=request.getParameter("name");

String password=request.getParameter("password");

if (password.equalsIgnoreCase("000000")){

%>

用戶登陸成功

<%}else{

  response.sendRedirect("dispatcherDemo.jsp");

}   

%>

</body>

</html>

首先運行login.jsp,如圖-11所示。

圖4-11 login.jsp運行顯示結果

輸入用戶名「orion」、密碼「000000」和驗證碼「2071」點擊「登陸」按鈕提交至checklogin.jsp頁面運行結果如圖4-12所示。

圖4-12 checklogin.jsp運行顯示結果

若是輸入密碼不等於「000000」時,checklogin.jsp將執行以下語句:

response.sendRedirect("dispatcherDemo.jsp");

顯示結果如圖4-13所示。

圖4-13 dispatcherDemo.jsp運行顯示結果

從運行結果來看IE的地址欄發生了改變已經徹底指向了

http://localhost:8080/implict_object/dispatcherDemo.jsp

說明是從客戶端從新發送了一次請求到服務器,因此dispatcherDemo.jsp沒法從request對象中再次取得用戶名參數。

【思考1】思考RequestDispatcher.forward()和response.sendRedirect()二者有什麼區別?編寫程序時使用哪一個更好?

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

response對象:設置響應標頭

 

經過response.setHeader()方法能夠設置HTTP響應的頭信息參數使客戶端能自動產生相應的動做。

【例4-8】限時自動重定向

接下來將實現一個JSP中實如今某頁面停留若干秒後,自動重定向到另外一頁面的功能。實際上HTML的使用中也有相似的功能:

<meta http-equiv="refresh" content="300; url=target.jsp">

它的含義是:在5分鐘以後,正在瀏覽的頁面將會自動變爲target.html。代碼中的300爲刷新的延遲時間,以秒爲單位。targer.jsp爲你想轉向的目標頁,若爲本頁則爲自動刷新本頁。能夠經過setHeader來實現某頁面停留若干秒後,自動重定向到另外一頁面,關鍵代碼以下:

String content=stayTime+";URL="+URL;

response.setHeader("REFRESH",content);

refreshDemo.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>refreshDemo</title>

</head>

<body bgcolor="#ffffff">

<h1>

自動刷新示例

</h1>

<%

System.out.println(new java.util.Date()+ "刷新一次了");

String content=5+";URL=refreshDemo.jsp";

response.setHeader("REFRESH",content);

%>

</body>

</html>

refreshDemo.jsp設置的是每隔5秒刷新一次,運行結果顯示如圖4-14所示。

圖4-14 refreshDemo.jsp運行顯示結果

 

圖4-15 運行refreshDemo.jsp時Tomcat的控制檯輸出

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

out對象

 

out對象能把結果輸出到網頁上。一般咱們最常使用out.println(String name)和out.print(String name),它們二者最大的差異在於println()在輸出的數據後面會自動加上換行的符號;而println()不會在數據後自動換行。但這種區別對於HTML網頁輸出在IE瀏覽中顯示沒有任何差異的,若是用記事本查看HTML源碼時能夠看到是有差異的。

out對象除了這兩種最常使用方法以外,它還有一些方法,這些方法主要是用來控制管理輸出的緩衝區(buffer)和輸出流(output stream)。

int getBufferSize():取得目前緩衝區的大小(KB)。

int getRemaining():取得目前使用後還剩下的緩衝區大小(KB)。

void clearBuffer():清除輸出緩衝區的內容。

void close():關閉輸出流,清除全部的內容。

【例4-9】使用out對象

outDemo.jsp

<%@ page contentType="text/html; charset=GBK"%>

<html>

<head>

<title>outDemo.jsp</title>

</head>

<body>

<h2>JSP out對象示例</h2>

<%

out.println("歡迎來到 JSP: 隱含對象<br>");

out.print("歡迎來到 JSP: 隱含對象<br>");

int BufferSize=out.getBufferSize();

int Availabel=out.getRemaining();

int Used=BufferSize-Availabel;

%>

緩衝區大小:<%= BufferSize%><br>

能夠使用大小:<%= Availabel%><br>

被使用了:<%=Used %><br>

</body>

</html>

outDemo.jsp運行顯示結果如圖4-16所示。

圖4-16 outDemo.jsp運行顯示結果

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

與Context有關的隱含對象

 

本節中將要介紹session、application、pageContext這三個對象。session對象提供一些機制,讓服務器能個別辨認用戶。當程序在執行時,application對象能提供服務端(Server-Side)的Context,說明哪些資源是可利用的,哪些信息是可獲取的。pageContext對象提供存取全部在此網頁中能夠被利用的隱含對象,而且能夠管理它們的屬性。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

session對象

 

session對象表示用戶的會話情況,用此項機制能夠輕易識別每個用戶,能保存和跟蹤用戶與服務器之間的會話狀態。例如,購物車最常使用session的概念,當用戶把商品放入購物車時,它再去添加另外的商品到購物車時,原先選購的商品仍然在購物車內,並且用戶不用反覆去作身份驗證。但若是用戶關閉Web瀏覽器,則會斷開與服務器的會話。

session對象存儲有關用戶會話的全部信息。session對象用於在程序的網頁之間跳轉時,存儲有關會話的信息,如圖4-17所示。

圖4-17 會話跟蹤原理圖

session對象經常使用的方法以下。

void setAttribute(String name,Object value):以名稱/值的方式,將一個對象的值存放到session中。

void getAttribute(String name):根據名稱去獲取session中存放對象的值。

【例4-10】校驗驗證碼

接下來演示如何從session對象中得驗證碼,並比較用戶輸入的驗證碼是否與session對象中保存的驗證碼相等。一塊兒來修改例4-7中的checklogin.jsp文件代碼。

checklogin.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>responseDemo</title>

</head>

<body bgcolor="#ffffff">

<h1>

用戶登陸信息

</h1>

<%

String name=request.getParameter("name");

String password=request.getParameter("password");

if (password.equalsIgnoreCase("000000")){

//從Session中取得驗證碼的值

String verifycode=(String)session.getAttribute("verifycode");

//從客戶端取用戶提交過來驗證碼

String verifycode1=request.getParameter("verifycode");

if (verifycode.equalsIgnoreCase(verifycode1)){

%>

用戶登陸成功,客戶端輸入驗證碼爲:<%= verifycode1%>

<%}

}else{

  response.sendRedirect("dispatcherDemo.jsp");

}   

%>

</body>

</html>

接下來看看來效果。login.jsp的運行效果如圖4-18所示。

圖4-18 login.jsp運行顯示結果

輸入用戶爲「orion」,密碼爲「000000」和驗證碼爲「4762」點擊「登陸」按鈕後運行結果如圖所示。

圖4-19 從會話中取得驗證碼的顯示

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

application對象

 

application對象的做用範圍比session更大,不只僅是在同一個瀏覽器窗口中,而是做用於整個應用程序,全部客戶端瀏覽器窗口均可以共享對象,它從服務器啓動開始就在,直到服務器關閉爲止。application對象經常使用的方法以下。

String getServerInfo():取得容器的名稱和版本。

void setAttribute(String name,Object value):以名稱/值的方式,將一個對象的值存放到application中。

void getAttribute(String name):根據名稱去獲取application中存放對象的值。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

pageContext對象

 

pageContext對象使用戶能夠訪問頁面做用域中定義的全部隱含對象。pageContext對象提供方法以訪問隱含對象在頁面上定義的全部屬性,它的做用範圍僅僅在頁面內。

pageContext對象最經常使用的方法以下。

void setAttribute(String name,Object value):以名稱/值的方式,將一個對象的值存放到pageContext中。

void getAttribute(String name):根據名稱去獲取pageContext中存放對象的值。

這兩個方法的使用與session,application相似,下面舉一個例子來區別pageContext、session、application這3個對象做用範圍的區別。

【例4-11】計數器

下面將分別使用session、application和pageContext對象顯示會話計數、應用程序計數和頁面計數。

Count.java

package implictobject;

public class Count {

//定義計數器

private int count;

//返回計數器的當前值

    public int getCount(){

        return ++count;

    }

}

countDemo.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="implictobject.*" %>

<html>

<head>

<title>countDemo</title>

</head>

<body bgcolor="#ffffff">

<h1>

多種計數器示例

</h1>

<%

//判斷是否存在計數器對象,不存在則新建

if(pageContext.getAttribute("count")==null)

pageContext.setAttribute("count",new Count());

if(session.getAttribute("count")==null)

session.setAttribute("count",new Count());

if(application.getAttribute("count")==null)

application.setAttribute("count",new Count());

%>

<h2>

  頁面計數器:

  <%=((Count)pageContext.getAttribute("count")).getCount() %>

</h2>

<h2>

  會話計數器:

  <%=((Count)session.getAttribute("count")).getCount() %>

</h2>

<h2>

  應用計數器:

  <%=((Count)application.getAttribute("count")).getCount() %>

</h2>

</body>

</html>

countDemo.jsp運行結果如圖4-20所示。

圖4-20 countDemo.jsp運行結果

多刷新幾回頁面能夠發現頁面計數器始終爲1,會話計數器和應用計數器實現告終果累加。按如圖所示的操做新建一個瀏覽器窗口看看countDemo.jsp輸出的結果是否有變化。

看看新建瀏覽器窗口的輸出,以下圖所示。

圖4-21 新建瀏覽器窗口後countDemo.jsp運行結果

能夠看出application(應用計數器)徹底是依賴服務器存在的,session(會話計數器)依賴窗口會話,pageContext(頁面計數器)只依賴頁面自己。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

與Servlet有關的隱含對象

 

在JSP頁面的執行過程當中,每一個JSP頁面都會生成一個Servlet。Servlet對象提供方法和變量以訪問爲JSP頁面建立的Servlet的全部信息。Page和config就是這樣的Servlet對象。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

page對象

 

page對象提供對網頁上定義的全部對象的訪問。page對象表示頁面自己,它是java.lang.Object類的一個實例。爲JSP頁面建立的Servlet類定義變量和方法,這些變量和方法包含頁面的信息。使用page對象能夠訪問全部這些變量和方法。page對象的用法以下。

<%@page info="個人信息" contentType="text/html;charset=GBK" %>

<html>

<body>

<%=((javax.servlet.jsp.HttpJspPage)page).getServletInfo()%>

</body>

</html>

不過,page對象較少在JSP開發中使用,通常使用前面學過的page指令便可。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

config對象

 

config對象存儲Servlet的一些初始信息,與page對象同樣都會不多用到。config對象是javax.servlet.ServletConfig接口的一個實例,ServletConfig接口提供方法以檢索Servlet初始化參數。config對象表示編譯JSP頁面的Servlet初始化數據的配置。

String propertyFile=(String)config.getInitParameter("propertyFile");

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

與Error有關的隱含對象

 

最後一類的隱含對象只有一個成員:exception對象。當JSP網頁有錯誤時會產生異常,而exception對象就來針對這個異常作處理。exception對象並非在每個JSP網頁中都可以使用。若要使用exception對象時,必須在page指令中設定。<%@page isErrorPage="true"%>才能使用,否則在編譯時會產生錯誤。

【例4-12】使用exception對象

MakerError.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page errorPage="ErrorPage.jsp" %>

<html>

<head>

<title>產生錯誤頁面</title>

</head>

<body bgcolor="#ffffff">

<h1>

產生被零整除錯誤的頁面,若是沒有發生跳轉說明頁面正確運行

</h1>

<%

  int i=8,j=0;

  out.print("i/j的正確結果:");

  out.print(i/j);

%>

</body>

</html>

ErrorPage.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@page isErrorPage="true" %>

<%@page import="java.io.PrintWriter"%>

<html>

<head>

<title>錯誤處理頁面</title>

</head>

<body bgcolor="#ffffff">

<h1>

程序運行發生了以下錯誤:

</h1>

<font color="red">

  錯誤緣由是:<%=exception.getMessage()%>

</font>

<br>

<font color="red">

  錯誤跟蹤:<%exception.printStackTrace(new PrintWriter(out));%>

</font>

</body>

</html>

MakerError.jsp會產生一個除零異常將被自動轉給ErrorPage.jsp處理,由於<%@page isErrorPage="true" %>因此能讀取exception對象中的錯誤信息。運行結果如圖4-22所示。

圖4-22 錯誤處理頁面運行結果

【專家提示】程序代碼中打印異常追蹤信息使用了printStackTrace(new java.io.PrintWriter(out)),其中 printStackTrace()的參數要爲PrintWriter而不是JspWriter。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月03日

 

小結

 

JSP隱含對象分爲I/O有關對象、Context有關對象、Servlet有關對象、Error有關對象4類。

I/O有關對象包括request、response和out;Context有關對象包括session、application和pageContext;Servlet對象包括config和page;Error有關對象包括exception。

request對象經過getParameter()和getParameterValues()方法去獲取表單請求數據;response對象經過sendRedirect()方法去實現重定向;out方法經過print()方法去實現頁面輸出。

session、application和pageContext對象經過setAttribute()和getAttribute()方法去設置和獲取屬性值。

 
 
 
 

第 4 章:隱含對象解析做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

思考解答

 

【思考1】思考requestDispatcher.forward()和response.sendRedirect()二者的區別,以及平時在程序開發中如何使用它們?

答:requestDispatcher.forward()是容器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向後的地址;而response.sendRedirect()則是徹底的跳轉,瀏覽器將會獲得跳轉的地址,並從新發送請求連接。這樣,從瀏覽器的地址欄中能夠看到跳轉後的連接地址。前者更加高效,在前者能夠知足須要時,儘可能使用requestDispatcher.forward()方法。

 

第5章  Servlet開發

【本章專家知識導學】

衆所周知JSP頁面最終在服務端是被編譯成Servlet的形式運行的,要對JSP有深刻的瞭解,Servlet是最基本的內容,只要可以把Servlet學好,就更可以理解JSP技術底層運做的方式。

本章旨在引導讀者學習什麼是Servlet以及客戶端和服務器之間的數據傳輸是如何發生的。經過學習讀者還可以掌握HttpServlet類的方法,用於開發Servlet的Servlet生命週期、基本接口、類和方法的概念。讀者將可以較全面地使用Servlet API進行開發。

5.1  什麼是Servlet

服務器是一臺設備,它爲網絡上的不一樣設備(客戶端)的請求提供信息。例如,文件服務器提供有關文件的共享信息。最初,經過編寫CGI(Common Gateway Interface,通用網關接口)程序來實現數據在Web上的傳輸,這類程序是使用如Perl這樣的語言編寫的。可是,對於客戶端做出的每一個請求,必須建立CGI程序的一個新的實例,這將佔用大量內存致使系統運行效率不高。所以爲了解決這個問題,1997年3月 Sun Microsystems公司所組成的JavaSoft部門推出了Servlet技術替代當時的CGI之類的產品。Java Servlet是一個專門用於編寫網絡服務器應用程序的Java組件。全部基於Java的服務器端編程都是構建在Servlet之上的。Servlet具備以下優勢:

可移植性

因爲Servlet是用Java編寫的,因此它與生俱來就有跨平臺的特性,所以Servlet程序的設計徹底和平臺是無關的,一樣的Servlet徹底能夠在Apache,IIS等不一樣Web服務器上執行,無論底層的操做系統是Windows,Solaris,Mac,Linux仍是其餘的能支持Java的操做系統。

高效率

Servlet是跟普通的Java程序同樣,是被編譯成字節碼後由JVM執行的。相比傳統的CGI,儘管CGI是用本地代碼直接執行的,可是因爲每次客戶端發出請求,服務器必須啓動一個新的程序來處理請求,這就把高負載強加給了服務器資源,尤爲若是CGI使用腳本語言編寫時,如perl語言,服務器還必須啓動語言解釋程序,程序越多,佔用的內存就越多,消耗CPU資源也越多,嚴重影響系統性能。

  Servlet運行於Servlet引擎管理的Java虛擬機中,被來自客戶機的請求所喚醒,與CGI不一樣的是,在虛擬機中只要裝載一個Servlet就可以處理新的請求,每一個新請求使用內存中那個Servlet的相同副本,因此效率比CGI要高。其它採用服務器端的腳本,如ASP,PHP,語言解釋程序是內置程序,所以能夠加快服務器的運行,可是效率仍是比不上準編譯的Servlet。實際的使用也已經證實,Servlet是效率很高的服務器端程序,很適合用來開發Web服務器應用程序。

【專家提示】使用過CGI的讀者必定知道CGI程序的做用,Servlet要實現的功能和CGI是同樣的,只是實現的時候更爲方便,效率更高。若是讀者對以上概念不是很清楚,也沒必要着急,經過學習下面的內容,有了感性的認識,再回來看看,必定會有更大的收穫。

擴展性

Java Servlet有着十分普遍的應用。不只能簡單的處理客戶端的請求,藉助Java的強大的功能,使用Servlet還能夠實現大量的服務器端的管理維護功能,以及各類特殊的任務,好比,併發處理多個請求,轉送請求,代理服務等。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

Servlet的工做原理

 

Servlet容器將Servlet動態地加載到服務器上。以HTTP Servlet爲例,HTTP Servlet使用HTTP請求和HTTP響應標題與客戶端進交互。所以,Servlet容器支持請求和響應所用的HTTP協議。Servlet應用程序的工做原理如圖 5-1所示。

圖5-1 Servlet工做原理

客戶端對Servlet的請求首先會被Web服務器接收,Web服務器將客戶的HTTP請求提交給Servlet容器,Servlet容器調用相應的Servlet,Servlet做出的響應傳遞到Servlet容器,並進而由WEB服務器將響應傳輸給客戶端。WEB服務器提供靜態內容並將全部客戶端對Servlet做出的請求傳遞到Servlet容器。

Servlet是實現javax.servlet.Servlet接口的對象。大多數Servlet經過從GenericServlet或HttpServlet類進行擴展來實現。Servlet API包含於兩個包中,即javax.servlet和javax.servlet.http。

(1)javax.servlet包

圖5-2 javax.Servlet包

ServletInputStream類:用於從客戶端讀取二進制數據。

ServletOutputStream類:向客戶端發送二進制數據。

GenericServlet類:抽象類,定義一個通用的,獨立於底層協議的Servlet。

ServletRequest接口:定義一個對象封裝客戶向Servlet發關的請求信息。

ServletResponse接口:定義一個對象輔助Servlet將請求的響應信息發送給客戶端。

ServletContext接口:定義Servlet使用方法以獲取其容器的信息。

ServletConfig接口:定義了在Servlet初始化的過程當中由Servlet容器傳遞給Servlet的配置信息對象。

Servlet接口:定義全部Servlet必須實現的方法。

(2)javax.servlet.http包

圖5-3 javax.servlet.http

HttpServletRequest接口:擴展ServletRequest接口,爲HTTP Servlet提供HTTP請求信息。

HttpServletResponse接口:擴展ServletResponse接口,提供HTTP特定的發送響應的功能。

HttpSession接口:用於標識客戶端並存儲有送客戶端的信息。

HttpSessionAttributeListener接口:實現這個偵聽接口用於獲取會話屬性列表改變的通知。

HttpServlet類:擴展GenericServlet的抽象類。用於擴展建立Http Servlet。

Cookie類:建立一個Cookie,用於存儲Servlet發送給客戶端的消息。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

如何開發Servlet

 

讀者瞭解Servlet的一些基礎知識後,接下來我將開發一個簡單的Servlet。開發Servlet步驟通常分爲:

安裝Servlet運行環境。

編寫Servlet接口的實現程序。

編譯並部署編寫好的Servlet程序。

運行Servlet查看結果。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

安裝Servlet運行環境

 

爲了運行Servlet,首先固然須要一個JVM來提供對Java的基本支持,通常須要安裝JRE(Java Runtime Environment)或JDK(Java Develop Kit,JRE是其一個子集)。其次咱們須要Servlet API的支持,通常的Servlet引擎都自帶Servlet API,只要咱們安裝Servlet引擎,或直接支持Servlet的Web服務器以後便會自動安裝上Servlet相關的程序包。本章使用本書第二章「開發環境的安裝與配置」中所講述的Tomcat服務器爲Servlet運行環境。

【專家提示】典型的Servlet運行環境有JSWDK,Tomcat,Resin等,這幾個都是免費的軟件,適合用來學習Servlet和JSP。它們都自帶一個簡單的HTTP Server,只需簡單配置便可投入使用,也能夠把它們綁定到經常使用的Web服務器上,如Apache,IIS等,提供小規模的Web服務。還有一些商業的大中型的支持Servlet和JSP的Web服務器,如JRun,Web Sphere,Web Logic等等,配置比較複雜,並不適合初學者,可是功能較爲強大,有條件的讀者能夠一試。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

編寫Servlet接口的實現程序

 

程序必須導入(import)javax.servlet.*、javaxservlet.http.*兩個包。

全部Servlet都必須實現javax.servlet.Servlet接口(Interface),可是一般咱們都會從javax.servlet.GenericServlet或javax.servlet.http.HttpServlet擇一繼承來實現。若寫的Servlet程序和HTTP協議無關,那必須繼承GenericServlet抽象類;如有關,就必須繼承HttpServlet抽象類。目前咱們絕大多數應用都是與HTTP協議有關,因此本書示例的Servlet繼承HttpServlet抽象類。

【例5-1】一個簡單的Servlet 

firstServlet.java

package ch05;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

public class FirstServlet extends HttpServlet {

    private static final String CONTENT_TYPE = "text/html; charset=GBK";

    //初始化

    public void init() throws ServletException {

    }

    //處理HTTP請求

    protected void service(HttpServletRequest request, HttpServletResponse response) throws

           ServletException, IOException {

       response.setContentType(CONTENT_TYPE);

       PrintWriter out = response.getWriter();

       out.println("<html>");

       out.println("<head><title>FirstServlet</title></head>");

       out.println("<body bgcolor=\"#ffffff\">");

       out.println("<H1>這是個人第一個Servlet</H1>");

       out.println("</body>");

       out.println("</html>");

       out.close();

   }

    //清除資源

    public void destroy() {

    }   

}

Servlet能夠利用HttpServletResponse接口的setContentType()方法來設定內容類型,咱們要顯示爲HTML網頁類型,所以,內容類型設爲「text/html」,這是HTML網頁的標準MIME類型值。以後,Servlet用getWrite()方法取得PrintWriter類型的out對象,它與PrintSteam相似,可是它能對Java的Unicode字符進行編碼轉換。最後,再利用out對象把字符串顯示在網頁上。

接下來看如何編譯、部署Servlet程序。將servlet-api.jar(能夠在{Tomcat_Install}\common\lib目錄下找到)加入至CLASSPATH之中,使用您的IDE工具或直接使用javac來編譯firstServlet.java。編譯好firstServlet.java以後將其生成的class文件放置到相應的Web應用目錄,如圖 5-4所示。

圖5-4 部署Servlet應用

接下再設定web.xml,以下:

<servlet>

    <servlet-name>firstservlet</servlet-name>

    <servlet-class>ch05.FirstServlet</servlet-class>

  </servlet>

  <servlet-mapping>

    <servlet-name>firstservlet</servlet-name>

    <url-pattern>/firstservlet</url-pattern>

  </servlet-mapping>

這樣當客戶端產生/firstservlet請求的時候,Tomcat就能把這個請求定向到ch05.firstServlet上,該Servlet就能正常運行了。

firstServlet.java的執行結果如圖5-5所示。

圖5-5 firstServlet.java的執行結果

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

Servlet的生命週期

 

跟客戶端的Applet類似,Servlet也遵循嚴格的生命週期。Servlet的生命週期由Servlet容器控制,容器建立Servlet的實例。Servlet生命週期就是指Servlet實例在建立以後響應客戶請求直至銷燬的全過程。Servlet實例的建立取決於Servlet的首次調用。Servlet接口定義了Servlet生命週期的3個方法,分別說明以下。

&#61656;init()。當Servlet第一次被裝載時,Servlet引擎調用這個Servlet的init()方法,只調用一次。若是某個Sevlet須要特殊的初始化須要。那麼Servlet編寫人員能夠重寫該方法來執行初始化任務。這是一個可選的方法。若是某個Servlet不須要初始化,那麼默認狀況下將調用它父類的init()方法。系統保證,在init方法成功完成之前,是不會調用Servlet去處理任何請求的。

&#61656;service()。這是Servlet最重要的方法,是真正處理請求的地方。對於每一個請求,Servlet引擎將調用Servlet的service()方法,並把Servlet請求對象和Servlet響應對象最爲參數傳遞給它。

&#61656;destroy()。這是相對於init的可選方法,當Servlet即將被卸載時由Servlet引擎來調用,這個方法用來清除並釋放在init()方法中所分配的資源。

Servlet的生命週期能夠被概括爲如下幾步:

(1) 裝載Servlet,這一項操做通常是動態執行的。然而,Servlet一般會提供一個管理的選項,用於在Servlet啓動時強制裝載和初始化特定的Servlet。

(2) 服務器建立一個Servlet實例。

(3) 服務器調用Servlet的init()方法。

(4) 一個客戶端請求到達Server。

(5) 服務器建立一個請求對象。

(6) 服務器建立一個響應對象。

(7) 服務器激活Servlet的servic()e方法,傳遞請求和響應對象做爲參數。

(8) service()方法得到關於請求對象的信息,處理請求,訪問其餘資源,得到須要的信息。

(9) service()方法使用響應對象的方法。將響應傳回Server,最終到達客戶端。Service()方法可能激活其餘方法以處理請求。如doGet(),doPost()或其餘程序員本身開發的方法。

(10) 對於更多的客戶端請求,Server建立新的請求和響應對象,仍然激活此servlet的service()方法,將這兩個對象做爲參數傳遞給它,如此重複以上的循環,但無需再次調用init方法,Servlet通常只初始化一次。

(11) 當Server再也不須要Servlet時,好比當Server要關閉時,Server調用Servlet的destroy()方法。

Servlet生命週期的各個階段如圖5-6所示。

圖5-6 Servlet生命週期

【例5-2】Servlet的生命週期 

接下來將firstServlet.java示例代碼修改演示Servlet生命週期的各類方法的調用。

firstServlet2.java

package ch05;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

//Servlet生命週期演示

public class FirstServlet2 extends HttpServlet {

    private static final String CONTENT_TYPE = "text/html; charset=GBK";

    private String user;

    //讀取初始化參數    

    public void init() throws ServletException {

        super.init();        

        user=this.getServletConfig().getInitParameter("user");

        System.out.println("Servlet已經成功初始化");

    }

    //處理HTTP請求

    protected void service(HttpServletRequest request, HttpServletResponse response) throws

           ServletException, IOException {

       response.setContentType(CONTENT_TYPE);

       PrintWriter out = response.getWriter();

       out.println("<html>");

       out.println("<head><title>FirstServlet</title></head>");

       out.println("<body bgcolor=\"#ffffff\">");

       out.println("<H1>加載後初始化參數user="+user+"</H1>");

       out.println("</body>");

       out.println("</html>");

       out.close();

       System.out.println("Servlet的service方法被執行了一次");

   }

    //清除資源

    public void destroy() {

        System.out.println("Servlet實例已經被釋放");

    }

}

firstServlet2加載並實例化後init()方法讀取web.xml中初始化參數並在系統控制檯輸出「Servlet已經成功初始化」的信息;service()方法接受客戶端的請求在響應中輸出init()方法中讀取的初始化參數值隨後在系統控制檯輸出「Servlet的service()方法被執行了一次」;容器在銷燬Servlet實例以前會調用destroy()方法,destroy()方法給了Servlet機會,來清除所持有的資源(好比內存,文件處理和線程),本例僅僅是在系統控制檯輸出「Servlet實例已經被釋放」。

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee_

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

  <display-name>ch05</display-name>

  <servlet>

    <servlet-name>firstservlet</servlet-name>

    <servlet-class>ch05.FirstServlet</servlet-class>

  </servlet>

  <servlet-mapping>

    <servlet-name>firstservlet</servlet-name>

    <url-pattern>/firstservlet</url-pattern>

  </servlet-mapping>

  <!--Servlet生命週期示例-->

  <servlet>

    <servlet-name>firstservlet2</servlet-name>

    <servlet-class>ch05.FirstServlet2</servlet-class>

    <!--定義初始化參數-->

    <init-param>

      <param-name>user</param-name>

      <param-value>jspdev</param-value>

    </init-param>

  </servlet>

  <servlet-mapping>

    <servlet-name>firstservlet2</servlet-name>

    <url-pattern>/firstservlet2</url-pattern>

  </servlet-mapping>

</web-app>

firstServlet2的執行結果如圖 5-7所示。

圖5-7   firstServlet2的執行結果

多點擊幾回「刷新」或按「F5」鍵並中止應用服務器,系統控制檯顯示結果如圖 5-8所示。

圖5-8 FirstServlet2運行時在系統控制檯輸出

能夠看到建立Servlet實例並初始化(init()方法)只在第一次調用Servlet時執行,之後反覆調用僅僅只執行service()方法。中止應用服務器(Tomcat)則調用了destroy()方法。

【專家提示】Servlet生命週期徹底由Servlet容器掌握,當Servlet容器沒有限定一個加載的Servlet能保存多長時間,所以,一個Servlet實例可能只在Servlet容器中存活幾毫秒,或是其餘更長的任意時間。所以示例中咱們採用了中止Tomcat應用服務器的方式來測試destroy()方法。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

Servlet與表單交互

 

表單是HTML中使用最普遍的傳遞信息的手段。能使用Servlet與表單的交互,就在客戶端與服務器之間架起了一座橋樑。Servlet使用HttpServlet類中的方法與表單進行交互。在HttpServlet類中有幾個未徹底實現的方法,讀者能夠本身定義方法的內容,可是必須正確使用方法名稱以使HTTP Server把客戶請求正確的映射到相應的函數上。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

HTTP Servlet

 

HttpServlet做爲一個抽象類用來建立用戶本身的 HTTP Servlet。HttpServlet類擴展了GenericServlet類。HttpServlet類的子類必須至少重寫如下方法中一個:

doGet():由服務器調用來處理客戶端發出的GET請求。經過GenericServlet類的service()方法來調用此方法。重寫GET方法還支持HTTP HEAD請求,該請求返回沒有主體只標題字段的響應。提交響應以前,Servlet容器要編寫標題,這是由於在HTTP中必須在發送響應主體以前發送標題。GET方法必須是安全的,若是客戶端請求更改存儲的數據,則必須使用其餘的HTTP方法。若是請求的格式不正確,則doGet()方法返回HTTP「請求錯誤」消息。doGet()方法的語法爲:

public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException

其中,request是存儲客戶端請求的HttpServletRequest對象;response是包含服務器對客戶端做出響應的HttpServletResponse對象。

doPost():服務器調用以容許Servlet處理客戶端發出的POST請求。經過GenericServlet類的service()方法來調用此方法。HTTP POST方法用於經過Internet發送大量數據。提交響應以前,Servlet容器要編寫標題,這是由於在HTTP中必須在發送響應主體以前發送標題。若是HTTP POST請求格式不正確,則doPost()方法會返回HTTP「請求錯誤」消息。doPost()方法的語法爲:

public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException

其中,request是存儲客戶端請求的HttpServletRequest對象;response是包含服務器對客戶端做出響應的HttpServletResponse對象。

doHeader()用於處理HEADER請求。

doPut()用於處理PUT請求。

doDelete()用於處理DELETE請求。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

HttpServletRequest和HttpServletResponse

 

HttpServletRequest接口

HttpServletRequest接口擴展ServletRequest接口並向HTTP Servlet提供信息。Servlet容器建立HttpServletRequest實現對象,並將其做爲參數傳遞給Servlet的service()方法(service()方法再傳遞給doGet(),doPost()等)。

HttpServletRequest接口的經常使用方法以下。

getInputStream():返回客戶端請求中的二進制數據,並將其存儲在ServletInputStream對象中。

getParameter(String name):用於獲取隨請求信息一塊兒發送的請求參數。

getContentLength():返回客戶端發送的請求的實際長度,若是長度未知,則返回-1。

getMethod():返回用做出請求的HTTP方法的名稱,如GET和POST。

HttpServletResponse接口

HttpServletResponse接口擴展ServletResponse接口,用於幫助向客戶端發送響應。HttpServletResponse實現對象在建立後會做爲參數傳遞至service()方法。

HttpServletResponse接口的經常使用方法以下。

getOutputStream():返回一個ServletOutputStream對象,它被用來向客戶端發送二進制數據響應。

getWriter():返回將字符文本發送到客戶端的PrintWriter類的對象。

setContentLength(int len):容許設置將做爲響應發送的數據的長度。

【例5-3】Servlet與表單交互數據

接下來將在一個Servlet中演示對GET請求和POST請求的不一樣處理。

formServlet.java

package ch05;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

public class FormServlet extends HttpServlet {

    private static final String CONTENT_TYPE = "text/html; charset=GBK";

    //初始化

    public void init() throws ServletException {

    }

    //處理HTTP的GET請求

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws

            ServletException, IOException {

        response.setContentType(CONTENT_TYPE);

        PrintWriter out = response.getWriter();

        out.println("<html>");

        out.println("<head><title>FormServlet</title></head>");

        out.println("<body bgcolor=\"#ffffff\">");

        out.println("<h3>GET請求被處理</h3>");

        out.println("<form method='post' action=''>");

        out.println("姓名:<input name='name' type='text'/><br>");

        out.println("年齡:<input name='age' type='text'/><br>");

        out.println("<input  type='submit' value='提交'/><br>");

        out.println("</form>");

        out.println("</body>");

        out.println("</html>");

        out.close();

    }

    //處理HTTP的POST請求

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws

            ServletException, IOException {

        response.setContentType(CONTENT_TYPE);

       PrintWriter out = response.getWriter();

       request.setCharacterEncoding("GBK");

       String name=request.getParameter("name");

       String age=request.getParameter("age");

       out.println("<html>");

       out.println("<head><title>FormServlet</title></head>");

       out.println("<body bgcolor=\"#ffffff\">");

       out.println("<h3>POST請求被處理</h3>");

       out.println("姓名:"+name+"<br>");

        out.println("年齡:"+age+"<br>");

       out.println("</body>");

       out.println("</html>");

       out.close();

    }

    //Clean up resources

    public void destroy() {

    }

}

formServlet對GET請求的處理時,生成一個HTML表單網頁並指定的提交請求數據方式是POST方式,並再次向formServlet提交請求。對POST請求的處理時,接收請求參數顯示HTML網頁。

圖5-9 FormServlet對GET請求的處理

 

圖5-10 FormServlet對POST請求的處理

經過示例咱們能夠看到對於同一個Servlet對GET和POST請求的不一樣的處理方式。

【思考1】爲何程序中覆蓋doGet()和doPost()等方法而不覆蓋service()方法?

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

小結

 

Servlet是容許運行在服務器上的Java代碼,能響應用戶的請求生成動態的內容;運行Servlet必須提供一個Servlet容器;Servlet API主要包含在兩個包中,分別爲javax.servlet和javax.servlet.http;經過繼承GenericServlet抽象類或HttpServlet抽象類,能夠編寫Servlet。

Servlet的生命週期由Servlet容器徹底掌控,Servlet接口定義了Servlet生命週期的3個方法,分別爲init()、service()和destroy()。

繼承HttpServlet抽象類的Servlet必須覆蓋以下至少一個方法:doGet()、doPost()、doPut()、doDelete()、destroy()和getServletInfo()。

 
 
 
 

第 5 章:Servlet開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

思考解答

 

【思考1】爲何程序中覆蓋doGet()和doPost()等方法而不覆蓋service()方法?

答:當服務器接收到對 servlet 的請求時,服務器會產生一個新的線程調用 service()方法。Service()方法檢查HTTP請求類型(GET、POST、PUT、DELETE 等)而後相應的調用doGet()、doPost()、doPut()、doDelete()等方法。若是servlet處理POST請求和GET請求方式相同,也能夠嘗試覆蓋service()方法。但這樣作並不理想,更好的作法在 doPost()方法中調用doGet()(或者反過來)。這種方法代碼稍多了一些,但相比直接覆蓋 service()方法它有幾個優勢:

1.這樣作確保您之後能夠在子類中添加對其餘請求服務的支持,如doPut()、doTrace() 等。若是您直接覆蓋了service()方法則就沒有了這種可能性。 

2.您能夠經過實現getLastModified()方法來增長對修改日期的支持。若是您調用了 doGet()方法,標準service()方法會用getLastModified()方法設置header的最後修改日期而後對GET請求做出迴應(包括以修改過的 header,If-Modified-Since header)。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

什麼是JavaBean

 

第6章  JavaBean開發

【本章專家知識導學】

JavaBean是JSP開發中一種重要的組件開發技術,JSP程序員須要學會用JavaBean來封裝各類程序中的處理邏輯,以提升程序的可複用程度和可讀性,並學會在JSP頁面中使用JavaBean組件。

本章從JavaBean的基本概念講起,詳細講解了如何開發JavaBean,包括如何編寫、編譯、部署和使用JavaBean。

6.1  什麼是JavaBean

能夠把JavaBean簡單地理解爲一個Java類,這個類中封裝了一段能夠重複使用的Java代碼。Sun公司把JavaBean定義爲一個可重複使用的軟件組件。爲了方便使用,JavaBean每每被設計成是具備特定功能的,如生成一個數據庫鏈接的JavaBean類、表明網上商場購物車的JavaBean類、計算某些複雜數字運算公式的類等。

JavaBean有兩種,一種是帶有可視化界面的JavBean,如表明窗口界面中的按鈕的類、代碼窗口界面中的下拉框的類等;另外一種中沒有可視代界面的JavaBean,在Web開發者常使用後者,由於Web系統的界面經過HTML、CSS等技術結合已能完成,集成顯示在瀏覽器,配合以JavaScript語言還能夠實現許多的特效,這比窗口界面的可視化應用程序界面具備更加豐富的表現力。

在Web開發中,使用JavaBean能夠把各類程序邏輯功能與頁面分離開來,以在Web頁面中儘可能少地出現Java代碼,而大量的Java代碼封裝於JavaBean中,這樣程序的可讀性更強,可維護性也會更好一些,大多數狀況下,修改代碼只需修改JavaBean代碼,而沒必要在冗長的Web頁面中去尋找Java代碼。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

如何開發JavaBean

 

本節中學習開發JavaBean時所必須掌握的幾個關鍵步驟時要用到的方法與技術:如何編寫JavaBean,如何編譯JavaBean,如何打包和解包jar文件,如何部署JavaBean類和jar文件,以及如何在JSP頁面中使用JavaBean。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

編寫JavaBean

 

編寫JavaBean,其實質上就是寫一個Java類的源代碼,所以能夠使用許多的編輯工做來編寫,最簡單的就是使用記事本了。爲了方便編寫、調試、編譯程序,筆者推薦使用Java IDE開發工具,如Eclipse、Jbuilder。在Eclipse中編寫JavaBean時,編寫了屬性後,能夠用嚮導方面爲JavaBean類的屬性生成getXxxx()和setXxxx()方法的代碼,以下降手工書寫代碼出錯的可能性;保存了JavaBean類後,Eclipse能爲程序員自動編譯類(固然這須要在Eclipse環境中做出設置),生成.class字節碼文件,這樣,程序員就沒必要再書寫複雜的javac編譯指令了。

JavaBean既然是一個類,那麼它固然也就可以有屬性和方法,編寫JavaBean所要作的工做就是書寫屬性和方法的源代碼。書寫時程序員須要遵循以下的規則:

(1)屬性的get()與set()方法

屬性名爲xxxx,則相應的獲得屬性值和設置屬性值的方法爲getXxxx()和setXxxx(),方法名中屬性名的第一個字母爲大寫,具體形式以下:

public 屬性數據類型 getXxxx()

public void setXxxx(屬性數據類型 data)

參數data是設置賦與屬性的值。

若是屬性數據類型爲布爾型,則形式以下:

public boolean isXxxx()

public boolean getXxxx()

public void setXxxx(boolean data)

isXxxx()方法和getXxxx()方法用於獲得屬性的值,setXxxx()方法用設置屬性的值。

(2)訪問屬性的方法都設爲public,即公有方法;若是有構造函數,則方法也爲public型。

然而,以上2個規則並非嚴格的,好比設置成員屬性的值也並不必定要使用setXxxx()方法,讀者也能夠自行編寫方法,在調用JavaBean注意使用就好了。所以,程序員也能夠依本身的喜愛來編寫程序,不過遵循這2個規則將給其它程序帶來一些方便。好比在使用<jsp:setProperty>指令來設置JavaBean的屬性值,默認狀況下就是調用的setXxxx()方法,使用<jsp:setProperty>指令來獲得JavaBean的屬性值時,默認狀況下就是調用的getXxxx()方法。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

編譯JavaBean

 

編譯JavaBean的方法和編譯一個Java類的方法相同,使用javac命令。若是使用Eclipse這樣的Java IDE開發工具,Eclipse還能爲程序員自動編譯JavaBean,其實Eclipse也是使用的javac命令來完成編譯工做的。

打開「命令與提示符工具」(在Windows 9x/2000/XP中是在【開始】→【程序】→【附件】選項中),再切換到保存JavaBean類源文件(擴展名爲.java)的目錄下,輸入以下命令:

javac 源文件名.java

若是編譯經過就會在和JavaBean類源文件同一目錄下生成同名的.class文件。

javac是一個編譯工具,在JDK安裝目錄的bin子目錄下有javac.exe文件,它是這個編譯器的執行文件,也能夠帶一些參數來使用,形式以下:

javac [編譯時的選項] 源文件名.java

「[]」中的內容表示可選項,也就是說編譯時的選項無關緊要。經常使用的編譯時的選項有以下一些:

(1)-classpath path。設定編譯時須要用到的Java類文件的路徑,若是在系統變量CLASSPATH中已有則沒必要給出,參數path是類文件的路徑。

(2)-d directory。設定編譯生成的.class文件輸入到哪個目錄。一般狀況下,javac把生成的 .class文件放在 .java文件所在的目錄中;若是使用-d參數,則能夠指定javac將生成的 .class文件在其餘目錄中;參數directory是要放入的目錄。

(3)-g。此選項在代碼產生器中打開調試表,之後可憑此調試產生的字節代碼。

(4)-nowarn。此選項禁止編譯器產生警告。

(5)-o。告訴javac優化由內聯的static、final以及privite成員函數所產生的代碼。

(6)-verbose。告知Java顯示出有關被編譯的源文件和任何被調用類庫的信息。

最爲經常使用的是第1項和第2項,設定要用到的類和class文件輸出的路徑。

【例6-1】編譯一個簡單的JavaBean

編寫一個JavaBean類,源代碼以下:

book.java

package bean;

/**

 * @author dengziyun

 */

public class book {

public long bookId;//書籍ID號

public String bookName;//書名

public String bookAbstract;//書的內容簡介

public String bookAuthor;//書的做者

public String bookPublisher;//書的出版社

public float bookPrice;//書的價格

/**

* @return Returns the bookAuthor.

*/

public String getBookAuthor() {

return bookAuthor;

}

/**

* @param bookAuthor The bookAuthor to set.

*/

public void setBookAuthor(String bookAuthor) {

this.bookAuthor = new String(bookAuthor);

}

/**

* @return Returns the bookId.

*/

public long getBookId() {

return bookId;

}

/**

* @param bookId The bookId to set.

*/

public void setBookId(long bookId) {

this.bookId = bookId;

}

/**

* @return Returns the bookName.

*/

public String getBookName() {

return bookName;

}

/**

* @param bookName The bookName to set.

*/

public void setBookName(String bookName) {

this.bookName = new String(bookName);

}

/**

* @return Returns the bookPublisher.

*/

public String getBookPublisher() {

return bookPublisher;

}

/**

* @param bookPublisher The bookPublisher to set.

*/

public void setBookPublisher(String bookPublisher) {

this.bookPublisher = new String(bookPublisher);

}

/**

* @return Returns the bookAbstract.

*/

public String getBookAbstract() {

return bookAbstract;

}

/**

* @param bookAbstract The bookAbstract to set.

*/

public void setBookAbstract(String bookAbstract) {

this.bookAbstract = new String(bookAbstract);

}

/**

* @return Returns the bookPrice.

*/

public float getBookPrice() {

return bookPrice;

}

/**

* @param bookPrice The bookPrice to set.

*/

public void setBookPrice(float bookPrice) {

this.bookPrice = bookPrice;

}

}

這個類爲書籍類,他的一個對象表明一本書。book類有6個屬性,bookId爲書籍的ID號,bookName爲書名,bookAbstract爲書的內容簡介,bookAuthor爲做者名稱,bookPublisher爲出版社名稱,bookPrice爲書的價格。這個類比較常見的用處就是在在線書店系統中,用來表明書籍,封裝數據庫中的書籍表的記錄。

針對書籍類的每個屬性都有相應的getXxxx()方法和setXxxx()方法,以便於JSP頁面在使用JavaBean時,能夠直接設置JavaBean的屬性。

進入命令窗口,將當前目錄切換到Java源文件所在的目錄,本處爲「D:\eclipse\workspace\javabean\src\bean」。若是系統變量PATH中沒有設置JDK的bin目錄,請加入。本例中設置JDK的bin目錄到PATH變量中的命令爲:

set path=%path%;d:\jdk5\bin

使用「%path%;」的目的是爲了避免影響PATH變量中原有的設置;本處由於JDK1.5安裝在「d:\jdk5」目錄中,故設置的路徑爲「d:\jdk5\bin」,讀者須要根據本身機器上的安裝狀況改變這個設置。

【專家提示】在命令窗口中設置變量PATH的值,並不會影響到系統變量的值,而只是對當前窗口中的對話在效,一旦窗口關閉即會失效,所以建議讀者把JDK的bin目錄設置到系統變量PATH中。設置系統變量能夠經過「個人電腦」「屬性」對話框中的「系統變量」選項卡來設置。

再用以下的命令編譯book.java:

javac book.java

【專家提示】book.java屬於bean包,在Java中包對應着操做系統的一個目錄,編譯時,須要把當前目錄切換到book.java所在的目錄,即Java源文件所在最底層的包的目錄。

編譯的狀況如圖6-1所示。

圖6-1    編譯book.java

從圖6-1也能夠看出,在book.java源文件的同一目錄下生成了編譯後的字節碼文件book.class。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

打包和解包jar文件

 

當編寫的類較多時,程序員經常會把類按功能類型,或按類與類之間的緊密程度,把屬於同一功能模塊或互相之間調用關係比較緊密的類放在同一個包中,若是類的體系比較龐大,還會將包再分紅若干個層次,造成一個樹形的架構,這就象操做系統文件夾的結構,事實上類的源代碼和編譯後的字節碼文件最終的表現形式也就是操做系統的文件夾結構,按包的層次進行組織。

若是在一個Web系統中須要引用許多個類,若是要將這些類一一配置到系統變量CLASSPATH中,要麼是CLASSPATH變量的配置參數值會至關冗長,且程序員要做的工做量也比較大,稍一不慎還會出錯。爲此,能夠考慮將全部要用到的類打成一個jar文件(或稱爲jar包),再在CLASSPATH中引用這個jar文件,就能夠使用這個jar文件中的全部類了。

那麼jar文件究竟是什麼呢?一個jar文件是一個壓縮包,能夠包含一組類及其相關的資源,甚至是聲音和圖像文件,把這些文件組成統一的一個文件——jar文件。有了jar文件,其中包含的類就沒必要一個一個地部署,能夠做爲一個jar文件一次部署,也能夠在網上方便下載,由於下載一個文件比下載多個文件方便得多。

將資源打包成jar文件的jar工具使用語法以下:

jar 打包時的選項 [打包後的jar文件名稱.jar] 要打包的文件

打包時的選項比較經常使用的有:

c——建立一個新的存檔文件。

f——文件列表中第一個文件的名稱爲要建立的或要訪問的包文件的名稱。

m——文件列表中的第一個文件是外部清單文件名。

t——jar文件的內容應制成表格。

u——更新已存在的jar文件。

v——當jar工具執行時顯示詳細信息。

X——從jar文件中展開文件。

這些選項能夠組合使用,如cvf。

「要打包的文件」參數中能夠使用通配符,若是是全部文件用「*」,若是是以JPEG爲擴展的則用*.JPEG。若是要將當前目錄下的全部.class文件打包成class.jar,可以使用以下的命令:

jar cf class.jar *.class

jar工具也能夠用於將jar文件解包。列出class.jar包中的文件命令以下:

jar tf class.jar

展開class.jar文件,並釋放在當前目錄下:

jar xf class.jar

除了jar工具之外,還有一種簡便的方法能夠將資源打包成jar文件,以及將jar文件解包,那就是使用WinRar或WinZip這樣的解壓縮工具。

將資源打包成jar文件的方法是:用WinRar或WinZip將資源打包成.zip壓縮文件,或將.zip文件的擴展名改成.jar。

將jar文件解包的方法是:將jar文件的擴展名改成.zip,再用WinRar或WinZip解壓縮。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

部署JavaBean類

 

部署JavaBean編譯後的.class文件,須要先考慮這個JavaBean是要讓Web站點中的全部Web應用都可以使用,仍是讓Web站點中的某一個Web應用可以使用,二者的部署方法不一樣。

若是要讓Web站點中的全部Web應用都可以使用,應當把類文件拷貝到Tomcat5安裝目錄的「common/classes」目錄中,若是類屬於某個包則應當把整個包都拷貝過去。

若是僅僅是想讓Web站點中的某一個Web應用可以使用,則應當把類文件拷貝到這個Web應用的「WEB-INF/classes」(注意區分大小寫)目錄中,「WEB-INF」是每一個Web應用都必需要有的子目錄。若是類屬於某個包則應當把整個包都拷貝過去。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

部署jar文件

 

與部署JavaBean相似,部署jar文件一樣有兩種狀況,一種是對Web服務器中的JSP頁面都有效;另外一種僅對當前應用有效。

若是要讓Web服務器中全部的JSP頁面均可以使用要部署的jar文件,則能夠把打包後的jar文件拷貝到Tomcat 5安裝目錄的「common/lib」或「lib」子目錄下,但須要重啓Tomcat服務器。這樣無需做出配置,JSP頁面便可使用這個jar文件了。

若是隻對當前的應用有效,則須在當前應用的WEB-INF子目錄中創建一個新的子目錄lib,並把jar文件拷貝過來。

【專家提示】其實,並沒必要把jar文件拷貝到這些指定的目錄中,也能夠是放在Web服務器中的任意以外,但必須在CLASSPATH系統變量中引用。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

在JSP中使用JavaBean

 

部署好JavaBean後就能夠JSP中使用了。要在JSP頁面中使用JavaBean,首先要用<%@page%>指令引入要使用到的類。如,要使用本章前文中編譯後的book類,可以使用以下的<%@page%>指令:

<%@page import="bean.book"%>

其中,book是要導入的類名,若是還有包,可在類名前加包名,形如「包名.類名」。

導入後便可以JSP頁面中的Java代碼中使用這個JavaBean類了。

JSP提供了指令標籤useBean簡單而又方便地使用JavaBean。這個指令標籤的語法以下:

<jsp:useBean id="給JavaBean實例取的名稱" class="Bean類名" 

scope="JavaBean實例的有效範圍"></jsp:useBean>   

<jsp:useBean id="給JavaBean實例取的名稱" class="JavaBean類名" 

scope=" JavaBean實例的有效範圍"/>

其中,id的設置可由用戶任意給定;class爲JavaBean類名,若是類之上還有包,則此參數用形如「包名.類名」的形式;scope有四種不一樣的取值範圍,分別解說以下:

scope設爲page,表示分配給每一個客戶的JavaBean不一樣,有效範圍僅對當前的JSP頁面有效,若是關閉此JSP頁面,相應的分配給此客戶的JavaBean將被取消。

scope設爲session表示分配給每一個客戶的JavaBean不一樣,但在同一個客戶打開的多個JSP頁面,即一次會話其間,是同一個JavaBean。若是在同一客戶的不一樣JSP頁面中聲明瞭相同id的JavaBean,且範圍仍爲scope,若更改此JavaBean的成員變量值,其餘頁面中此id的Bean的成員變量值也會被改變。當客戶打開服務器上的全部網頁都被關閉時,對應客戶的這一次會話中的JavaBean也被取消。

scope設爲request表示分配給每一個客戶的JavaBean不一樣,且有效範圍在request期間,即在請求與被請求頁面之間共享JavaBean。當對請求做出響應後,JavaBean就會被取消。

scope設爲application表示在服務器的全部客戶之間共享JavaBean。當一個客戶改變了成員變量的值時,另外一個客戶的此JavaBean的同一個成員變量值也會被改變。當服務器關閉時JavaBean纔會被取消。

【例6-2】使用JavaBean

假設前面編寫的類book位於包javabean下,經編譯經過後已按本節中部署class文件或部署jar文件的方法部署好,再來看在JSP頁面中如何使用它。

useBeanBook.jsp

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="bean.book"%>

<html>

<head>

<title>第一個JSP頁面</title>

</head>

<body>

<%//------用jsp:useBean指令使用JavaBean------

out.println("用jsp:userBean指令使用JavaBean<hr>");

%>

<jsp:useBean id="csaiBookZYS" class="bean.book" scope="page">

<jsp:setProperty name="csaiBookZYS" property="bookId" value="2"/>

<jsp:setProperty name="csaiBookZYS" 

property="bookName" value="系統分析師技術指南"/>

<jsp:setProperty name="csaiBookZYS" 

property="bookAuthor" value="張友生"/>

<jsp:setProperty name="csaiBookZYS" 

property="bookPublisher" value="清華大學出版社"/>

<jsp:setProperty name="csaiBookZYS" 

property="bookPrice" value="45"/>

</jsp:useBean>

<%

    out.println("書籍ID號:"+csaiBookZYS.bookId+"<br>"); 

    out.println("書名:"+csaiBookZYS.bookName+"<br>");

    out.println("做者:"+csaiBookZYS.bookAuthor+"<br>");

    out.println("出版社:"+csaiBookZYS.bookPublisher+"<br>");

    out.println("訂價:"+csaiBookZYS.bookPrice);  

%>

<jsp:getProperty name="csaiBookZYS" property="bookPrice"/>

<%//------在Java程序片中使用JavaBean------

    book csaiBookDZY=new book();

    csaiBookDZY.bookId=1;

    csaiBookDZY.bookName="精通J2EE網絡編程";

    csaiBookDZY.bookAuthor="鄧子云"; 

    csaiBookDZY.bookPublisher="清華大學出版社"; 

    csaiBookDZY.bookPrice=49; 

    out.println("<br>在Java程序片中使用JavaBean");

    out.println("<hr>書籍ID號:"+csaiBookDZY.bookId+"<br>"); 

    out.println("書名:"+csaiBookDZY.bookName+"<br>");

    out.println("做者:"+csaiBookDZY.bookAuthor+"<br>");

    out.println("出版社:"+csaiBookDZY.bookPublisher+"<br>");

    out.println("訂價:"+csaiBookDZY.bookPrice+"<br>");  

%>

</body>

</html>

程序的運行效果如圖6-2所示。

圖6-2    使用JavaBean

程序中經過兩種方法來使用JavaBean,一種是經過<jsp:useBean>指令來使用;另外一種是直接在Java程序片中使用。爲了減小Java代碼量,建議程序員儘可能使用JSP指令,以加強JSP頁面中代碼的可讀性。

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

設置與獲得JavaBean的屬性

 

從例6-2能夠看出,使用setXxxx()方法和getXxxx()方法能設置和獲得JavaBean的屬性值,也能夠用動做標籤setProperty與getProperty來修改與獲取JavaBean的屬性值。

getProperty標籤得到JavaBean的屬性值,並將這個屬性值以字符串的形式顯示出來。getProperty的使用語法格式以下:

<jsp:getProperty name="JavaBean的名稱" property="JavaBean屬性的名稱"/>

<jsp:getProperty name="JavaBean的名稱" property="JavaBean屬性的名稱">

<jsp:getProperty>

setProperty標籤設置JavaBean的屬性值用於設置JavaBean的屬性值。setProperty標籤的使用語法有以下4種:

<jsp:setProperty name="bean的名稱" property="*"/>

<jsp:setProperty name="bean的名稱" property="屬性名稱"/>

<jsp:setProperty name="bean的名稱" property="屬性名稱" param="參數名稱"/>

<jsp:setProperty name="bean的名稱" property="屬性名稱" value="屬性值"/>

在第一種語法格式中,property="*",應用這種格式要求bean屬性的名稱與類型要和request對象中參數名稱與類型一致,以此用bean中的屬性來接收客戶輸入的數據,系統會根據名稱來自動匹配。若是類型不一致,會根據bean中的類型進行轉換。第二種語法格式則只設置其中匹配的一個bean的屬性。第三種語法格式根據指定的reaquest對象中的參數與屬性匹配。第四種語法格式用來給bean的屬性賦值,屬性值的數據類型要與屬性的數據類型一致,不然程序會出錯,所以要進行數據類型的轉換。

setProperty動做指令能夠在useBean動做指令中使用,也可在聲明瞭useBean後使用,但不能在聲明以前使用。與userBean動做指令結合使用的語法格式以下:

<jsp:useBean id="bean的名稱" scope="有效範圍" class="包名.類名">

    <jsp:setProperty name="bean的名稱" property="屬性名稱" value="屬性值"/>

    … …

    <jsp:setProperty name="bean的名稱" property="屬性名稱" value="屬性值"/>

</jsp:useBean>

【專家提示】因爲用戶輸入的數據每每不規範,數據類型的轉換可能會出錯,所以在程序中要及時捕獲並報告錯誤,以加強程序的健壯性。

【專家提示】在同一個setProperty動做指令中不能同時存在param和value參數。

還一種方法,能夠經過表單來設置JavaBean的屬性值,但這種方法要求HTML表單輸入項的名字要與JavaBean屬性的名字相同,這樣服務器引擎會自動進行匹配把字符串轉換爲相應JavaBean屬性的數據類型數據。使用以下的語法格式:

<jsp:getProperty name="JavaBean的名稱" property="*"/>

【例6-3】用HTML表單設置JavaBean的屬性值

htmlJavaBean.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%!

public String codeToString(String str){//處理中文字符串的函數

String s=str;

  try{

    byte tempB[]=s.getBytes("ISO-8859-1");

    s=new String(tempB);

    return s;

  }catch(Exception e){

    return s;

  }  

}

%>

<jsp:useBean id="csaiBookZYS" class="bean.book" scope="page">

</jsp:useBean>

<jsp:setProperty name="csaiBookZYS" property="*"/>

<html>

<head>

<title>用HTML表單設置JavaBean的屬性</title>

</head>

<body>

<div align="center">

  <center>

<%

    out.println("書籍ID號:"+csaiBookZYS.bookId+"<br>"); 

    out.println("書名:"+codeToString(csaiBookZYS.bookName)+"<br>");

    out.println("做者:"+codeToString(csaiBookZYS.bookAuthor)+"<br>");

    out.println("出版社:"+codeToString(csaiBookZYS.bookPublisher)+"<br>");

    out.println("訂價:"+csaiBookZYS.bookPrice);  

%>

  <table border="1" width="46%">

  <form name="form1" action="" method="post">

    <tr>

      <td width="44%">請輸入書籍ID號:</td>

      <td width="56%"> <input type="text" name="bookId" size="20"></td>

    </tr>

    <tr>

      <td width="44%">請輸入書名:</td>

      <td width="56%"> <input type="text" name="bookName" size="20"></td>

    </tr>

    <tr>

      <td width="44%">請輸入做者名字:</td>

      <td width="56%"> <input type="text" name="bookAuthor" size="20"></td>

    </tr>

    <tr>

      <td width="44%">請輸入出版社名稱:</td>

      <td width="56%"> <input type="text" name="bookPublisher" size="20"></td>

    </tr>

    <tr>

      <td width="44%">請輸入此書的訂價:</td>

      <td width="56%"> <input type="text" name="bookPrice" size="20"></td>

    </tr>

    <tr>

      <td width="100%" colspan="2">

        <p align="center"><input type="submit" name="T1" size="20" value="提交">

                <input type="reset" name="T1" size="20" value="重置"> </td>

    </tr>

    </form>

  </table>

  </center>

</div>

</body>

</html>

程序中,表單的action屬性值爲空,表示數據提交到本頁面。表單中的輸入框的名稱與JavaBean屬性的名稱一一對應起來了,所以能夠只用以下的一句語句便可將提交過來的數據設置爲JavaBean的屬性值:

<jsp:setProperty name="csaiBookZYS" property="*"/>

程序的運行結果如圖6-3所示。

圖6-3    用HTML表單設置JavaBean的屬性值

<jsp:setProperty name="csaiBookZYS" property="*"/>語句也能夠改成以下的5句,效果相同:

<jsp:setProperty name="csaiBookZYS" property="bookId" param="bookId"/>

<jsp:setProperty name="csaiBookZYS" property="bookName" param="bookName"/>

<jsp:setProperty name="csaiBookZYS" property="bookAuthor" param="bookAuthor"/>

<jsp:setProperty name="csaiBookZYS" 

property="bookPublisher" param="bookPublisher"/>

<jsp:setProperty name="csaiBookZYS" property="bookPrice" param="bookPrice"/>

 
 
 
 

第 6 章:JavaBean開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

小結

 

JavaBean是一個可重複使用的軟件組件,能夠用來執行復雜的計算任務,或負責與數據庫的交互以及數據提取等。Java中有兩種JavaBean,便可視化和非可視化JavaBean,在JSP中通常使用後者。

編寫JavaBean其實質上就是編寫一個Java類,編寫屬性和方法。編譯JavaBean用javac命令。若是類比較多,可分類用包存放,交能夠打包成jar文件,打包和解包jar方便使用jar命令。

使用JavaBean也就是使用一個Java類,能夠用<%@page import%>語句導入這個類後,便可在Java代碼塊中使用,也能用<jsp:useBean>標籤來使用,再經過<jsp:setProperty>標籤和<jsp:getProperty>標籤設置和獲得JavaBean的屬性值。

 

第7章 Web方式上傳與下載文件

【本章專家知識導學】

Web應用程序常常要進行文件的上傳、下載操做。能夠使用Java I/O流自定義完成文件操做的類,也能夠使用專業的第三方上傳、下載組件。使用Java I/O流自定義完成文件操做的類,程序代碼多,設計複雜;而使用專業的上傳、下載組件,程序代碼短小,編制簡單。經常使用的文件操做組件有jspSmartUpload、FileUpload。

經過本章的學習,要掌握使用jspSmartUpload組件進行文件上傳、下載操做方法和使用FileUpload組件進行文件上傳操做的方法。

7.1 文件操做組件介紹

jspSmartUpload是一款免費、開源的文件上傳下載組件,能夠從以下的網站下載獲得:

http:// www.jspsmart.com

jspSmartUpload適合於在JSP文件中嵌入式實現文件的上傳和下載功能。該組件有如下幾個特色:

1.使用簡單。在JSP文件中僅僅書寫三五行Java代碼就能夠完成文件的上傳或下載,程序員使用方便、快捷。 

2.能全程控制上傳。利用jspSmartUpload組件提供的對象及其操做方法,能夠得到所有上傳文件的信息(包括文件名、大小、類型、擴展名、文件數據等),方便存取。

3.能對上傳的文件尺寸大小、類型等方面作出限制,能夠過濾掉不符合要求的文件。

4.下載靈功能活。只須要寫少許的代碼,就能把Web服務器當成是文件服務器來使用,不論文件是在Web應用的目錄下仍是在Web服務器的其它任何目錄下,均可以利用jspSmartUpload進行下載。

FileUpload也是一款免費開源的可實現文件上傳功能的組件,能夠從以下的網站下載獲得:

http://jakarta.apache.org

Commons是Apache開放源代碼組織中的一個Java子項目,該項目主要涉及一些開發中經常使用的模塊,例如文件上傳、命令行處理、數據庫鏈接池、XML配置文件處理等。這些項目集合了來自世界各地軟件工程師的心血,其性能、穩定性等方面都能經實際應用的考驗,有效地利用這些項目將會給開發帶來顯而易見的效果。FileUpload就是其中用來處理HTTP文件上傳的子項目。

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

jspSmartUpload組件的安裝與配置

 

下載獲得jspSmartUpload組件後,壓縮包的名字是jspSmartUpload.zip,將文件名更改成jspSmartUpload.jar(若是下載獲得的是jspSmartUpload.jar則無需更改)。Tomcat對文件名大小寫敏感,它要求Web應用程序相關的jar組件包所在目錄爲「WEB-INF/lib」。

將jspSmartUpload.jar文件拷貝到所須要使用jspSmartUpload組件的Web應用的「WEB-INF/lib」,便可以在這個Web應用的JSP文件中使用jspSmartUpload組件了。

【注意】按上述方法安裝後,只有當前Web應用下的程序能夠使用jspSmartUpload組件,若是想讓Web服務器的全部Web應用程序都能用它,則應當將jspSmartUpload.jar文件拷貝到Tomcat安裝目錄的「shared/lib」目錄下。

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

jspSmartUpload組件的主要對象

 

1.File類 

這個類包裝了一個上傳文件的全部信息。經過它,能夠獲得上傳文件的文件名、文件大小、擴展名、文件數據等信息。 

File類主要提供如下方法:

(1)saveAs()

方法原型:

public void saveAs(java.lang.String destFilePathName)  或

public void saveAs(java.lang.String destFilePathName, int optionSaveAs) 

其中destFilePathName是另存的文件名,optionSaveAs是另存的選項,該選項有三個值,分別是SAVEAS_PHYSICAL,SAVEAS_VIRTUAL,SAVEAS_AUTO。SAVEAS_PHYSICAL代表以操做系統的根目錄爲文件根目錄另存文件,SAVEAS_VIRTUAL代表以Web應用程序的根目錄爲文件根目錄另存文件,SAVEAS_AUTO則表示讓組件決定,當Web應用程序的根目錄存在另存文件的目錄時,它會選擇SAVEAS_VIRTUAL,不然會選擇SAVEAS_PHYSICAL。

例如,saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)執行後若Web服務器安裝在C盤,則另存的文件名實際是c:\upload\sample.zip。saveAs("/upload/sample.zip",_

SAVEAS_VIRTUAL)執行後若Web應用程序的根目錄是「webapps/jspsmartupload」則另存的文件名實際是「webapps/jspsmartupload/upload/sample.zip」。saveAs("/upload/sample.zip",SAVEAS_AUTO)執行時若Web應用程序根目錄下存在upload目錄,則其效果同saveAs("/upload/sample.zip",SAVEAS_VIRTUAL),不然同saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)。

對於Web程序的開發來講,最好使用SAVEAS_VIRTUAL,以便於程序的移植。

(2)isMissing()

isMissing()方法用於判斷用戶是否選擇了文件,也即對應的表單項是否有值。選擇了文件時,它返回false。未選文件時,它返回true。方法原型:

public boolean isMissing()

(3)getFieldName()

getFieldName()方法用於獲取HTML表單中對應於此上傳文件的表單項的名字。 方法原型:

public String getFieldName() 

(4)getFileName()

getFileName()方法用於獲取文件名(不含目錄信息)。方法原型:

public String getFileName() 

(5)getFilePathName()

getFilePathName()方法用於獲取文件全稱(帶路徑)。方法原型:

public String getFilePathName 

(6)getFileExt() 

getFileExt()方法用於獲取文件擴展名(後綴)。方法原型:

public String getFileExt() 

(7)getSize()

getSize()方法用於獲取文件長度,長度以字節計。方法原型:

public int getSize() 

(8)getBinaryData() 

getBinaryData()方法用於獲取文件數據中指定位移處的一個字節,用於檢測文件等。方法原型:

public byte getBinaryData(int index)

其中,index表示位移,其值在0到getSize()-1之間。

2. Files類

這個類表示全部上傳文件的集合,經過它能夠獲得上傳文件的數目、大小等信息。主要有如下方法:

(1)getCount()

getCount()方法可用於取得上傳文件的數目。方法原型:

public int getCount() 

(2)getFile()

getFile()方法可用於取得指定位移處的文件對象File(這是com.jspsmart.upload.File,不是java.io.File,注意區分)。方法原型:

public File getFile(int index)。

其中index爲指定位移,其值在0到getCount()-1之間。 

  (3)getSize()

   getSize()方法可得到上傳文件的總長度,可用於限制一次性上傳的數據量大小。方法原型:

public long getSize() 

  (4)getCollection()

   getCollection()方法用於將全部上傳文件對象以Collection的形式返回,以便其它應用程序引用,瀏覽上傳文件信息。方法原型:

public Collection getCollection() 

  (5)getEnumeration()

   getEnumeration()方法用於將全部上傳文件對象以Enumeration(枚舉)的形式返回,以便其它應用程序瀏覽上傳文件的信息。方法原型:

public Enumeration getEnumeration() 

3. Request類 

  Request類的功能等同於JSP內置的對象request。只因此提供這個類,是由於對於文件上傳表單,經過request對象沒法得到表單項的值,必須經過jspSmartUpload組件提供的Request對象來獲取。該類提供以下方法: 

  (1)getParameter()

   getParameter()方法用於獲取指定參數之值,若是指定的參數不存在,返回值爲null。 方法原型:

public String getParameter(String name)

其中name爲參數的名字。 

  (2)getParameterValues()

  當一個參數能夠有多個值時,用getParameterValues()方法來取其值,getParameterValues()方法返回的是一個字符串數組若是指定的參數不存在,返回值爲null。 方法原型以下:

public String[] getParameterValues(String name)。其中,name爲參數的名字。 

  (3)getParameterNames()

   getParameterNames()方法用於取得Request對象中全部參數的名字,經過返回的枚舉類型數據能夠遍歷全部參數。方法原型:

public Enumeration getParameterNames()

4.SmartUpload類

SmartUpload類用於完成上傳下載工做,它的主要方法以下。 

(1)initialize()

initialize()方法是上傳與下載時共用的方法,用於執行上傳下載的初始化工做,必須第一個被執行。方法原型(有多個,主要使用下面這個): 

public final void initialize(javax.servlet.jsp.PageContext pageContext) 

其中pageContext爲JSP頁面內置對象(頁面上下文)。 

(2)upload()

upload()方法用於上傳文件數據。通常地,上傳操做第一步執行initialize方法,第二步就是執行upload()方法。方法原型:

public void upload() 

  (2)save()

save()方法用於將所有上傳文件保存到指定目錄下,並返回保存的文件個數。 方法原型:

public int save(String destPathName)   或

public int save(String destPathName,int option) 

其中destPathName爲文件保存目錄,option爲保存選項,它有三個值,分別是SAVE_PHYSICAL,SAVE_VIRTUAL和SAVE_AUTO。(同File類的saveAs方法的選項之值相似)SAVE_PHYSICAL指示組件將文件保存到以操做系統根目錄爲文件根目錄的目錄下,SAVE_VIRTUAL指示組件將文件保存到以Web應用程序根目錄爲文件根目錄的目錄下,而SAVE_AUTO則表示由組件自動選擇。 

【專家提示】save(destPathName)做用等同於save(destPathName,SAVE_AUTO)。 

(3)getSize() 

getSize()方法用於獲取上傳文件數據的總長度。方法原型:

public int getSize() 

(4)getFiles()

getFiles()方法用於獲取所有上傳文件,以Files對象形式返回,能夠利用Files類的操做方法來得到上傳文件的數目等信息。方法原型:

public Files getFiles() 

  (5)getRequest()

   getRequest()方法用於取得Request對象,以便由此對象得到上傳表單參數之值。 方法原型:

public Request getRequest() 

  (6)setAllowedFilesList()

   setAllowedFilesList()方法用於設定容許上傳帶有指定擴展名的文件,當上傳過程當中有文件名不容許時,組件將拋出異常。方法原型:

   public void setAllowedFilesList(String allowedFilesList) 

  其中allowedFilesList爲容許上傳的文件擴展名列表,各個擴展名之間以逗號分隔。若是想容許上傳那些沒有擴展名的文件,能夠用兩個逗號表示。例如:setAllowedFilesList("doc,txt,,")將容許上傳帶doc和txt擴展名的文件以及沒有擴展名的文件。 

  (7)setDeniedFilesList()

   setDeniedFilesList()方法用於限制上傳那些帶有指定擴展名的文件。如有文件擴展名被限制,則上傳時組件將拋出異常。方法原型:

   public void setDeniedFilesList(String deniedFilesList) 

  其中deniedFilesList爲禁止上傳的文件擴展名列表,各個擴展名之間以逗號分隔。若是想禁止上傳那些沒有擴展名的文件,能夠用兩個逗號來表示。例如:setDeniedFilesList("exe,bat,,")將禁止上傳帶exe和bat擴展名的文件以及沒有擴展名的文件。 

  (8)setMaxFileSize()

   setMaxFileSize()方法用於設定每一個文件容許上傳的最大長度。方法原型:

public void setMaxFileSize(long maxFileSize) 

  其中maxFileSize爲爲每一個文件容許上傳的最大長度,當文件超出此長度時,將不被上傳。 

  (9)setTotalMaxFileSize() 

   setTotalMaxFileSize()方法用於設定容許上傳的文件的總長度,以限制一次性上傳的數據量大小。方法原型: 

  public void setTotalMaxFileSize(long totalMaxFileSize) 

  其中totalMaxFileSize爲容許上傳的文件的總長度。 

  (10)setContentDisposition()

 setContentDisposition()方法用於將數據追加到MIME文件頭的CONTENT-DISPOSITION域。jspSmartUpload組件會在返回下載的信息時自動填寫MIME文件頭的CONTENT-DISPOSITION域,若是用戶須要添加額外信息,請用此方法。方法原型:

  public void setContentDisposition(String contentDisposition) 

  其中contentDisposition爲要添加的數據。若是contentDisposition爲null,則組件將自動添加「attachment;」,以代表將下載的文件做爲附件,結果是IE瀏覽器將會提示另存文件,而不是自動打開這個文件(IE瀏覽器通常根據下載的文件擴展名決定執行什麼操做,擴展名爲doc的將用word程序打開,擴展名爲pdf的將用acrobat程序打開,等等)。             

(11)downloadFile()  

downloadFile()方法用於下載文件,共有如下三個原型可用,第一個最經常使用,後兩個用於特殊狀況下的文件下載(如更改內容類型,更改另存的文件名)。

①public void downloadFile(String sourceFilePathName)

其中sourceFilePathName爲要下載的文件名(帶目錄的文件全名) 

②public void downloadFile(String sourceFilePathName,String contentType)

其中sourceFilePathName爲要下載的文件名(帶目錄的文件全名),contentType爲內容類型(MIME格式的文件類型信息,可被瀏覽器識別)。 

③public void downloadFile(String sourceFilePathName,String contentType,String destFileName) 

其中sourceFilePathName爲要下載的文件名(帶目錄的文件全名),contentType爲內容類型(MIME格式的文件類型信息,可被瀏覽器識別),destFileName爲下載後默認的另存文件名。

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

FileUpload組件的安裝與配置

 

下載獲得FileUpload組件安裝包後,解壓獲得的zip包。將commons-fileupload.jar複製到要使用該組件的Web應用程序的「WEB-INF\lib」目錄下。

【注意】按上述方法安裝後,只有使用該組件的Web應用程序能夠使用FileUpload組件,若是想讓Tomcat服務器的全部Web應用程序都能用它,應當將commons-fileupload.jar拷貝到Tomcat的shared/lib目錄下。

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

文件上傳處理

 

本節中將分別介紹如何利用jspSmartUpload組件和FileUpload組件上傳文件。

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

利用jspSmartUpload組件進行文件上傳處理

 

下面經過三個實例來演示jspSmartUpload組件如何進行文件上傳處理操做。

【例7-1】jspSmartUpload簡單文件上傳

下面的web應用中,將實現一次能夠上傳三個文件到服務器上的功能。在JSP頁面上的表單中放置三個文件上傳域,【瀏覽…】按鈕用來選擇要上傳的文件,當選擇好文件後按【上傳】按鈕,就能夠將文件上傳至服務器upload目錄下。當完成上傳操做之後,服務器提示成功上傳多少個文件。

首先編寫提供文件選擇對話框的HTML頁面7-1.html中的代碼。

7-1.html

<HTML>

<HEAD>

<TITLE>例 7-1 jspSmartUpload 基本文件上傳</TITLE>

</HEAD>

<BODY BGCOLOR="white">

<HR>

<FORM METHOD="POST" ACTION="/jspsmartupload/7-1.jsp" ENCTYPE="multipart/form-data">

   <INPUT TYPE="FILE" NAME="FILE1" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE2" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE3" SIZE="50"><BR>

   <BR>

   <INPUT TYPE="SUBMIT" VALUE="上傳">

</FORM>

</BODY>

</HTML>

   【專家提示】凡是要上傳文件的表單都必須設置enctype屬性,且屬性值必須是「multipart/form-data」,同時method屬性必須設爲POST。

7-1.html的執行結果如圖7-1所示

圖7-1  7-1.html運行界面

接下來定義7-1.jsp來處理程序,7-1.jsp調用jspSmartUpload組件完成文件的上傳。

7-1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page language="java" import="com.jspsmart.upload.*"%>

<jsp:useBean id="mySmartUpload" scope="page" class="com.jspsmart.upload.SmartUpload" />

<HTML>

<HEAD>

<TITLE>例 7-1  jspSmartUpload 基本文件上傳</TITLE>

</HEAD>

<BODY BGCOLOR="white">

<HR>

<%

// 聲明變量count,用來存儲上傳文件個數

int count=0;        

    // 執行初始化操做

mySmartUpload.initialize(pageContext);

    //設定上傳文件最大字節數

mySmartUpload.setTotalMaxFileSize(100000);

// 上傳文件到服務器

mySmartUpload.upload();

try {

/*調用SmartUpload方法的save方法保存上傳文件。存儲時以文件原有名稱存儲。

尋找存儲路徑首先看當前web應用程序下是否存在upload目錄,若是有,則直接存儲在該目錄;不然,尋找web服務器所在驅動器物理路徑下是否存在upload目錄,若是有,則存儲,若是沒有,則會拋出異常。*/

count = mySmartUpload.save("/upload");

// 顯示上傳文件數量

out.println(count + "個文件已經上傳.");

    } catch (Exception e){ 

out.println(e.toString());

    }

%>

</BODY>

</HTML>    

 在執行後,選擇文件,單擊【上傳】按鈕,當上傳成功顯示確認頁面,如圖7-2所示。

圖7-2  上傳確認頁面

假設Tomcat5.5安裝在D盤根目錄下,

7-1.html和7-1.jsp都部署在D:\Tomcat5.5\webpass\jspsmartupload下, 

jspSmartUpload.jar部署在D:\Tomcat5.5\webpass\jspsmartupload\WEB-INF\lib下。

若是 (如:D:\Tomcat5.5\webpass\jspsmartupload)以及Web服務器所在的物理路徑(如D:\)都不存在upload目錄,則拋出異常,如圖7-3所示。

圖7-3 存儲路徑不存在致使的異常

    有時不但要上傳文件,並且還要顯示上傳文件信息。顯示上件文件信息,能夠經過File類的一些方法來得到。例如getFileName( )能夠獲得不帶目錄的文件名,getFilePathName()能夠獲得帶目錄的文件名,getFileExt()能夠獲得文件的擴展名,getsize()能夠獲得文件長度信息。接下來咱們看一個既能上傳文件,又能獲得文件信息的Web程序。

【例7-2】jspSmartUpload上傳文件,並顯示上傳文件信息

   首先定義文件選擇頁面7-2.html

7-2 .html

<HTML>

<TITLE>

jspSmartUpload 上傳文件,並顯示上傳文件信息

</TITLE>

<BODY BGCOLOR="white">

<HR>

<FORM METHOD="POST" ACTION="/jspsmartupload/7-2.jsp" 

ENCTYPE="multipart/form-data">

   <INPUT TYPE="FILE" NAME="FILE1" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE2" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE3" SIZE="50"><BR>

   <BR>

   <INPUT TYPE="SUBMIT" VALUE="上傳">

</FORM>

</BODY>

</HTML>

7-2.html的執行結果如圖7-4所示

圖7-4  7-2.html 的執行結果

接下來定義文件上傳處理程序7-2.jsp。

7-2.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page language="java" import="com.jspsmart.upload.*"%>

<jsp:useBean id="mySmartUpload" scope="page" class="com.jspsmart.upload.SmartUpload" />

<HTML>

<TITLE>

例7-2 jspSmartUpload 上傳文件,並顯示上傳文件信息

</TITLE>

<BODY BGCOLOR="white">

<TABLE BORDER=1  bordercolor="Black">

<TR><TD WIDTH="100">文件名</TD><TD WIDTH="50">擴展名</TD> 

    <TD WIDTH="100"> 長度</TD> <TD WIDTH="300"> 帶路徑的文件名</TD> </TR>

  <%

// 聲明變量count,用來存儲上傳文件個數

int   count=0;        

// 執行初始化操做

    mySmartUpload.initialize(pageContext);

// 上傳文件到服務器

mySmartUpload.upload();

// 對上傳到服務器的文件進行逐個處理

for (int i=0;i<mySmartUpload.getFiles().getCount();i++)

         {

         // 取出一個文件

   com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(i);

    // 只有myFile表明的文件存在時才執行存儲操做

   if (!myFile.isMissing()) {

        // 保存該文件到web應用程序下的upload目錄       

myFile.saveAs("/upload/" + myFile.getFileName());

  %>

              <TR><TD WIDTH="100"><%=myFile.getFileName()%> </TD>

              <TD WIDTH="50"><%=myFile.getFileExt()%></TD>

              <TD WIDTH="100"><%=myFile.getSize()%> </TD> 

              <TD WIDTH="300"><%=myFile.getFilePathName()%></TD> </TR>

  <%       

             //成功上傳文件計數

             count++;

           }

}

%>

</TABLE>

<%

     // 顯示能被上傳的文件數目

     out.println("<BR>"+mySmartUpload.getFiles().getCount()+"個文件 能被上傳.<BR>");

     // 顯示成功上傳的文件數目 

     out.println(count + " 個文件 已成功上傳.");

%>

</BODY>

</HTML>

獲得的上傳信息如圖7-5所示

圖7-5 上傳文件,並顯示文件信息

在網站中文件上傳已是經常使用的功能了,考慮到網絡的傳輸速度等緣由,多數狀況上傳的文件不該該很大,這就須要對用戶上傳文件的大小和類型進行限制。jspSmartUpload組件SmartUpload類提供了有效的方法來解決這些問題。例如:設置容許上傳文件的大小限制用setMaxFileSize()方法,容許上傳指定的帶有指定擴展名的文件用setAllowedFilesList(String allowedFilesList)方法,不容許上傳帶有擴展名的文件用setDeniedFilesList(String allowedFilesList)方法。接下來看一個利用jspSmartUpload上傳文件,並對上傳文件進行限制的Web程序。

【例7-3】jspSmartUpload上傳文件,並對上傳文件進行限制

7-3.html

<HTML>

<TITLE>

例7-3 jspSmartUpload 上傳文件,並對上傳的文件進行限制

</TITLE>

<BODY BGCOLOR="white">

<HR>

<FORM METHOD="POST" ACTION="/jspsmartupload/7-3.jsp"

 ENCTYPE="multipart/form-data">

   <INPUT TYPE="FILE" NAME="FILE1" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE2" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE3" SIZE="50"><BR>

   <BR>

   <INPUT TYPE="SUBMIT" VALUE="上傳">

</FORM>

</BODY>

</HTML>

 7-3.html執行結果如圖7-6所示

圖7-6  7-3.html執行結果

接下來定義7-3.jsp處理程序

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page language="java" import="com.jspsmart.upload.*"%>

<jsp:useBean id="mySmartUpload" 

scope="page" class="com.jspsmart.upload.SmartUpload" />

<HTML>

<TITLE>

例7-3 jspSmartUpload 上傳文件,並對上傳的文件進行限制

</TITLE>

<BODY BGCOLOR="white">

<HR>

<%

 int count=0;        

 mySmartUpload.initialize(pageContext);

 // 只容許上傳htm/html/txt/bmp/gif/mp3類型文件

 mySmartUpload.setAllowedFilesList("htm,html,txt,bmp,gif,mp3,,");

 //設置不容許上傳的文件類型exe/bat/zip

      // mySmartUpload.setDeniedFilesList("exe,bat,zip");

 //設置容許上傳文件的大小限制

 // mySmartUpload.setMaxFileSize(50000);

  mySmartUpload.upload();

      //在服務器的上傳目錄中使用原始文件名保存文件

  try {

count = mySmartUpload.save("/upload", mySmartUpload.SAVE_VIRTUAL);

  } catch (Exception e){

out.println("<b>錯誤信息 : </b>" + e.toString());

  }

  //顯示成功上傳的文件數目

  out.println(count + " 個文件 己經成功上傳。");

%>

</BODY>

</HTML>

當按指定類型(htm/html/txt/bmp/gif/mp3類型)上傳文件時,獲得的上傳處理信息,如圖7-7所示。

圖7-7 上傳文件成功信息

當不按指定類型(禁止exe/bat/zip類型)上傳文件時,就會拋出異常信息,如圖7-7所示。

圖7-7 拋出異常信息

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

利用FileUpload組件進行文件上傳處理

 

FileUpload組件將頁面提交的全部元素(普通form表單域,如text和文件域file)都看做同樣的FileItem,這樣上傳頁面提交的request請求也就是一個FileItem的有序組合,FileUpload組件能夠解析該request,並返回一個的FileItem。而對每個FileItem,FileUpload組件能夠判斷出它是普通form表單域仍是文件file域,從而根據不一樣的類型,採起不一樣的操做:若是是普通的表單域,就讀出其值,若是是文件域,就保存文件到服務器硬盤上或者內存中。

本小節將經過兩個實例,演示FileUpload組件的用法。

【例7-4】利用apachefileupload組件進行文件上傳 

7-4.html

<HTML>

<TITLE>

例7-4  apachefileupload 上傳文件

</TITLE>

<BODY BGCOLOR="white">

<HR>

<FORM METHOD="POST" ACTION="/apachefileupload/7-4.jsp" 

ENCTYPE="multipart/form-data">

   <INPUT TYPE="FILE" NAME="FILE1" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE2" SIZE="50"><BR>

   <INPUT TYPE="FILE" NAME="FILE3" SIZE="50"><BR>

   <BR>

   <INPUT TYPE="SUBMIT" VALUE="上傳">

</FORM>

</BODY>

</HTML>

【注意】必須保證表單的ENCTYPE屬性值爲multipart/form-data,這樣瀏覽器才能正確執行上傳文件的操做。

7-4.html執行結果如圖7-8所示

圖7-8  7-4.html執行結果

接下來編寫7-4.jsp處理程序。首先建立一個DiskFileUpload對象,經過它來解析請求。執行解析後,全部的表單都保存在一個List中。而後經過循環依次得到List裏的FieldItem對象。

7-4.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="org.apache.commons.fileupload.*"%>

<%@ page import="java.util.*"%>

<%@ page import="java.io.*"%>

<HTML>

<TITLE>例7-4  apachefileupload 上傳文件</TITLE>

<BODY BGCOLOR="white">

<% 

try {

        //建立一個DiskFileUpload對象,經過它來解析請求

        DiskFileUpload fu = new DiskFileUpload();        

        // 獲得全部的文件:

        List fileItems = fu.parseRequest(request);

%>

<TABLE BORDER=1  bordercolor="Black">

<TR><TD WIDTH="500">文件名</TD><TD WIDTH="100">文件長度</TD>   </TR>

<%

        Iterator i = fileItems.iterator();

        // 依次處理每個文件:

        while(i.hasNext()){

            FileItem fi = (FileItem)i.next();

            // 得到文件名,這個文件名包括路徑:

            String fileName = fi.getName();

          if(fileName!=null && fileName.length()!=0) {

                File fullFile = new File(fi.getName());              

                    File savedFile =

 new File(application.getRealPath("/")+"/uploadfiles",_

fullFile.getName());

                fi.write(savedFile);              

%>

               <TR><TD WIDTH="500"><%=fi.getName()%> </TD>

              <TD WIDTH="100"><%=fi.getSize()%></TD> </TR>

<%     

             }

        }

%>

</TABLE>

<%       

   out.println("己經成功上傳" );

    }

    catch(Exception e) {

        e.printStackTrace();       

        out.println(e.getMessage());

    }

%>

</BODY>

</HTML>

7-4.jsp執行後頁面所如圖7-9所示。

圖7-9 7-4.jsp執行後頁面

【例7-5】利用apachefileupload組件進行文件上傳,並對上傳文件進限制。

7-5.html

<HTML>

<TITLE>

例7-5  apachefileupload 上傳文件,並對上傳文件進行限制

</TITLE>

<BODY BGCOLOR="white">

<HR>

<FORM METHOD="POST" ACTION="/apachefileupload/7-5.jsp"

 ENCTYPE="multipart/form-data">

   <INPUT TYPE="FILE" NAME="FILE1" SIZE="50"><BR>

   <INPUT TYPE="SUBMIT" VALUE="上傳">

</FORM>

</BODY>

</HTML>

7-5.hmtl執行結果如所圖7-10所示

圖7-10 7-5.hmtl執行結果

接下來編寫7-5.jsp處理程序:處理程序首先檢查服務器目錄,是否有upload目錄,如沒有就建立;而後檢查unload目錄是否有tmp目錄,如沒有就建立;接下來就是進行上傳操做。

7-5.jsp

<HTML>

<TITLE>

例7-5  apachefileupload 上傳文件,並對上傳文件進行限制

</TITLE>

</HTML>

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="org.apache.commons.fileupload.*"%>

<%@ page import="java.util.*"%>

<%@ page import="java.io.*"%>

<%

      File uploadPath=new File("c:\\upload");//上傳文件目錄

      if(!uploadPath.exists()){

           uploadPath.mkdirs();

       }

       String tempPath="c:\\upload\\tmp\\"; // 臨時文件目錄

       File tempPathFile=new File("c:\\upload\\tmp");

       if(!tempPathFile.exists()){

           tempPathFile.mkdirs();

      }

try {

        DiskFileUpload fu = new DiskFileUpload();

        // 設置最大文件尺寸 1MB

        fu.setSizeMax(10485760);

        // 設置緩衝區大小,這裏是4KB

        fu.setSizeThreshold(4096);

        // 設置臨時目錄:

        fu.setRepositoryPath(tempPath);

        // 獲得全部的文件:

        List fileItems = fu.parseRequest(request);

        Iterator i = fileItems.iterator();

        // 依次處理每個文件:

        while(i.hasNext()) {

            FileItem fi = (FileItem)i.next();

            // 得到文件名,這個文件名包括路徑:

            String fileName = fi.getName();

            if(fileName!=null) {

                File fullFile = new File(fi.getName());

                File savedFile = new File(uploadPath ,fullFile.getName());

                fi.write(savedFile);              

            }

        }

       out.println("文件已經成功上傳");

    }

    catch(Exception e) {

        out.println(e.getMessage());

    }

%>

7-5.jsp處理程序上傳文件成功提示頁面以下圖7-11所示。

圖7-11 7-5.jsp 文件上傳成功提示頁面

當文件違反限制進行上傳時,處理程序會出現提示頁面如圖7-12所示。

圖7-12 7-5.jsp 文件違反限制上傳時出現的提示頁面

在這個文件中須要注意的是FileUpload對象的一些參數值的意義,以下面代碼所示的三個參數sizeMax、sizeThreshold、repositoryPath:

// 設置容許用戶上傳文件大小,單位:字節

fu.setSizeMax(104857600);

// 設置最多隻容許在內存中存儲的數據,單位:字節

fu.setSizeThreshold(4096);

// 設置一旦文件大小超過getSizeThreshold()的值時數據存放在硬盤的目錄

fu.setRepositoryPath(tempPath);

這3個參數的意義分別爲: 

sizeMax:用來設置上傳文件大小的最大值,一旦用戶上傳的文件大小超過該值時將會拋出一個FileUploadException異常,提示文件太大; 

sizeThreshold:設置內存中緩衝區的大小,一旦文件的大小超過該值的時候,程序會自動將其它數據存放在repositoryPath指定的目錄下做爲緩衝。合理設置該參數的值能夠保證服務器穩定高效的運行; 

repositoryPath:指定緩衝區目錄。 

【專家提示】從實際應用的狀況來看要想上傳文件的程序可以穩定高效的工做,其中參數SizeThreshold的值相當重要,設置太大會佔用過多的內存,設置過小會頻繁使用硬盤做爲緩衝以至犧牲性能。所以,設置該值時要根據用戶上傳文件大小分佈狀況來設定。例如大部分文件大小集中在100KB左右,則能夠使用100KB做爲該參數的值,固然了再大就不太合適了。

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

文件下載處理

 

jspSmartUpload組件提供上傳和下載功能,而FileUpload組件只提供上傳功能。下面這個例子演示了利用jspSmartUpload組件進行文件下載操做。

【例7-7】利用 jspSmartUpload下載文件 

首先編寫下載頁面7-7.html中的代碼,該文件連接到下載處理程序7-7.jsp。

7-7.html

<HTML>

<TITLE>

例7-7 jspSmartUpload 下載文件

</TITLE>

<BODY BGCOLOR="white">

<HR>

<A HREF="/jspsmartupload/7-7.jsp"> readme.txt 下載</A>

</BODY>

</HTML>

7-7.html執行結果如圖7-13所示 

圖7-13  7-7.html執行結果

接下來編寫7-7.jsp處理程序

7-7.jsp

<jsp:useBean id="mySmartUpload"

 scope="page" class="com.jspsmart.upload.SmartUpload" /><%

mySmartUpload.initialize(pageContext);

// 設定contentDisposition爲null以禁止瀏覽器自動打開文件,

//保證點擊連接後是下載文件。若不設定,則下載的文件擴展名爲txt時,直接在瀏覽器打開。

//文件類型爲doc時,瀏覽器將自動用word打開它。擴展名爲pdf時瀏覽器將用acrobat打開。

mySmartUpload.setContentDisposition(null);

// 下載文件

mySmartUpload.downloadFile("/upload/readme.txt");%>

 
 
 
 

第 7 章:Web方式上傳與下載文件做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

小結

 

本章主要講解了如何利用jspSmartUpload組件進行文件上傳、下載操做,如何利用FileUpload組件進行上傳操做。調用的jspSmartUpload和FileUpload這兩個組件的訪問頁面表單都必須設置enctype屬性,且屬性值必須是「multipart/form-data」,同時表單的method屬性值必須是POST。jspSmartUpload、 FileUpload組件均可以進行文件上傳和對上傳文件進行各類限制,但FileUpload組件不能進行文件下載操做。

 
 
 
 

第 8 章:JSP數據庫開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

JDBC概述

 

第8章  JSP數據庫開發

【本章專家知識導學】

在應用系統中將數據存入數據庫中最大的好處是能利用開發技術(如:JSP、ASP、PHP和Perl)對數據做出分析,並按照不一樣的需求而呈現出不一樣的內容。例如:許多網站所提供的個性化服務,搜索引擎,在線訂票應用等皆以數據庫做爲後端架構衍生出來的應用。

本章主要探討JDBC的架構與運做方式,讓讀者對JDBC有完整的基礎概念後,可以快速上手JSP與數據庫的運用,並介紹了一些數據庫操做時經常使用的技術,如使用存儲過程、使用事務處理等。

8.1  JDBC概述

JDBC(Java Database Connectivity)是Sun提供的一套數據庫編程標準API接口,由Java語言編寫的類、接口組成,其體系結構如圖8-1所示。

圖8-1 JDBC體系結構圖

用JDBC寫的程序可以自動地將SQL語句傳送給相應的數據庫管理系統。不但如此,使用Java編寫的應用程序能夠在任何支持Java的平臺上運行,沒必要在不一樣的平臺上編寫不一樣的應用。Java和JDBC的結合可讓開發人員在開發數據庫應用程序時真正實現「一次編寫,處處運行!」

鏈接數據庫有四種鏈接方式。第一種就是ODBC(Open Database Connection 開放式數據庫鏈接)橋鏈接:ODBC橋鏈接是經過操做系統裏面的數據源鏈接到各類不一樣的數據庫。絕大多數數據庫都支持操做系統裏面的數據源。也提供了相應的驅動程序。包括:SQL Server 2000,Oracle9i等等。在JAVA剛開始的時候,SUN公司提供了用於ODBC橋鏈接的驅動程序JDBC-ODBC橋驅動程序,它把JDBC的調用轉換爲ODBC操做。這個橋使得全部支持ODBC的DBMS均可以和Java應用程序交互,但僅適用於Windows平臺,適用於JDBC初學者。

圖8-2 JDBC-ODBC體系結構圖

第二種驅動程序也稱爲部分Java驅動程序(native-API partly-Java Driver),由於它們直接將JDBC API翻譯成具體數據庫的API。也就是本地庫Java驅動程序,將JDBC調用轉換爲對數據庫的客戶端API的調用。

圖8-3 JDBC本地驅動體系結構圖

第三種驅動程序是網絡驅動程序(net-protocol all-java driver(JDBC Proxy)),它將JDBC API轉換成獨立於數據庫的協議。JDBC驅動程序並無直接和數據庫進行通信;它和一箇中間件服務器通信,而後這個中間件服務器和數據庫進行通信。這種額外的中間層次提供了靈活性:能夠用相同的代碼訪問不一樣的數據庫,由於中間件服務器隱藏了Java應用程序的細節。

圖8-4 JDBC網絡驅動程序體系結構圖

第四種驅動程序是純Java驅動程序(native-protocal all-Java driver),它直接與數據庫進行通信。不少程序員認爲這是最好的驅動程序,由於它一般提供了最佳的性能,並容許開發者利用特定數據庫的功能。固然,這種緊密偶合會影響靈活性,特別是若是您須要改變應用程序中的底層數據庫時。這種驅動程序一般用於applet和其它高度分佈的應用程序。適用於企業應用,如圖8-5所示。

圖8-5 JDBC純Java驅動程序體系結構圖

 
 
 
 

第 8 章:JSP數據庫開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

Java編程語言和JDBC

 

編寫正確且遵照規範的Java程序,能夠無需從新編譯就在任何啓用Java技術的平臺上運行。Java編程語言完全地進行了規定。根據定義,啓用Java技術的平臺必須支持已知的核心庫。就java.sql包或javax.sql包或者JDBC就是這樣一個庫,它們能夠視爲ODBC的可移植版本,且其自己就是重大的標準。Java編程語言和JDBC一塊兒使用,能夠給編寫數據庫應用程序提供正確的可移植性解決方案。JDBC驅動程序就是JAVA類,它實現JDBC驅動程序接口,並能夠爲特別的數據庫轉換程序(通常是SQL)請求。無疑,驅動程序在這裏起了重要做用。大多數的數據庫供應商如今都提供驅動程序,以實現特定系統的JDBC API,這些驅動程序一般都是免費提供的。JDBC編程的核心包爲java.sql包,其結構如圖8-6所示。

圖8-6 java.sql包結構圖

 
 
 
 

第 8 章:JSP數據庫開發做者:鄧子云赫斌等    來源:希賽網    2014年03月04日

 

JDBC編程的步驟

 

第一步:加載驅動程序。

爲了與特定的數據庫相連,JDBC必須加載相應的驅動程序。如:

try {

//加載JDBC-ODBC驅動

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

如下是加載各類不一樣的數據庫驅動程序的方法:

//SQL Server

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

//MySQL

Class.forName("org.gjt.mm.mysql.Driver");

//Oracle

Class.forName("Oracle.jdbc.driver.OracleDriver");

//Informix

Class.forName("com.informix.jdbc.IfxDriver");

//Sybase

Class.forName("com.sybase.jdbc2.jdbc.SybDriver");

//AS400

Class.forName("com.ibm.as400.access.AS400JDBCConnection");

第二步:將「驅動程序」傳遞到DriverManager,而後得到「鏈接」。

DriverManager類的getConnection(String url,String user, String password)方法用於創建與某個數據庫的鏈接。每一個JDBC驅動程序使用一個專門的JDBC URL做爲自我標識的一種方法。

JDBC URL的格式爲:jdbc : <子協議名> : <子名稱> 

子協議(sub-protocol)與JDBC驅動程序有關,能夠是odbc,oracle,db2,mysql,microsoft等等,根據實際的JDBC驅動程序廠商而不一樣。子名稱(數據庫定位器)是與驅動程序有關的指示器,用於惟一指定應用程序要和哪一個數據庫進行交互。根據驅動程序的類型,該定位器可能包括主機名,端口和數據庫系統名。如下是鏈接語句示例:

try{

String url="jdbc:odbc:myodbc";

Connection con=DriverManager.getConnection(url);

// 或者

/*Connection con=DriverManager.getConnection(url,user,password);

}catch(SQLException e){

e.printStackTrace();

如下是鏈接各類不一樣的數據庫的URL編寫方法:

//SQL Server

DriverManager.("jdbc:microsoft:sqlserver://主機:端口號; DatabaseName=數據庫名","用戶名","密碼")

//MySQL

DriverManager.getConnection("jdbc:mysql://主機:端口號:數據庫名","用戶名","密碼")

//Oracle

DriverManager.getConnection("jdbc:Orcale:thin:@主機:端口號:數據庫名","用戶名","密碼")

//Informix

DriverManager.getConnection("jdbc:informix-sqli://主機:端口號/數據庫名:

INFORMIXSERVER=informix服務名","用戶名","密碼")

//Sybase

DriverManager.getConnection("jdbc:sybase:Tds:主機:端口號/數據庫名","用戶名","密碼")

//AS400

DriverManager.getConnection("jdbc:as400://主機」,"用戶名","密碼")}

第三步:建立語句,Statement ,PreparedStatement,或CallableStatement,並將它們用於更新數據庫或執行查詢。

Statement 對象用於將SQL語句發送到數據庫中。實際上有三種Statement對象,它們均可以做爲在給定鏈接上執行SQL語句的對象:Statement、PreparedStatement( 繼承Statement )和 CallableStatement(繼承PreparedStatement)。它們都專用於發送特定類型的 SQL 語句:Statement 對象用於執行不帶參數的簡單 SQL語句;PreparedStatement 對象用於執行帶或不帶 IN 參數的預編譯 SQL 語句;CallableStatement對象用於執行對數據庫已存儲過程的調用。

第四步:查詢並返回包含有已請求數據的ResultSet,該ResultSet是按類型檢索的。

ResultSet包含符合SQL語句中條件的全部行,而且它經過一套get方法(這些get方法能夠訪問當前行中的不一樣列)提供了對這些行中數據的訪問。DatabaseMetaData和ResultSetMetaData接口能夠用來提供有關數據庫或ResultSet的信息。

第五步:顯示數據或根據獲得的查詢結果完成業務邏輯處理。

第六步:最後關閉ResultSet(結果集)、Statement(語句對象)、Conection(數據庫鏈接)。

 

【例8-1】經過ODBC創建與數據庫的鏈接 

配置Windows下ODBC詳細步驟以下(以配置鏈接SQL Server 2000的pubs數據庫爲例):

(1)啓動SQL Server 2000數據庫。

從控制面板裏面找到數據源,如圖8-7所示。

圖8-7 準備建立ODBC數據源

打開數據源,創建鏈接SQLServer的數據源,建立界面如圖8-8所示。

圖8-8 建立ODBC數據源

選擇系統DSN,點擊 按鈕。出現圖8-9的界面,選擇「SQL Server」點擊完成,出現圖8-10的界面。

圖8-9 建立ODBC數據源

 

圖8-10 建立ODBC數據源

輸入數據源的名字,如:myodbc。在服務器裏面加個點,表示用本地機器上的SQL Server數據庫服務器。點擊下一步,顯示圖8-11所示的對話框。

圖8-11 建立ODBC數據源

選擇 ,輸入登錄數據庫使用的用戶名和密碼。這裏的用戶名和密碼是SQLServer裏面可用的用戶名和密碼。點擊下一步,顯示圖8-12所示的對話框。

圖8-12 建立ODBC數據源

選擇要訪問的數據庫,這點選擇pubs,點擊下一步,顯示圖8-13所示的對話框。

圖8-13 建立ODBC數據源

點擊完成,顯示圖 8-14所示的對話框。

圖8-14 建立ODBC數據源

測試數據源若是出現圖 8-15,說明數據源已經建立成功。

圖8-15 建立ODBC數據源

建立Web應用並編寫odbc_connection.jsp頁面,代碼以下。

odbc_connection.jsp

<%@ page language="java" contentType="text/html; charset=GBK"%>

<%@ page import="java.sql.*" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>    

    <title>經過ODBC創建鏈接</title>

  </head>  

  <body>

  <%

   Connection con = null;

try {

// 加載ODBC驅動

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

// 經過驅動管理器(DriverManager)得到鏈接

con = DriverManager.getConnection("jdbc:odbc:myodbc",

"sa","");

// 若是鏈接不成功,就會出現異常,不會執行下面這個語句

out.println("<H1>");

out.println("經過ODBC數據源鏈接數據庫成功!");

out.println("</H1>");

} catch (Exception e) {// 若是出現異常,會打印堆棧裏異常的信息

e.printStackTrace();

} finally {// 用完後,關閉鏈接,釋放資源

try {

if (con != null) // 防止出現內存泄露

con.close();

} catch (Exception e) {

e.printStackTrace();

}

}  

   %>    

  </body>

</html>

運行結顯示如圖8-16所示。

圖8-16 odbc_connection.jsp運行結果

【例8-2】經過SQLServer提供的驅動程序得到鏈接

SQL Server的驅動程序須要用到三個jar文件,它們分別爲:msbase.jar、mssqlserver.jar、msutil.jar,而後設置classpath環境變量指向這三個路徑。若是隻是當前Web應用須要使用,能夠將這三個jar文件拷貝到當前Web應用的「WEB-INF/lib」目錄下。

sqlserver_connection.jsp

<%@ page language="java" contentType="text/html; charset=GBK"%>

<%@ page import="java.sql.*" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>    

    <title>經過Sqlserver純驅動程序創建鏈接</title>

  </head>  

  <body>

  <%

   Connection con = null;

try {

// 加載SQLSERVER的驅動程序

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

// 經過驅動來得到一個鏈接

con = DriverManager.getConnection(

"jdbc:microsoft:sqlserver://localhost:1433;"

+ "databasename=pubs", "sa", "");

// 若是鏈接不成功,就會出現異常,不會執行下面這個語句

out.println("<H1>");

out.println("經過SQLServer純驅動程序鏈接數據庫成功!<br> con="+con);

out.println("</H1>");

} catch (Exception e) {// 若是出現異常,會打印堆棧裏異常的信息

e.printStackTrace();

} finally {// 用完後,關閉鏈接,釋放資源

try {

if (con != null) // 防止出現內存泄露

con.close();

} catch (Exception e) {

e.printStackTrace();

}

}  

   %>    

  </body>

</html>

運行結果顯示如圖 8-18所示。

圖8-18 SQLServer純Java驅動鏈接數據庫運行結果

【例8-3】經過Oracle提供的驅動程序得到鏈接

下面介紹如何經過Oracle提供的驅動程序得到鏈接。須要使用的只有一個jar文件:classes12.jar。設置環境變量classpath 指向該jar文件。若是隻是當前Web應用須要使用,能夠將這個jar文件拷貝到當前Web應用的「WEB-INF/lib」目錄下。

oracle_connection.jsp

<%@ page language="java" contentType="text/html; charset=GBK"%>

<%@ page import="java.sql.*" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>    

    <title>經過oracle純驅動程序創建鏈接</title>

  </head>  

  <body>

  <%

   Connection con = null;

try {

// 加載ORACLE9i的驅動程序

Class.forName("oracle.jdbc.driver.OracleDriver");

// 得到鏈接 oracle數據庫的端口號:1521 數據服務器的名字叫ora921

// 登錄的用戶名爲system,密碼爲:itjob (默認密碼爲manager)

con = DriverManager.getConnection(

"jdbc:oracle:thin:@127.0.0.1:1521:ora921", "system","itjob");

// 若是鏈接不成功,就會出現異常,不會執行下面這個語句

out.println("<H1>");

out.println("經過ora921純驅動程序鏈接數據庫成功!<br> con="+con);

out.println("</H1>");

} catch (Exception e) {// 若是出現異常,會打印堆棧裏異常的信息

e.printStackTrace();

} finally {// 用完後,關閉鏈接,釋放資源

try {

if (con != null) // 防止出現內存泄露

con.close();

} catch (Exception e) {

e.printStackTrace();

}

}  

   %>    

  </body>

</html>

運行結果顯示如圖 8-19所示。

圖8-19 Oracle純Java驅動鏈接數據庫運行結果

【專家提示】Oracle數據庫純Java驅動包並隨安裝Oracle數據庫或客戶端一同安裝,讀者能夠從〔Oracle安裝目錄〕\ jdbc\lib下找到相應的驅動包。

【專家提示】細心的讀者會發現咱們在演示這個例子時瀏覽器的URL顯示爲:

http://localhost:8088/jdbcdemo/oracle_connection.jsp

顯然咱們將Tomcat的默認HTTP端口8080改成8088了,這是由於咱們在本機啓動了Oracle數據庫服務佔用了8080端口。讀者能夠經過運行netstat –a –b –o命令來查看機器端口占用狀況,如圖 8-20所示。

圖8-20 本機端口被佔用狀況

能夠看到8080端口被Oracle數據庫的監聽服務進程TNSLSNR.exe進程所佔用。

【例8-4】經過鏈接池得到鏈接

首先請讀者根據在上面建立數據庫鏈接的經驗,來思考下列問題:

爲何須要鏈接池?

什麼是鏈接池?

如何初始化鏈接池?

如何使用鏈接池?

當使用DriverManager方法來獲取數據庫鏈接時,每一個對新數據庫鏈接的請求都會致使很大的開銷。若是頻繁地獲取新的鏈接,將會影響性能問題。這在Web服務器端編程的時候尤其明顯。請求一個新的Connection對象會帶來大量的開銷和不少潛在的錯誤。爲了最小化開銷,爲何在咱們使用完數據庫鏈接後不是從新使用它們,而是刪除它們呢?JDBC設計者在建立接口ConnectionPoolDataSource時使用這種流行的設計模式,這容許您建立數據庫鏈接池,其中的鏈接在關閉後能夠重用,而不是刪除。

PooledConnection是一個特殊類型的數據庫鏈接,在關閉時不會被刪除,不象常規的Connection對象(當常規的鏈接再也不被使用時,垃圾收集器能刪除它們)。相反,PooledConnection被緩存以備未來再次使用,從而可能帶來大幅度的性能提高。

配置Tomcat5數據庫鏈接池

目前幾乎全部的應用服務器都支持數據庫鏈接池的建立和管理,接下來咱們將具體演示Tomcat中SQLServer數據庫鏈接池的建立和管理步驟。

首先在你要使用鏈接池的Web應用的META-INF目錄下建立一個context.xml文件,如圖8-21所示。

圖8-21 建立一個context.xml文件

啓動Tomcat5後進入Tomcat歡迎頁面,如圖8-21所示。

圖8-22 Tomcat歡迎頁面

點擊「Tomcat Administration」進入Tomcat的管理員登陸頁面,如圖8-22所示。

圖8-23 Tomcat管理員登陸頁面

輸入用戶名 admin 密碼 (安裝時指定若是忘記了能夠打開{Tomcat安裝目錄}\conf\ tomcat-users.xml文件查看)後點擊Login按鈕進入管理配置頁面如圖8-23所示。

圖8-24 Tomcat管理配置頁面

選擇jdbcdemo web應用程序下的Data Sources選擇Create New Data Source建立一個新的數據源,如圖 8-24所示。 

圖8-25 Tomcat數據鏈接池管理配置頁面

填寫以下參數:

JNDI Name:jdbc/sqlserver(未來以此來查找數據庫鏈接池)。

Data Source URL(數據源URL):

jdbc:microsoft:sqlserver://localhost:1433;databasename=pubs

User Name:sa

Vaildation Query:select 1

而後點擊Save按鈕保存數據庫鏈接池的設置,如圖 8-25所示。

圖8-26 Tomcat數據鏈接池管理配置頁面

點擊「Commit Changes」按鈕向服務器提交設置。

圖8-27 Tomcat數據鏈接池管理配置頁面

點擊肯定按鈕完成配置

pool_connection.jsp

<%@ page language="java" contentType="text/html; charset=GBK"%>

<%@ page import="java.sql.*,javax.naming.*,javax.sql.*" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>    

    <title>經過數據庫鏈接池創建鏈接</title>

  </head>  

  <body>

  <%

   Connection con = null;

try {

Context initContext = new InitialContext();

Context envContext  = (Context)initContext.lookup("java:/comp/env");

DataSource ds = (DataSource)envContext.lookup("jdbc/sqlserver");

con = ds.getConnection();

out.println("<H1>");

out.println("第一次經過數據庫鏈接池鏈接數據庫成功!<br> con="+con);

out.println("</H1>");

con.close();

con = ds.getConnection();

out.println("<H1>");

out.println("第二次經過數據庫鏈接池鏈接數據庫成功!<br> con="+con);

out.println("</H1>");

con.close();

} catch (Exception e) {// 若是出現異常,會打印堆棧裏異常的信息

e.printStackTrace();

   %>    

   %>    

  </body>

</html>

運行結果,顯示如圖 8-28所示。

圖8-28 pool_connection.jsp頁面運行顯示結果

從運行顯示結果來看咱們兩次取得的數據庫鏈接對象爲同一個對象。

【專家提示】請讀者注意因爲鏈接池對象是在構建Web應用時由容器建立並管理的,此時Web應用並無開始被加載。若是採用Java純驅動來鏈接數據庫的驅動程序包應由原來放在「WEB-INF/lib」目錄移到「{Tomcat安裝目}/shared/lib」目錄下,不然會拋出找不到相應驅動程序包而產生異常。

 

第9章 XML操做

【本章專家知識導學】

XML(eXtensible Markup Language,可擴展的標記語言)是一種在Internet上被普遍應用的標記語言,它將SGML的豐富功能與HTML的易用性結合到Web的應用中,經常使用來做爲各類網絡應用系統的數據交換報文、描述系統配置參數文件等。

操做XML文件的開源軟件接口包括DOM 、SAX、JDOM等,程序員須要熟悉並掌握這些經常使用的API接口的使用,可以經過這些接口來編寫Java語句來實現對XML文件的處理。

本章將在介紹XML、DTD等基礎知識後,詳細解說DOM 、SAX、JDOM對XML文件的處理方法。

9.1 XML概述

XML便可擴展的標記語言,能夠定義語義標記,是元標記語言。XML不像HTML(Hyper Text Markup Language,超文本標記語言),HTML只能使用規定的標記,不能擴展;而對於XML用戶則能夠定義本身所須要的標記。XML和HTML師出同門,都是從SGML(Standard Generalized Markup Language)延伸發展而來的標記語言。

XML是一個精簡的SGML,它將SGML的豐富功能與HTML的易用性結合起來。XML保留了SGML的可擴展功能,這使XML從根本上有別於HTML。XML要比HTML強大得多,它再也不是固定的標記,而是容許定義數量不限的標誌來描述文件中的資料,容許嵌套的信息結構。HTML只是Web頁面用來顯示數據的通用方法,而XML提供了一個直接處理Web數據的通用方法。HTML着重描述Web頁面的顯示格式,而XML着重描述的是Web頁面的內容的結構。

XML正被愈來愈普遍地應用,它能夠用來表示數據和數據結構;能夠用來定義數據規範;在企業間交換數據時做爲信息的載體——XML報文等。XML已成爲Internet中不可缺乏的技術,JSP做爲Web編程的語言就有可能須要處理XML文件。

程序員能夠自行編寫Java程序操做XML文件,操做時能夠使用DOM、SAX、JDOM等流行的開源軟件接口操做XML文件。然而,在JSP頁面中插入處理XML文件的Java代碼將使得JSP頁面代碼冗長、邏輯複雜。

因爲超文本標記語言HTML的簡單易學、句法簡明緊湊等優勢,使得它在Web主頁上大顯身手。HTML只是提供了在網絡上數據顯示方式的通用方法,它不描述數據間的邏輯結構。可擴展標記語言XML(Extensible Markup Language)從不一樣角度解決了HTML存在的問題。XML同HTML同樣是一種標記語言,它們都來自於標準通用標記語言SGML。可是XML提供了一個描述數據邏輯結構和交換數據的有效手段,顯示方式提交給樣式表來處理,這是它與HTML的最大區別。

總而言之,XML 是一種元標記語言,該語言提供一種描述結構數據的格式。這有助於更精確地聲明內容,方便跨越多種平臺的更有意義的搜索結果。此外,XML 將起用新一代的基於 Web 的數據查詢和處理應用程序。

 
 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

編寫XML

 

XML文件的編輯能夠使用一些基本的文本編輯器進行,如記事本、寫字板等。固然,若是使用所見即所得的編輯器就更方便了,如XML.Spy。在編寫好代碼後將文件另存爲後綴名爲xml的文件。在任何支持XML的瀏覽器中打開XML文件(或直接雙擊文件)便可看到顯示結果。一個完整的XML文件通常有三個部分構成:XML版本說明、文件類型定義和文件主體,下面看一個簡單的XML文件結構的例子。

【例9-1】一個簡單的XML文件示例

links.xml

<?xml version="1.0" encoding="gb2312"?>

<links>

<link>

<text>JSP Insider</text>

<url newWindow="no">http://www.jspinsider.com</url>

<author>周雄偉</author>

<date>

<day>16</day>

<month>6</month>

<year>2007</year>

</date>

<description>A JSP information site.</description>

</link>

<link>

<text>The makers of Java</text>

<url newWindow="no">http://java.sun.com</url>

<author>Sun Microsystems</author>

<date>

<day>17</day>

<month>6</month>

<year>2007</year>

</date>

<description>Sun Microsystem's website.</description>

</link>

<link>

<text>The standard JSP container</text>

<url newWindow="no">http://jakarta.apache.org</url>

<author>Apache Group</author>

<date>

<day>18</day>

<month>6</month>

<year>2007</year>

</date>

<description>Some great software.</description>

</link>

</links>

該文件用來保存用戶數據,雙擊links.xml文件,該文件在IE瀏覽器中的顯示效果如圖9-1所示。

圖9-1 一個簡單的XML文件示例運行效果圖

文件的第一行以下:

<?xml version="1.0" encoding="gb2312"?>

這是XML 處理指令聲明的第一句,即XML版本說明,它以「<?」開始,以「?>」結束。每一個XML文件都是從一個XML版本說明開始,其做用是告訴瀏覽器或者其它處理程序:這個文件是XML文件。XML版本信息說明格式以下:

<?xml version="版本號" standalone="yes/no" encoding="UTF-8"?>

其中:

version:表示文件遵照的XML規範的版本,在本例中的version 是1.0;

standalone:表示文件內部包含文件類型定義DTD。若是無,參數爲no,默認值爲no;

encoding:表示文件所用的字符編碼,通常是UTF-8或UTF-16,默認UTF-8。若是但願XML文件中能夠使用中文標誌和處理中文字符,必須說明爲gb2312。

【專家提示】<? xml version=…?> 必須是文件的第一行,而且前面不能有空格。

例子中接下來的語句是XML文件主體。XML文件類型定義了文件的邏輯結構,與XML文件類型對應的數據叫XML文件的主體,也簡稱爲XML文件。XML文件主體部分是由XML元素屬性值組成的。一個XML 元素由一個起始標記、一個結束標記,以及夾在這兩個標記之間的數據內容所組成,它用於標識XML文件元素的屬性值。其基本形式以下:

<標記名> 數據內容 </標記名>

其中文件根元素則是一個能夠包含多個嵌套子元素的頂層元素。在例9-1中<links>和 </links>就是根元素,它包含了另外的四個元素。

在XML文件中,標記大小寫是有區別的,而且必須配對使用。<P>和<p>是不一樣的標誌。在定義元素時,先後標誌大小寫要保持同樣。例如<author>張馳</author>,寫成<Author>張馳</author>是錯誤的。

【專家提示】XML是爲了便於閱讀和理解而在XML文件中附加的信息,它們將不會被掃描程序解釋或瀏覽器顯示。註釋的語法格式與HTML中的同樣。

【專家提示】一個XML 元素的下一級節點能夠用「標記名=數據內容」這種「name=value」鍵值對的方式表示。如例子中的第一個date節點能夠表示爲:

……..

<link day="16" month="6"  year="2007">

</link>

…….

XML文件的類型定義簡稱DTD(Document Type Describtion,文檔類型描述),它指明瞭文件主體必須符合的規範。例子中沒有DTD,這部分的知識在將下一節中講述。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DTD

 

XML文件的類型定義簡稱DTD,它指明瞭文件主體必須符合的規範。在一個DTD中,具體規定了引用該DTD的XML文件可以使用哪些標記、父元素中可以包括哪些子元素、各個元素出現的前後順序、元素可包含的屬性、元素和屬性值的數據類型,以及可以使用的實體及符號規則等。

DTD能夠在XML文件內部直接定義,也能夠是一個徹底獨立的文件。DTD由許多約定和聲明語句構成,這些語句能夠包含在XML文件內部,被稱爲內部DTD;也能夠獨立保存爲一個文件,而稱爲外部DTD,此時,在XML文件使用到它時只要直接引用它就能夠了。

DTD主要具備下列幾方面的做用:

(1)能夠驗證XML 文件數據的有效性。

(2)能夠爲某類XML文件提供統一的格式和相同的結構。

(3)能夠保證在必定範圍內,XML 文件數據的交流和共享。

(4)應用程序設計人員根據DTD 就可以知道對應XML 文件的邏輯結構,從而編寫出相應的處理應用程序。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DTD的基本結構

 

在一份DTD 中,包含了對XML 文件所使用的元素、元素間的關係、元素可用的屬性、可以使用的實體等的定義規則。一份DTD 其實是若干條有關元素、屬性、實體等定義和聲明語句的集合。

例9-1中links.xml文件中的XML文件的類型定義DTD能夠是以下的內容:

<? DOCTYPE links[

<!ELEMENT link(text,URL,athuor,date)>

<!ELEMENT text(#PCDATA)>

<!ELEMENT URL(#PCDATA)>

<!ELEMENT athuor(#PCDATA)>

<!ELEMENT date(#PCDATA)>

<!ELEMENTdater(day,month,year)

<!ELEMENT day(#PCDATA)>

<!ELEMENT month(#PCDATA)>

<!ELEMENT year(#PCDATA)>

]>

在DTD中能夠包含下列各類聲明語句:

(1)DTD 聲明開始語句。

(2)元素類型聲明語句。

(3)屬性列表聲明語句。

(4)實體聲明語句。

(5)註釋語句。

下面對這些內容進行簡單的說明。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DTD聲明與引用

 

DTD的聲明根據使用狀況的不一樣,通常能夠份內部DTD、外部DTD和混合DTD的引用。

(1)引用內部DTD

DTD的聲明語法格式以下:

<!DOCTYPE 根元素名稱 [DTD聲明語句序列]>

其中:

「<!DOCTYPE」表示DTD聲明的開始,關鍵字DOCTYPE必須大寫。

根元素名稱是指定XML文件的根元素名稱,這個根元素名稱必須精確地與文件中實際的根元素名稱一致。

DTD聲明語句序列是指包含在一對方括號([ ])以內的若干條語句,用來對XML文件中所使用的元素、屬性和實體等進行具體聲明。

【專家提示】在XML文件中引用內部DTD時,應該在文件開頭的XML聲明語句中添加standalone="yes" 的說明。

(2)引用外部DTD

引用外部DTD首先要建立外部DTD。外部DTD 是一個獨立於XML 文件的文件,使用.dtd爲其文件擴展名。此種文件實際上也是一個文本文件,可用任何文本編輯器建立。在外部DTD 中,除了沒有內部DTD 中的「<!DOCTYPE  根元素名稱」 語句以外,其餘聲明語句都是同樣的。

根據外部DTD性質的不一樣,又可將其分爲私有DTD文件和公共DTD文件。私有DTD文件是指並未公開的DTD文件,一般屬於某個組織內部或我的全部;公共DTD文件則是爲某一應用領域或行業所制定,被國際上的標準組織或行業組織普遍承認的、公開的、標準的DTD文件。

引用私有DTD文件的語法格式爲:

<!DOCTYPE根元素名稱SYSTEM  DTD的URL>

引用公共DTD文件的語法格式爲:

<!DOCTYPE根元素名稱PUBLIC DTD名  DTD的URL>

【專家提示】在XML文件中引用外部DTD時,應該在開頭的XML聲明語句中添加standalone="no" 說明。

(3)混合引用DTD

混合引用DTD是指在一個帶有內部DTD的XML文件中,再引用一個或多個外部DTD來共同規範文件中的內容。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DTD對元素的聲明

 

元素聲明的語法格式:

<!ELEMENT element_name element_definition>

其中:<!ELEMENT: 元素聲明語句的開始,關鍵字ELEMENT必須大寫。

element_name: 所聲明的元素名稱。

element_definition:對該元素內容的定義,用來規定該元素能夠包含的內容。

【專家提示】靈活控制元素出現次數以及元素的分組與嵌套。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DTD對屬性的聲明

 

DTD屬性聲明的語法:

<! ATTLIST Element_Name

Attribute_Name Type [added_declare]

Attribute_Name Type [added_declare]

……

>

其中:

<!ATTLIST:表示屬性定義語句的開始,ATTLIST是關鍵字,必須大寫。

Element_Name:元素名,用來指定對該元素的屬性進行聲明。

Attribute_Name:該元素具備的某個屬性名,屬性的命名規則與元素的命名規則是一致的。

Type:屬性的數據類型。

added_declare:屬性的附加聲明,是一個可選項。

對於DTD屬性聲明的內容比較多,使用也不是不少,對這一部分感興趣的讀者能夠參考有關XML的專門書籍。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

實體的聲明與引用

 

在XML規格中,實體(Entity)具備普遍的含義,一般是指有效的XML文件自己、外部的DTD子集、定義成DTD中外部實體的外部文件或在DTD中定義的用引號括起來的字符串等與XM 文件相關的儲存單元。XML的實體都有一個名稱,用這個名稱來代替這些數據。

XML有兩種類型的實體。一種是在XML文件中使用的實體;另外一種是參數實體,只在DTD文件中使用。

在DTD文件中使用的實體的定義格式爲:

<!ENTITY [%] Entity_Name Entity_Value >或

<!ENTITY [%] Entity_Name SYSTEM Entity_URL>

其中:

<!ENTITY :表示開始聲明一個實體,關鍵字ENTITY必須大寫。

[%]:[]表示可選項,%表示聲明的是一個參數實體。

Entity_Name :表示內部參數實體的名稱。

Entity_Value :表示實體的內容。

SYSTEM :是定義爲外部實體的關鍵字。

Entity_URL :外部實體文件的URL。

已定義的實體在文件中的引用格式爲:&實體名;

例如定義版權信息的實體:

<!DOCTYPE copyright [<!ENTITY copyright "版權全部 全部人:周雄偉">]>

若是版權信息內容和他人共享一個XML文件,也能夠外部引用它,外部引用格式實體爲&copyright。

【例9-2】帶實體元素的XML文件示例

entity.xml

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE copyright [<!ENTITY copyright "版權全部 全部人:周雄偉">]>

<myfile>

<title>lucene開發設計</title>

<author>周雄偉等</author>

<email> daweycs@163.com</email>

<date>20020715</date>

&copyright;

</myfile>

帶實體元素的XML文件示例entity.xml文件在IE中顯示如圖9-2所示。

圖9-2 帶實體元素的XML文件示例運行效果圖

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

命名空間(Namespaces)

 

XML中標誌都是用戶建立的,在不一樣的DTD文件中,有可能出現含義不一樣但名稱相同的標誌。當在一個XML文件中使用多個DTD文件時,就有可能出現標誌同名的矛盾,這會引發數據混亂。

例以下面的文件表示桌子: 

<table>wood table</table>

下面這一個文件卻表示表格:

<table>namelist</table> 

若是須要同時處理這兩個文件,就會發生名字衝突。

Namespaces實際上就是名字空間。引進了Namespaces這個概念就能解決這個問題。Namespaces經過給標誌名稱加一個Namespaces名(URL)定位以區別這些名稱相同的標誌。

Namespaces名一樣須要在XML文件的開頭部分說明,說明的格式以下:

<document xmlns:yourname='URL'>

其中yourname是定義的Namespaces的名稱,URL就是名字空間的網址。

假設上面的"桌子<table>"文件來自http://www.zhuozi.com,能夠說明爲

<document xmlns:itsname='http://www.zhuozi.com'> 

而後在後面的標誌中使用定義好的名字空間:

<itsname :table>wood table</table>

這樣就將這兩個<table>區分開來。

【專家提示】設置URL並非說這個標誌真的要到那個網址去讀取,僅僅做爲一種區別的標誌而已。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DOM

 

在Java中對XML的解析接口經常使用的有3大類:基於DOM(Document Object Model)的解析接口、基於SAX(Simple API for XML)的解析接口和基於JDOM(Java Document Object Model)技術的解析接口。解析器實際上就是一段代碼,它讀入一個XML文件並分析其結構。目前主流的解析器有:JAXP(Java API for XML Processing)、Xerces(Apache)、XML4J(IBM)和xalan等,主流的解析器都支持SAX和DOM。支持JDOM的解析器目前只有SUN公司發佈的jdom包。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DOM的類

 

DOM即文件對象模型。在應用程序中,基於DOM的XML分析器將一個XML文件轉換成了一個對象模型的集合(這個集合一般被稱爲DOM樹),應用程序能夠經過對該對象模型的操做,實現對XML文件中數據的操做。

(1)Document類

Document類描述了整個XML的文件語法結構,它包含了一系列Node類造成的樹形結構。程序員能夠先掃描XML源文件,獲得相應的Document對象,遍歷這顆樹來獲得XML文件的全部內容,這是對XML文件操做的起點。而後再繼續其餘對XML文件的操做。

Document類包含了建立相關類對象的方法,主要有:

createAttribute(String):用給定的屬性名建立一個Attribute對象.,而後可以使用setAttributeNode方法將其放置在一個Element對象上面。

createElement(String):用給定的參數建立一個Element對象,表明XML文件中的一個標誌,而後能夠在這個Element對象上添加屬性或進行其它操做。

createTextNode(String):用給定的字符串建立一個Text對象,Text對象表明了標誌或者屬性中所包含的純文本字符串。若是在一個標誌內沒有其它的標誌,那麼標誌內的文本所表明的Text對象是這個Element對象的惟一子對象。

getElementsByTagName(String):返回特定標誌元素的NodeList對象。

getDocumentElement():返回一個表明DOM根節點的Element對象,也就是表明XML文件根元素的那個對象。

(2)Node對象

Node類是DOM結構中最爲基本的類,它描述了文件樹中的一個抽象的節點。它包含類型爲Element、Attr、Text和其餘類的特徵。Node對象引用的其成員變量來操做XML文件。Node包含的主要方法有:

appendChild(org.w3c.dom.Node):爲這個節點添加一個子節點,並放在全部子節點的最後,若是這個子節點已經存在,則先把它刪掉再添加進去。

getFirstChild():若是節點存在子節點,則返回第一個子節點,對等的,還有getLastChild()方法返回最後一個子節點。

getNextSibling():返回DOM樹中這個節點的下一個兄弟節點,對等的,還有getPreviousSibling()方法返回其前一個兄弟節點。

getNodeName():根據節點的類型返回節點的名稱。

getNodeType():返回節點的類型。

getNodeValue():返回節點的值。

hasChildNodes():判斷是否是存在有子節點。

hasAttributes():判斷這個節點是否存在有屬性。

getOwnerDocument():返回節點所處的Document對象

insertBefore(org.w3c.dom.Node new,org.w3c.dom.Node ref):在給定的一個子對象前再插入一個子對象。

removeChild(org.w3c.dom.Node):刪除給定的子節點對象。

replaceChild(org.w3c.dom.Node new,org.w3c.dom.Node old):用一個新的Node對象代替給定的子節點對象。

(3) NodeList對象 

NodeList對象,顧名思義,就是表明了一個包含了一個或者多個Node的列表。能夠經過下列方法得到列表中的元素:

getLength():返回列表的長度。

item(int):返回指定位置的Node對象。

(4) Element對象

Element類描述XML文件中的標誌元素,繼承於Node,亦是Node的最主要的子對象。在標誌中能夠包含有屬性,於是Element對象中有存取其屬性的方法,而任何Node中定義的方法,Element都繼承下來。Element對象所包含的主要方法有:

getElementsByTagName(String):返回一個NodeList對象,它包含了在這個標誌中其下的子孫節點中具備給定標誌名字的標誌。

getTagName():返回一個表明這個標誌名字的字符串。

getAttribute(String):返回標誌中給定屬性名稱的屬性的值。在這兒須要注意的是,由於XML文件中容許有實體屬性出現,而這個方法對這些實體屬性並不適用。這時候須要用getAttributeNodes()方法來獲得一個Attribute對象來進行進一步的操做。

getAttributeNode(String):返回一個表明給定屬性名稱的Attribute對象。

(5) Attribute對象

Attribute對象表明了某個標誌中的屬性。Attribute繼承Node,可是由於Attr其實是包含在Element中的,它不能被看做是Element的子對象。在DOM中Attributer並非DOM樹的一個節點,因此Node中的getparentNode(),getpreviousSibling()和getnextSibling()返回的都將是null。也就是說,Attribute是Element類的一部分,它並不做爲DOM樹中單獨的一個節點出現。這一點在使用的時候要同其它的Node子對象相區別。

DOM類在DOM中都是用接口描述語言IDL定義的,於是,DOM能夠映射到任何面向對象的語言,只要它實現了DOM所定義的接口就能夠了。許多公司和廠家提供了符合DOM規範的DOM接口和程序包。下面以微軟的DOM接口爲例,講述DOM的使用。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

DOM讀取XML文件

 

DOM讀取XML文件一般要用到如下五個基本的步驟:

(1)創建一個解析器工廠。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

(2)以利用這個工廠來得到一個具體的解析器對象。

DocumentBuilder builder= factory.newDocumentBuilder();

(3)利用DocumentBuilder的parse()方法接受一個XML文件名做爲輸入參數,返回一個Document對象。Document對象表明了一個XML文件的樹模型。

Document doc=builder.parse("candidate.xml");

(4)使用Document對象的getElementsByTagName()方法,咱們能夠獲得一個NodeList對象,它是XML文件中的標籤元素列表,能夠使用NodeList對象的item()方法來獲得列表中的每個Node對象。

NodeList nl =doc.getElementsByTagName("PERSON");

Element node=(Element) nl.item(i);

(5)經過Node對象的getNodeValue()方法提取某個標籤內的內容。

node.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue()

下面咱們來看一個具體的DOM讀取XML文件的示例。

【例9-3】DOM讀取XML文件示例

本例將DOM讀取XML文件示例程序是對例9-1的links.xml文件的用戶數據讀取出來並用表格的方式在IE瀏覽器上顯示。源程序以下:

display.jsp

<%@ page contentType="text/html;charset=gb2312"%>

<%@page import="javax.xml.parsers.*,java.io.*,java.util.*, "%> 

<%@page import=org.w3c.dom.*,org.apache.xml.serialize.* "%>

<html>

<head>

<title> DOM讀取XML文件示例</title>

</head>

<body>

<table border=1>

<!--輸出表頭-->

<tr >

<td>content</td>

<td>url</td>

<td>author</td>

<td>date</td>

<td>description</td>

</tr>

<%

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//(1)

DocumentBuilder builder=factory.newDocumentBuilder();//(2)

Document doc=builder.parse("link.xml");//(3)

doc.normalize();

NodeList links =doc.getElementsByTagName("link");//(4)

<!--輸出數據-->

for (int i=0;i<links.getLength();i++){

Element link=(Element) links.item(i);//(4)

out.print("<tr>");

out.println("<td>"+link.getElementsByTagName("text").item(0).getFirstChild().getNodeValue()+"</td>");//(5)

out.println("<td>"+link.getElementsByTagName("url").item(0).getFirstChild().getNodeValue()+"</td>");//(5)

out.println("<td>"+link.getElementsByTagName("author").item(0).getFirstChild().getNodeValue()+"</td>");//(5)

Element linkdate=(Element) link.getElementsByTagName("date").item(0); //(4)

String day=linkdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();//(5)

String month=linkdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();

String year=linkdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();

out.println("<td>"+day+"-"+month+"-"+year+"</td>");

out.println("<td>"+link.getElementsByTagName("description").item(0).getFirstChild().getNodeValue()+"</td>");//(5)

out.println();

}

%>

</table>

</body>

</html>

該程序基本上徹底遵循上面講到的DOM讀取XML文件五個基本的步驟(程序中有具體的註釋),只是第(4)、(5)部在反覆屢次使用,程序的基本原理很是簡單。其運行的結果如圖9-3所示。

圖9-3 DOM讀取XML文件示例運行結果圖

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

修改XML文件

 

修改XML文件就是在修改了DOM樹後從新寫入到XML文件中去的問題了。在修改XML文件一般會遇到兩個方面的問題:

(1)是在XML文件中增長記錄

在XML文件中增長記錄,首先要在DOM樹中增長一個節點元素,而後在這個節點上增長子節點元素,並給相應的葉節點賦值,最後把DOM樹保存到XML文件中。

(2)是在XML文件中修改節點的值。

修改XML文件中節點的值,先是讀入到DOM樹中,再遍歷DOM樹,在遍歷的過程當中找到相應的節點並修改其值,在把修改的DOM保存到XML文件中。

這裏咱們先看一個在XML文件中增長記錄的示例。

【例9-4】用DOM修改XML文件示例

該示例仍然用例9-1的應用環境,功能是對links.xml增長一條數據記錄。增長的數據記錄的XML內容以下:

<link>

<text>Wudong's Homepage</text>

<url newWindow="no">http://www.wudong.com</url>

<author>Wudong Liu</author>

<date>

<day>6</day>

<month>10</month>

<year>2006</year>

</date>

<description>A site from Wudong Liu,give u lots of suprise!!!</description>

</link>

具體程序實現的源代碼以下。

domchangxml.jsp

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="javax.xml.parsers.*, javax.xml.transform.*,javax.xml.transform.dom.*"%>

<%@ page import="javax.xml.transform.stream.*,java.io.*,java.util.*, org.w3c.dom.*, org.apache.xml.serialize.* "%>

<html>

<head>

<title> DOM修改XML文件示例</title>

</head>

<body>

<%  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

  DocumentBuilder builder=factory.newDocumentBuilder();

  Document doc=builder.parse("links.xml");

  doc.normalize();

   //---取得變量---- 

  String text="Wudong's Homepage";

  String url="www.wudong.com";

  String author="Wudong Liu";

  String discription="A site from Wudong Liu, give u lots of suprise!!!";

  //建立一個link對象

  Text textseg;

  Element link=doc.createElement("link");

  //XML文件中添加一個link項目的具體元素 

  Element linktext=doc.createElement("text");

  textseg=doc.createTextNode(text);

  linktext.appendChild(textseg);

  link.appendChild(linktext);

  Element linkurl=doc.createElement("url");

  textseg=doc.createTextNode(url);

  linkurl.appendChild(textseg);

  link.appendChild(linkurl);

  Element linkauthor=doc.createElement("author");

  textseg=doc.createTextNode(author);

  linkauthor.appendChild(textseg);

  link.appendChild(linkauthor);

  String day="6";

  String month="10";

  String year="2006";

  Element linkdate=doc.createElement("date");

  Element linkdateday=doc.createElement("day");

  textseg=doc.createTextNode(day);

  linkdateday.appendChild(textseg);

  Element linkdatemonth=doc.createElement("month");

  textseg=doc.createTextNode(month);

  linkdatemonth.appendChild(textseg);

  Element linkdateyear=doc.createElement("year");

  textseg=doc.createTextNode(year);

  linkdateyear.appendChild(textseg);

  linkdate.appendChild(linkdateday);

  linkdate.appendChild(linkdatemonth);

  linkdate.appendChild(linkdateyear);

  link.appendChild(linkdate);

  Element linkdiscription=doc.createElement("description");

  textseg=doc.createTextNode(discription);

  linkdiscription.appendChild(textseg);

  link.appendChild(linkdiscription);

//建立好的節點添加到DOM樹中

doc.getDocumentElement().appendChild(link);

//用XSLT把DOM樹輸出

TransformerFactory tFactory =TransformerFactory.newInstance();

  Transformer transformer = tFactory.newTransformer();

  DOMSource source = new DOMSource(doc);

  StreamResult result = new StreamResult(new File("links.xml"));

  Transformer transform(source, result);    

%>

<table border=1>

<!--輸出表頭-->

<tr >

<td>content</td>

<td>url</td>

<td>author</td>

<td>date</td>

<td>description</td>

</tr>

<%  //輸出顯示數據

      NodeList links =doc.getElementsByTagName("link"); 

       for (int i=0;i<links.getLength();i++){

      link= (Element) links.item(i);

      out.print("<tr>");

out.println("<td>"+link.getElementsByTagName("text").item(0).getFirstChild().getNodeValue()+"</td>");

out.println("<td>"+link.getElementsByTagName("url").item(0).getFirstChild().getNodeValue()+"</td>");

out.println("<td>"+link.getElementsByTagName("author").item(0).getFirstChild().getNodeValue()+"</td>");

linkdate=(Element) link.getElementsByTagName("date").item(0);

day=linkdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();

month=linkdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();

year=linkdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();

out.println("<td>"+day+"-"+month+"-"+year+"</td>");

out.println("<td>"+link.getElementsByTagName("description").item(0).getFirstChild().getNodeValue()+"</td>");

out.println();

    }

%>

</table>

</body>

</html>

該程序首先在DOM 樹中增長一條記錄,將DOM樹保存到links.xml文件中,而後再將DOM樹中的內容顯示出來,程序的流程很是清晰明瞭(與上面講到步驟的一致),但要注意各類方法,特別是把DOM樹輸出使用XSLT顯得特別簡單。程序的運行結果如圖9-4所示,與例9-3比較多了一條記錄數據。

圖9-4 DOM修改XML文件示例運行結果圖

程序的運行後,links.xml文件在IE中顯示如圖9-5所示。

圖9-5  程序的運行後links.xml文件在IE中顯示結果

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

SAX

 

SAX即XML簡單應用程序接口。SAX提供了一種對XML文件進行順序訪問的模式,這是一種快速讀寫XML數據的方式。當使用SAX分析器對XML文件進行分析時,會觸發一系列事件,並激活相應的事件處理函數,從而完成對XML文件的訪問,因此SAX接口也被稱做事件驅動接口。

SAX是一種輕量型的方法。在處理DOM的時候,須要讀入整個的XML文件,而後在內存中建立DOM樹,生成DOM樹上的每一個Node對象。

當文件比較小的時候,這不會形成什麼問題,可是一旦文件變大,處理DOM就會變得至關費時費力。特別是其對於內存的需求,將是成倍的增加,以致於在某些應用中使用DOM是一件很不經濟的事,一個較好的替代解決方法就是SAX。

XML不只規定了如何表示和顯示數據,還提供了標準的API供處理XML數據,這也就是咱們稱之爲智能數據或數據標準的緣由。

SAX(The Simple API for XML)是基於事件的XML分析API,功能比較簡單。 這一API是事件驅動的,又稱"順序訪問"協議。每當它看到一個新的XML標記(或遇到一個錯誤,或想告訴你什麼事時)就用一個SAX解析器註冊你的句柄,激活你的回調方法。

DOM 定義了分析程序應當顯露的標準命令集,使您可以在程序中訪問 HTML 和 XML 文件內容。支持 DOM 的 XML 分析程序取出 XML 文件中的數據,並經過一組能夠對它編程的對象來顯露它。DOM將一個XML文件轉換成你程序中的一個對象集合。而後你能夠任意處理對象模型。這一機制也稱爲"隨機訪問"協議,由於你能夠在任什麼時候間訪問數據的任何一部分,而後修改、刪除或插入新數據。 DOM的特色是功能強大,但分析時間長,佔用資源多。

SAX 提供了處理 XML 文件的快速、低內存的另外一種方法。在使用 DOM 分析 XML 文件時,它在內存中創建了完整的文件樹。相比而言,SAX 將遍歷文件,並將新元素的開始或結束等通知分析事件的調用應用程序。使用 SAX 的一個最佳功能是分析長文件。例如,用 SAX 分析器,應用程序能夠監視發生的事件,只將文件中必要的部分讀入內存。

在Tomcat5.5中已經安裝了SAX解析器,提供了SAX方式的API接口。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

SAX的類

 

SAX方式解析XML文件最重要的類就是ContentHandler,ContentHandler類的方法無須調用,它們就象一個事件監聽器,在解析XML文件的過程當中會自動觸發相應的事件來調用方法。此類的經常使用方法以下:

(1)startDocument()

當遇到文檔的開頭時調用這個方法,能夠在其中作一些預處理的工做。調用方法以下:

void startDocument()

(2)endDocument()

當文檔結束時會調用這個方法,能夠在其中作一些善後的工做。調用方法以下:

void endDocument()

(3)startElement()

當讀到一個標籤開始時,會觸發事件並調用這個方法。調用方法以下:

void startElement(String namespaceURI,String localName,String qName,Attributes atts)

其中,參數namespaceURI指的是名域,在本書的實例中無須用到,參數localName爲使用名域時的標籤名,若是不使用名域,此參數值均爲null。參數qName爲標籤名,參數atts是標籤的屬性集。

(4)endElement()

在遇到結束標籤時,會調用這個方法。調用方法以下:

void endElement(String namespaceURI,String localName,String qName)

其中,參數含義同startElement()。

(5)characters()

這個方法用來處理在XML文件中讀到的字符串,以及讀到的這個字符串在這個數組中的起始位置和長度,它的參數是一個字符數組,能夠很容易用String類的一個構造方法來得到這個字符串的String類:String charEncontered=new String(ch,start,length)。

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

SAX讀取XML文件

 

SAX解析器工做的過程至少包含3步。

(1)和DOM同樣,須要創建一個解析器工廠。

SAXParserFactory spf = SAXParserFactory.newInstance();

(2)建立一個解析器對象。

SAXParser saxParser = spf.newSAXParser();

(3)將解析器和XML文件聯繫起來,開始解析。

saxParser.parse(new File(filename),new sax());

在進行具體的應用中(包括用SAX讀取XML文件)主要使用ContentHandler類的方法自動觸發相應的事件來調用這些方法進行的工做,下面是一個用SAX讀取XML文件的示例程序。

【例9-5】用SAX讀取XML文件示例

saxParseUserXML1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="javax.xml.parsers.*,org.xml.sax.*,org.xml.sax.helpers.*,

org.xml.sax.helpers.DefaultHandler,java.io.*"%>

<html>

  <head><title>用SAX解析並遍歷user.xml</title></head>

  <body>

<%!

static class SAXParseUser extends DefaultHandler{

StringBuffer tempString=new StringBuffer();

//文件解析開始

public void startDocument() throws SAXException {

tempString.append("開始解析xml文件......<br>");

}

//標籤解析開始

public void startElement(String namespaceURI, String localName,String qName, Attributes atts) throws SAXException{

tempString.append("開始解析結點,結點名稱:"+qName+"<br>");

//解析獲得標籤全部的屬性

for(int i=0;i<atts.getLength();i++){

tempString.append("&nbsp;&nbsp;屬性"+atts.getQName(i)+",值爲:"+atts.getValue(i)+"<br>");

}

}

//標籤解析結束

public void endElement(String namespaceURI,String localName,String qName) throws SAXException{

tempString.append("解析結點結束,結點名稱:"+qName+"<br>");

}

//字符串解析

public void characters(char[] ch,int start,int length){

tempString.append("&nbsp;&nbsp;解析出字符串,值爲:'"+(new String(ch,start,length))+"'<br>");

}

//文件解析結束

public void endDocument() throws SAXException {

tempString.append("解析xml文件結束!<br>");

}

//獲得解析結果

public StringBuffer getPrintXML(){

return tempString;

}

}

%>

<%//生成SAX解析器工廠長

SAXParserFactory spf = SAXParserFactory.newInstance();

XMLReader xmlReader = null;

SAXParser saxParser=null;

SAXParseUser saxParseUser=new SAXParseUser();

String filename=pageContext.getServletContext().getRealPath("/link.xml");

try {

// 建立一個解析器SAXParser對象

saxParser = spf.newSAXParser();

// 獲得SAXParser中封裝的SAX XMLReader

xmlReader = saxParser.getXMLReader();

//設置解析時處理事件的對象

xmlReader.setContentHandler(saxParseUser);

//開始解析XML文件

xmlReader.parse(filename);

}catch (Exception ex) {

System.out.println(ex);

}

%>

   <!--輸出解析結果-->

<table border=1>

<!--輸出表頭-->

<tr >

<td>content</td>

</tr>

<%

  out.println("<td>"+saxParseUser.getPrintXML()+"</td>");

%>  

 </table>

 </body>

</html>

程序的註釋很清晰,這個例子須要注意的是ContentHandler類自己的特色:ContentHandler類的方法無須調用,它們就象一個事件監聽器,在解析XML文件的過程當中會自動觸發相應的事件來調用方法。在實際開發過程當中能夠把ContentHandler類的繼承類聲明爲JavaBean。程序的運行結果如圖9-6所示。

圖9-6 用SAX讀取XML文件示例運行結果

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

JDOM

 

JDOM的處理方式是與DOM相似的操做。是SUN公司發佈的一種簡單方便的XML處理接口。JDOM設計者的目標是:「Java + XML = JDOM」。2002年的JavaOne會議上JDOM的主要創始人Jason Hunter有一篇精彩的演講介紹了JDOM技術,題目就是「JDOM Makes XML Easy」在那篇文件裏,JDOM被拿來與DOM比較,JDOM是爲了在Java中提供比DOM和SAX更爲方便的XML處理接口而開發的。在http://jdom.org能夠下載JDOM的最新版本。JDOM的jar組件包文件是jdom.jar。

JDOM的處理方式有些相似於DOM,但它主要是用SAX實現的,沒必要擔憂處理速度和內存的問題。另外,JDOM中幾乎沒有接口,所有是類,主要的類有:

Attribute(屬性)、CDATA(內容)、Comment(註釋)、Document(文件)、Element(元素)Namespace(命名空間)、ProcessingInstruction(處理指令)和Text(文本)。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

JDOM的類

 

JDOM中提供了以下7個包,各自的功能以下:

org.jdom——提供描述XML文件的基本類。

org.jdom.input——提供DOMBuilder和SAXBuilder類, 用來讀取及解析已有的XML文件。

org.jdom.output——提供創建XML文件的類,有DOMOutput、SAXOutput、XMLOutput等類。

org.jdom.adapters——該包是用來與DOM進行溝通的。

org.jdom.filter——包含了xml文檔的過濾器類。

org.jdom.transform——包含了將jdom xml文檔接口轉換爲其餘xml文檔接口。

org.jdom.xpath——包含了對xml文檔xpath操做的類.

在org.jdom中提供的類主要有:

Document——文件類,提供設置或獲取根元素、元素內容、註釋、處理命令等的方法。

Element——元素類,提供設置或獲取元素的子元素、內容、屬性等的方法。

Attribute——屬性類,提供設置或獲取元素屬性名、屬性值的方法。

Entity——實體類,提供設置或獲取實體名、內容的方法。

DocType——DTD聲明類,提供設置或獲取DTD聲明及內容的方法。

ProcessingInstruction——處理命令類,提供設置或獲取處理命令及內容的方法。

org.jdom中還提供了Comment(註釋類)、CDATA、Namespace等一些類。

下面來看一下具體的類的經常使用方法,以及這些經常使用方法的使用。

一、Document類

(1)Document的操做方法

Element root = new Element("GREETING");

Document doc = new Document(root);

root.setText("Hello JDOM!");

或者簡單的使用

Document doc = new Document(new Element("GREETING").setText("Hello JDOM!t"));

這點和DOM不一樣。Dom則須要更爲複雜的代碼,以下:

DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();

DocumentBuilder builder =factory.newDocumentBuilder();

Document doc = builder.newDocument();

Element root =doc.createElement("root");

Text text = doc.createText("This is the root");

root.appendChild(text);

doc.appendChild(root);

【專家提示】JDOM不容許同一個節點同時被2個或多個文檔相關聯,要在第2個文檔中使用原來老文檔中的節點的話。首先須要使用detach()把這個節點分開來。

(2)從文件、流、系統ID、URL獲得Document對象

DOMBuilder builder = new DOMBuilder();

Document doc = builder.build(new File("jdom_test.xml"));

SAXBuilder builder = new SAXBuilder();

Document doc = builder.build(url);

在新版本中DOMBuilder 已經不多使用DOMBuilder.builder(url),用SAX效率會比較快。

(3)DOM的Document和JDOM的Document之間的相互轉換使用方法

DOMBuilder builder = new DOMBuilder();

org.jdom.Document jdomDocument = builder.build(domDocument);

DOMOutputter converter = new DOMOutputter();// work with the JDOM document…

org.w3c.dom.Document domDocument = converter.output(jdomDocument);

二、XMLOutPutter類

JDOM的輸出很是靈活,支持不少種io格式以及風格的輸出。

Document doc = new Document(...);

XMLOutputter outp = new XMLOutputter();

outp.output(doc, fileOutputStream); // 用XMLOutputter對象輸出JDOM文檔對象

outp.setTextTrim(true); // Compressed output

outp.output(doc, socket.getOutputStream());

outp.setIndent(" ");// 設置緊縮編排使用的字符串

outp.setNewlines(true);

outp.output(doc, System.out);

三、Element類

(1)瀏覽Element樹

Element root = doc.getRootElement();//得到根元素element

List allChildren = root.getChildren();// 得到全部子元素的一個list

List namedChildren = root.getChildren("name");// 得到指定名稱子元素的list

Element child = root.getChild("name");//得到指定名稱的第一個子元素

JDOM給了咱們不少很靈活的使用方法來管理子元素(這裏的List是java.util.List)

List allChildren = root.getChildren();

allChildren.remove(3); // 刪除第四個子元素

allChildren.removeAll(root.getChildren("jack"));// 刪除叫「jack」的子元素

root.removeChildren("jack"); // 便捷寫法

allChildren.add(new Element("jane"));// 加入

root.addContent(new Element("jane")); // 增長子節點元素

allChildren.add(0, new Element("first"));

(2)移動Element

在JDOM裏移動Element很簡單:

Element movable = new Element("movable");

parent1.addContent(movable); // 向Document中添加子元素

parent1.removeContent(movable); //向Document中刪除子元素

parent2.addContent(movable); // add

在Dom裏移動Element:

Element movable = doc1.createElement("movable");

parent1.appendChild(movable); //向Document中添加子元素

parent1.removeChild(movable); //向Document中刪除子元素

parent2.appendChild(movable); // 出錯!

(3)Element的text內容讀取

String desc = element.getText();//獲得元素文本值

String desc = element.getTextTrim();//獲得元素文本值並去除左右空格

(4)Elment內容修改

element.setText("A new description");//設置元素的文本

四、Attribute類

<table width="100%" border="0"> </table>

String width = table.getAttributeValue("width");//得到attribute

int border = table.getAttribute("width").getIntValue();

table.setAttribute("vspace", "0");//設置attribute

table.removeAttribute("vspace");// 刪除一個或所有attribute

table.getAttributes().clear();

使用JDOM經過程序創建一個新的XML文件,或者對一個已有XML文件進行轉換(存取以及修改、添加等操做)。

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

使用JDOM建立和讀取XML文件

 

使用JDOM建立一個新XML文件的通常步驟是: 

(1) 創建元素及其內容

創建一個元素(Element對象)做爲根結點;

創建根結點的子結點(若是有):建一新元素,加入到根結點中做爲子結點;

創建子結點的下面一層子結點:

……

直至建完葉子。

創建DOM結構樹時能夠橫向一層一層地依次創建,也能夠縱向向下建完葉子再回頭創建另外一結點,創建順序不限。

(2)以根結點爲根元素創建文件(Document對象)

(3)創建XML文件

(4)使用org.output包中的方法創建輸出流對象

(5)使用輸出流對象的output方法將Document對象輸出到文件中,完成XML文件的創建。

【例9-6】用JDOM讀取XML文件示例

本例將利用JDOM編寫一個JSP程序(CreateXML.java),該程序實現創建一個新的XML文件「books.xml」,並用表格輸出在瀏覽器XML文件books.xml的數據。

源程序以下:

jdomreadxml.jsp

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="org.jdom.*,org.jdom.input.*,org.jdom.output.XMLOutputter,

java.io.*,org.jdom.output.Format,java.util.*"%>

<html>

<head>

<title> JDOM讀取XML文件示例</title>

</head>

<body>

<%

   Element root,ele,name,name1,name2,name3;

   //Element root=new Element("教材表")

   root=new Element("教材表");    //創建根元素<教材表>

  //創建根元素的第一個子元素<教材>

   ele=new Element("教材");       //建新元素<教材>

   root.addContent(ele);             //將<教材>加入根元素, 成爲根元素的子元素

   name=new Element("書名");     //建新元素<書名>

   ele.addContent(name);            //將<書名>加入<教材>中, 成爲<教材>的子元素

   name.setText("Java網絡編程"); //設置<書名>的內容

   name1=new Element("做者");     //建新元素<做者>

   ele.addContent(name1);     //將<做者>加入<教材>中, 成爲<教材>的第2個子元素

   name1.setText("陳春穎等");

   name2=new Element("出版社");     //建新元素<出版社>

   ele.addContent(name2);   //將<出版社>加入<教材>中, 成爲<教材>的第3個子元素

   name2.setText("高等教育出版社");

   name3=new Element("價格");  //建新元素<價格>

   ele.addContent(name3);  //將<價格>加入<教材>,成爲<教材>的第4個子元素

   name3.setText("46.0");        //設置<價格>的內容

  //創建根元素的第二個子元素<教材>

   ele=new Element("教材");        

   name=new Element("書名");  

   name1=new Element("出版社"); 

   name2=new Element("做者"); 

   name3=new Element("價格");     

   name.setText("專家導學JSP應用開發");  

   name1.setText("電子工業出版社");

   name2.setText("周雄偉等");

   name3.setText("51.0");         

   ele.addContent(name); 

   ele.addContent(name1); 

   ele.addContent(name2); 

   ele.addContent(name3); 

   root.addContent(ele); //將<教材>加入根元素, 成爲根元素的第2個子元素

 //創建根元素的第二個子元素<教材>

   ele=new Element("教材");        

   name=new Element("書名");  

   name1=new Element("出版社"); 

   name2=new Element("做者"); 

   name3=new Element("價格");     

   name.setText("Lucene開發");  

   name1.setText("電子工業出版社");

   name2.setText("周雄偉等");

   name3.setText("55.0");         

   ele.addContent(name); 

   ele.addContent(name1); 

   ele.addContent(name2); 

   ele.addContent(name3); 

   root.addContent(ele); //將<教材>加入根元素, 成爲根元素的第3個子元素

Document doc=new Document(root);  //以根元素創建文件

FileOutputStream f=new FileOutputStream("books.xml");  

XMLOutputter out1=new XMLOutputter();   //創建輸出流

Format format=Format.getPrettyFormat(); //格式化文件

format.setEncoding("gb2312"); //格式設爲gbk2312中文將顯示

out1.setFormat(format); 

out1.output(doc,f);    //將文件輸出到XML文件中

%>

<table border=1>

<!--輸出表頭-->

<tr >

<td>書名</td>

        <td>價格</td>

        <td>出版社</td>

<td>做者</td>

</tr>

<%//---獲得數據---

SAXBuilder builder = new SAXBuilder();//建立對象

//創建Document對象

Document readDocument = builder.build(pageContext.getServletContext().getRealPath("books.xml"));

//獲得根元素

Element rootElement = readDocument.getRootElement();

//獲得根無素的子元素列表,實際上就是user元素列表

List list = rootElement.getChildren();

//-----輸出數據----

for(Iterator i = list.iterator();i.hasNext();){

 Element current = (Element)i.next();

 out.println("<tr>");

 //----輸出書名--

out.println("<td>"+current.getChildText("書名")+"</td>");

 //----輸出價格--

out.println("<td>"+current.getChildText("價格")+"</td>");

          //----輸出出版社--

         out.println("<td>"+current.getChildText("出版社")+"</td>");

          //----輸出做者--

         out.println("<td>"+current.getChildText("做者")+"</td>");

out.println("</tr>");

}

%>

</table>

</body>

</html>

結合使用JDOM建立一個新XML文件的通常步驟和源程序的註釋,這個程序不難理解,程序的運行結果如圖9-7所示。

圖9-7 DOM讀取XML文件示例運行結果

該程序運行後,在該程序的目錄下即生成XML文件「books.xml」,雙擊「books.xml」文件,便可看到如圖9-8所示效果。

圖9-8 books.xml的運行結果

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

使用JDOM修改XML文件

 

使用JDOM修改XML文件與DOM修改XML文件同樣,也包含兩個方面的。是在XML文件中在XML文件中增長記錄和是在XML文件中修改節點的值兩個方面,它們的進行的基本原理相似。用JDOM由現有XML文件生成DOM模型時,對一個XML文件進行轉換過程如圖9-9所示,能夠分爲以下幾步:

(1)創建一個解析器

(2)解析XML文件並傳回Document對象

(3)JDOM提供的方法存取這個Document對象

圖9-9 XML轉換DOM模型

前面DOM講了在XML文件中增長記錄的示例,這裏咱們來說一個在XML文件中修改節點值的例子。

【例9-7】JDOM修改XML文件示例

本例將編寫一個JSP程序,它利用JDOM讀出例9-6所生成的XML文件「books.xml」的內容,並對其進行修改後再寫回XML文件「books.xml」中,源程序以下:

jdomchangxml.jsp

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="javax.xml.parsers.*,org.jdom.*,org.jdom.output.XMLOutputter,java.io.*,java.util.*"%>

<%@ page  import="org.jdom.*,org.jdom.input.*,org.jdom.output.XMLOutputter,java.io.*,

org.jdom.output.Format,java.util.*"%>

<html>

<head>

<title> JDOM修改XML文件示例</title>

</head>

<body>

<%

   SAXBuilder sb = new SAXBuilder();         //創建一個解析器

   //構造一個Document,讀入books.xml文件的內容

   Document doc = sb.build(new FileInputStream("books.xml"));

   Element root = doc.getRootElement();      //獲得根元素

   java.util.List books = root.getChildren();    //獲得根元素全部子元素的集合

   Element book = (Element)books.get(0);      //獲得第1個子元素<教材>

   //爲第1個元素<教材>添加一條屬性

   Attribute a = new Attribute("有課件","true");

   //book.addAttribute(a);

   book.setAttribute(a);

   //爲第1個元素<教材>添加一個元素<做者>

   Element author = new Element("做者"); //建新元素<做者>

   author.setText("yinzhaolin"); //設置<做者>的內容

   book.addContent(author);   //將<做者>加入<教材>中

   book.removeChild("價格");   //刪除子元素<價格>

   book = (Element)books.get(1);    //獲得第2個元素<教材>

   //修改價格

   Element price = book.getChild("價格");   //獲得指定的子元素<價格>

   price.setText("56");    //將價格改成20元

   XMLOutputter out1 = new XMLOutputter();//創建輸出流

   out1.output(doc, new FileOutputStream("books.xml"));  //將文件輸回到XML文件中

%>

<table border=1>

<!--輸出表頭-->

<tr >

<td>書名</td>

        <td>價格</td>

        <td>出版社</td>

<td>價格</td>

</tr>

     <%//---獲得數據---

Element newroot = doc.getRootElement();

//獲得根無素的子元素列表,實際上就是user元素列表

List list = newroot.getChildren();

//-----輸出數據----

for(Iterator i = list.iterator();i.hasNext();){

 Element current = (Element)i.next();

 out.println("<tr>");

 //----輸出書名--

out.println("<td>"+current.getChildText("書名")+"</td>");

 //----輸出做者--

         out.println("<td>"+current.getChildText("出版社")+"</td>");

          //----輸出出版社--

         out.println("<td>"+current.getChildText("做者")+"</td>");

          //----輸出價格--

out.println("<td>"+current.getChildText("價格")+"</td>");

out.println("</tr>");

}

%>

</table>

</body>

</html>

程序的源碼進行了詳細的註釋,對比之前的代碼,JDOM比DOM和SAX方式操做XML文件明顯要方便,並且效率比DOM方式要高。程序的運行結果如圖9-10所示

圖9-10 JDOM修改XML文件示例運行結果

上面的程序修改了例9-6所創建的XML文件books.xml,修改後的books.xml顯示的結果如圖9-11。

圖9-11 修改後的XML文件顯示結果

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

XML文件與數據庫操做

 

XML文件與數據庫的操做應用很是普遍,既能夠用XML文件對數據庫進行鏈接與配置,也能夠把數據庫的表記錄用XML文件進行備份。其中數據庫表記錄集轉換到XML文件大致能夠分兩步:

(1)創建數據庫和表,利用ODBC中設置數據源,並指向該數據庫。

(2)把數據庫的記錄集轉換成XML文件。其步驟以下:

利用select語句創建須要的記錄集(ResultSet);

得到記錄集的結構;

把記錄集轉換成XML文件。

下面看一個JDOM把數據庫的錶轉化成XML文件示例。

【例9-8】JDOM把數據庫的錶轉化成XML文件示例

本例將編寫使用JDOM技術的JSP應用程序,它讀出Access數據庫student.mdb中學生信息表(information)表的記錄集,並將它們轉換成名爲DB.xml的XML文件。student.mdb的information表結構以下。

表9-1  學生信息表結構

 

源程序以下:

jdomchangDBtoxml.jsp

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="javax.xml.parsers.*,org.jdom.*,org.jdom.output.XMLOutputter,java.io.*,java.util.*, java.sql.*,org.jdom.output.Format"%>

<html>

<head>

<title> JDOM把數據庫的錶轉化成XML文件示例</title>

</head>

<body>

JDOM把數據庫的錶轉化成XML文件<br>

<%

//創建數據庫鏈接並獲取學生表的記錄集和結構

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加載橋驅動程序

Connection con=DriverManager.getConnection("jdbc:odbc:Demo"); //創建數據庫鏈接

Statement stmt=con.createStatement();

ResultSet rs=stmt.executeQuery("select * from information"); //獲取結果集

rs.next();

out.println(rs.getString("字段1"));

//得到結果集的結構

ResultSetMetaData rsmd=rs.getMetaData();

//得到結果集的列數,也就是數據項的數目

int numcols=rsmd.getColumnCount();

//記錄集到XML文件的轉換

Element root,ele,name; //定義Element類的對象根元素(root)

root=new Element("student"); //創建根元素

//循環, 將結果集中的每一條記錄轉換成一個元素(標記名爲「第…個記錄」)

while(rs.next())

{ele=new Element("第"+rs.getRow()+"條紀錄"); //設置元素,名爲「第…個記錄」

out.println(ele);

for(int i=1;i<=numcols;i++) //循環,將一條記錄中的每一個字段轉換成一個元素

{// getColumnLabel(i) 獲取第i個列的字段名(列數從0開始)。

//out.println(rs.getString(i));

name=new Element(rsmd.getColumnLabel(i)); //以得到的字段名爲標記名設置元素

name.setText(rs.getString(i)); //獲取字段內容做爲字段名元素的內容

ele.addContent(name); //將字段名元素置爲記錄的子元素

}

root.addContent(ele); //將記錄元素置爲根元素的子元素

}

Document doc=new Document(root); //以根元素創建文件

FileOutputStream f=new FileOutputStream("DB.xml");

XMLOutputter out1=new XMLOutputter(); //將文件輸出造成XML文件

Format format=Format.getPrettyFormat(); //格式化文件

format.setEncoding("gb2312"); //編碼設爲gb2312中文將顯示正常

out1.setFormat(format);

out1.output(doc,f);

rs.close(); con.close(); //關閉各個對象

out.println("數據庫表Information已成功地轉化成XML文件DB.xml!");

%>

</table>

</body>

</html>

程序的運行結果如圖9-12所示。

圖9-12 JDOM把數據庫的錶轉化成XML文件

程序運行後在工程的目錄下生成XML文件「DB.xml」,雙擊「DB.xml」文件,便可看到如圖9-13所示結果。

圖9-13  由數據庫記錄集轉換獲得的XML文件顯示結果

 
 
 
 

第 9 章:XML操做做者:鄧子云赫斌等    來源:希賽網    2014年03月05日

 

小結

 

XML在Web開發中應用普遍,已經進入Java程序員必備的知識範疇。本章從XML的基本概念講起,由淺入深,介紹了XML的文件結構以及DTD知識,主要講解XML文件的三種處理方式:DOM\SAX和JDOM。

DOM和SAX是經常使用的兩種操做XML文件的接口。DOM方式先將XML文件讀入內存,創建起一棵文檔樹,經過對這棵文檔樹的操做來完成對XML文件的操做。SAX API是事件驅動的,又稱"順序訪問"協議。每當它看到一個新的XML標記(或遇到一個錯誤,或想告訴你什麼事時)就用一個SAX解析器註冊你的句柄,激活你的回調方法。

DOM 定義了分析程序應當顯露的標準命令集,使您可以在程序中訪問 HTML 和 XML 文件內容。DOM的特色是功能強大,但分析時間長,佔用資源多。

SAX是一種輕量型的方法,它是基於事件的XML分析API,功能比較簡單。SAX 提供了處理 XML 文件的快速、低內存的另外一種方法。建議較小的XML文件或須要修改XML時使用DOM接口,速度要求較高時採用SAX接口。

JDOM組合了DOM和SAX的優勢,功能特別強大,還提供了Document,Element,Comment,DocType,Attribute,Text等Java類,能夠利用這些類建立、遍歷並修改JDOM文檔以及把數據庫的錶轉換成XML文件。

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

構建JavaMail的開發環境

 

對於Java平臺而言,JavaMail算是比較晚加入的API,目前在Java網站(http://java.sun.com/products/javamail/)上最新版本是JavaMail1.4API,本章中將使用它來做爲開發工具。

1.mail.jar

讀者能夠到如下的網址下載最新的JavaMail API:

http://java.sun.com/products/javamail/downloads/index.html

下載後獲得的文件名爲javamail-1_4.zip。首先將javamail-1_4.zip解壓縮後,mail.jar是最重要的文件,它裏面就是JavaMail API的類,除mail.jar以外,它還內附dsn.jar、imap.jar、javamailapi.jar、pop3.jar、smtp.jar。

【專家提示】讀取能夠用WinRar工具查看dsn.jar、imap.jar、javamailapi.jar、pop3.jar、smtp.jar幾個文件的內容,會發現它們僅僅是mail.jar文件的拆分而已,因此一般在開發過程當中只須要選用mail.jar文件便可。

2.activation.jar

除了mail.jar以外,讀者還能夠到以下的網址下載最新的JavaBeans Activation Framework(JAF):

http://java.sun.com/products/javabeans/jaf/

JAF目前最新版本爲1.1。

接下來將activation.jar和mail.jar這兩個jar文件拷貝至當前Web應用的「WEB-INF/lib」目錄下,如圖10-1所示:

圖10-1 構建JavaMail開發環境

這些前期工做都準備好後,接下來就是學習JavaMail的開發步驟了。

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

JavaMail API

 

JavaMail應用程序接口(API)用於發送和接收郵件。它不只獨立於平臺,能夠在Windows、Macintosh和Linux上使用,還獨立於底層傳輸協議,能夠使用郵局協議(Post Office Protocol,POP3)和Internet郵件訪問協議(IMAP)接收消息。JavaMail中的消息是使用簡單郵件傳輸協議(Simple Mail Transfer Protocol,SMTP)服務器來發送的。

JavaMail API的工做原理如圖10-2所示。

圖10-2 JavaMail API的工做原理

在圖10-2中,發件人使用Transport對象發送消息。Transport對象將消息提交到網絡,而後發送給收件人。發送給收人的消息存儲在消息服務器中。存儲由許多個文件夾和郵件組成,收件人能夠訪問該文件夾並讀取消息。

在JavaMail API中定義四個主要組件:Message、Folder、Sotre和Session.

Message

Message類是一個抽象類,定義郵件信息以內容類型等屬性,包含標題和內容:標題包含全部的尋址信息,而內容包含數據。Message類的部分經常使用方法以下:

setFrom:指定消息的發件人。

setRecipients:指定收件人的地址。

setSubject:指定消息的主題。

setText:指定消息的文本。

setSentDate:指定消息的發送日期。

setReplyTo:指定消息回覆導向的地址。

getFlags:返回當前消息的標記。

RECENT:指明收到的新消息。

SEEN:指明已查看的消息。

Folder

Folder類是一個抽象類,Folder包含消息和子文件夾。Folder對象用於消息的通訊和管理。默認狀況下,Folder類處於關閉狀態,在這種狀態下不能查看消息和子文件夾。要查看消息和子文件夾,須要使用Folder類的open()方法打開文件夾。Folder類的部分經常使用的方法以下:

open:打開文件,能夠用兩種模式打開文件夾。

READ_ONLY模式:以只讀模式打開文件夾。

READ_WRITE模式:以讀寫模式打開文件夾。在這種模式下,用戶能夠編寫、更新和刪除消息。

create:新建一個文件夾。

exists:檢查文件夾是否存在。

getFolder:得到文件夾。

getMessage:得到指定的消息對象。

Store

Store類是一個抽象類,消息存儲在文件夾(如Inbox和Drafts等)中,而這些文件夾存儲在消息存儲器中(Store)。Store類提供對文件夾的方法並並驗證鏈接,Store類的方法還用於查看消息和文件夾。在鏈接Store以前,用戶須要建立一個會話。建立Store的語法爲:

Store store=obj_session.getStore(protocol);

store.connect(hostname,username,password);

其中,getStore(protocol)得到實現指定協議的Store對象,服務器使用該協議發送和接收消息;connect(hostname,username,password)鏈接到指定地址,並接受主機名、用戶名和密碼做爲參數。

Session

Session類是JavaMail API的最高級別的類。它定義了用來與郵件系統進行通訊的郵件會話,使用戶能夠使用相應的getXXX()方法來訪問Store和Transport對象。還用於存儲信息與服務器創建會話鏈接。Session類可以控制和加載類,能夠建立共享和非共享會話,而共享會話能夠被多個應用程序共享。建立非共享會話的語法爲:

Session session=Session.getDefaultInstance(p,null) ;

其中,Session.getDefaultInstance(p,null)得到默認的Session對象。若是未設置默認對象,就新建一個Session對象並做爲默認對象安裝。p是屬性對象,null表示沒有驗證程序,任何人均可以得到默認會話。

【思考1】JavaMail組件中爲何Message、Folder和Store都被定義爲抽象類?咱們若是取得它們相應的實例對象?

 

這節將學習編寫一個最簡單的發信程序,編寫郵件程序時,使用JavaMail要導入一些包,這些包分別以下:

java..util.*:定義集合框架、日期和時間工具,以及事件模型的集合。

java.io.*:經過數據流,序列化和文件系統來提供系統輸入和輸出。

javax.mail.*:定義對全部郵件系統都通用的類。

javax.mail.internet.*:定義特定於Internet郵件系統的類。

javax.activation.*:由JavaMail API使用,以管理MIME數據。

構造JavaMail發郵件程序涉及的步驟如圖10-3所示。

圖10-3 構建JavaMail發郵件程序的步驟

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

建立JavaMail會話

 

Session對象管理用以與消息傳送系統進行交互的配置選項和用戶驗證信息,建立會話的語法爲:

Properties props = new Properties();

props.put("mail.smtp.host", host);

props.put("mail.smtp.auth", "true"); 

Session mailSession = Session.getDefaultInstance(props);

mailSession.setDebug(true);

其中,props.put("mail.smtp.host", host)指定發送郵件時所使用的SMTP服務器,props.put("mail.smtp.auth", "true")指定發送郵件時所使用的SMTP服務器是否須要進行身份驗證。

其中,mailSession.setDebug(boolean )指定是否在系統控制檯顯示發送郵件的DEBUG信息。如:

  圖10-4 發送郵件的提示信息

【專家提示】setDebug(true)時,會將JavaMail所作的每一步工做的調試信息在系統控制檯上輸出。當發送郵件的數據量較大和數量較多時會引發系統I/O阻塞致使系統運行緩慢,因此當程序員開發調試完成正式發佈運行時要將setDebug(false)。

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

構造消息

 

建立會話和設置屬性以後,構造要發送的消息因爲Message類是一個抽象類,咱們使用Message類的子類MimeMessage來建立構造消息的實例。建立消息實例的語法爲:

//經過會話實例建立新的消息實例

Message message=new MimeMessage(mailSession);

//設置發件人信息

   message.setFrom(new InternetAddress(from)); 

  //設置收件人信息

   message.addRecipient(Message.RecipientType.TO,new InternetAddress(to)); 

   //設置抄送人信息

   message.addRecipient(Message.RecipientType.CC,new InternetAddress("orion@csai.cn")); 

   //設置郵件主題

   message.setSubject(subject); 

   //設置郵件文本內容

   message.setText(content);

   //設置發信日期

   message.setSentDate(new java.util.Date());

  //保存郵件設置信息

   message.saveChanges();

【專家提示】調用完Message類的setFrom()、setRecipients()、setSubject()和setText()方法後,必定要調用saveChanges()方法才保存相應的設置信息。

【專家提示】RecipientType.表示郵件以何種方式傳送給收人相應屬性有TO直送、CC(Carbon Copy,抄送)和BCC(Bind Carbon Copy,暗送)等。

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

發送消息

 

簡單郵件傳輸協議(Simple Mail Transfer Protocol,SMTP)是用於發送郵件的協議。建立會話和構造消息以後,得到Transport對象,而後使用這個類的Send()方法發送消息。

Transport transport = mailSession.getTransport("smtp");

transport.connect(host, user, password);

transport.sendMessage(message, message.getAllRecipients());

transport.close();

其中:getTransport(「SMTP」)返回實現了SMTP協議的傳輸對象。

【例10-1】發送簡單的郵件

先作一個JavaMailSend.html的用戶界面讓用戶輸入數據,而後再傳關到JavaMailSend.jsp作處理。

JavaMailSend.html

<html>

<head>

  <title>CH10 - JavaMailSend.html</title>

<meta http-equiv="Content-Type" content="text/html; charset=GB2312">

</head>

<body>

<h2>利用JavaMail來發送電子郵件</h2>

<form name="Form" method="post" action="JavaMailSend.jsp">

  <p>郵件主機:<input type="text" name="Host" size="30" maxlength="30"></p>

  <p>賬號:<input type="text" name="User" size="30" maxlength="30"></p>

  <p>密碼:<input type="password" name="Password" size="30" maxlength="30"></p>

  <p>寄信人:<input type="text" name="From" size="30" maxlength="30"></p>

  <p>收信人:<input type="text" name="To" size="30" maxlength="30"></p>

  <p>主題:<input type="text" name="Subject" size="30" maxlength="30"></p>

  <p>內容:</p><p><textarea name="Message" cols=40 rows=5></textarea></p>

  <input type="submit" value="發送">

  <input type="reset" value="清除">

</form>

</body>

</html>

JavaMailSend.html頁面的執行結果如圖10-5所示,其中包括郵件主機、在郵件主機上註冊的賬號、密碼、寄信人、收信人、主題和內容。當用戶填好數據後,按下【發送】,就會將窗體數據傳送到JavaMailSend.jsp作發送電子郵件的工做。

圖10-5 JavaMailSend.html的執行結果

JavaMailSend.jsp

<%@ page import="javax.mail.*" %>

<%@ page import="javax.mail.internet.*" %>

<%@ page import="javax.activation.*" %>

<%@ page import="java.util.*,java.io.*" %>

<%@ page contentType="text/html;charset=GBK" %>

<html>

<head>

  <title>CH10 - JavaMailSend.jsp</title>

</head>

<body>

<h2>利用JavaMail來傳送電子郵件 </h2>

<%      //設置中文參數的編碼

        request.setCharacterEncoding("GBK");

        //接收相應的參數

String host   = request.getParameter("Host");

        String user   = request.getParameter("User");

        String password   = request.getParameter("Password");

   String From         = request.getParameter("From");

   String to           = request.getParameter("To");

String Subject      = request.getParameter("Subject");

         String messageText  = request.getParameter("Message");  

        Properties props = new Properties();

        //指定SMTP服務器

        props.put("mail.smtp.host", host); 

        //指定是否須要SMTP驗證

        props.put("mail.smtp.auth", "true"); 

        try {

            //建立JavaMail會話

            Session mailSession = Session.getDefaultInstance(props);

            //在控制檯顯示debug信息

            mailSession.setDebug(true); 

            //構造新的消息對象

            Message message = new MimeMessage(mailSession);

            ////發件人

            message.setFrom(new InternetAddress(From)); 

            //收件人

            message.addRecipient(Message.RecipientType.TO,

                                 new InternetAddress(to)); 

            //抄送人                     

            message.addRecipient(Message.RecipientType.CC,

                                 new InternetAddress("jspadmin@csai.cn")); 

            //郵件主題                     

            message.setSubject(Subject);

            //郵件內容

            message.setText(messageText); 

            //發信日期

            message.setSentDate(new java.util.Date()); 

            message.saveChanges();

            //構建傳送對象

            Transport transport = mailSession.getTransport("smtp");

            transport.connect(host, user, password);

            transport.sendMessage(message, message.getAllRecipients());

            transport.close();

            out.println("<h5>郵件已順利傳送至:"+to+"</h5>");

    }

    catch (MessagingException mex) {

      mex.printStackTrace();

    }

%>

</body>

</html>

圖10-6 JavaMailSend.jsp執行結果

JavaMailSend.jsp範例中,筆者以csai.cn的郵件服務器來作測試,讀者也能夠使用其餘免費電子郵信箱的郵件服務器,只要它有提供SMTP的服務。

【專家提示】若是讀取在運行上述示例時系統控制檯出現以下錯誤提示

圖10-7 錯誤的異常信息

有多是您機器防火牆軟件阻止了郵件傳送程序,請您更改防火牆設置。

登陸orion@csai.cn郵箱查看結果如圖 10-8所示

圖10-8 郵箱查看信件

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

接收郵件

 

接下來將編寫接收郵件程序將前面發送的郵件從服務器上收下來,構造郵件接收程序的步驟如圖10-9所示。

圖10-9 構造郵件接收程序

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

登陸Store

 

Store對象具備一個用於鏈接到Store的connect()方法。此方法提供簡單的驗證,要求輸入用戶名和密碼。鏈接Store的語法爲:

Properties props=new Properties();

  props.put("mail.pop3.host",host);

  Session mailsession=Session.getDefaultInstance(props);

  Store store=mailsession.getStore("pop3");

  store.connect(host,user,password);

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

列出INBOX中的郵件

 

文件夾名INBOX是一個保留名字,表明全部消息第一次到達系統的位置。收到的消息存儲在消息存儲器中的文件夾中。列出INBOX中全部消息的語法爲:

  Folder inbox=store.getDefaultFolder().getFolder("INBOX");

  inbox.open(Folder.READ_WRITE);

  Message[] message=inbox.getMessages();

其中,getFolder("INBOX") 將得到INBOX文件夾並將其存儲在對象中。

inbox.open(Folder.READ_WRITE) 將以讀寫模式打開文件夾,採用這種模式在收取服務器端的郵件能夠刪除服務器端的副本並釋放服務器空間。

getMessage() 返回文件夾中全部消息對象。

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

讀取消息

 

在JavaMail中,POP3是用於接收消息的協議。要讀取消息,可鏈接到Store並打開指定文件夾,檢索數組中的消息,讀取消息的語法爲:

for (int i = 0; i < message.length; i++) {

    message[i].setFlag(Flags.Flag.DELETED,true);

    out.println("郵件主題:"+message[i].getSubject()+"<br>");

    out.println("郵件發送者:"+message[i].getFrom()[0]+"<br>");

    out.println("發送時間:"+message[i].getSentDate()+"<br>");

    out.println("內容:"+message[i].getContent()+"<br>");   

  }  

  inbox.close(true);

  store.close();

其中,setFlag(Flags.Flag.DELETED,true) 將消息標記爲刪除。

 Inbox.close(true) 關閉INBOX文件夾,參數爲true表示刪除其中標記爲刪除的消息。

【專家提示】在讀取消息後請使用Store對象的close()方法關閉存儲器,若是再次鏈接到一個已經鏈接的存儲器將發生錯誤。

【例10-2】接收郵件

先來作一個JavaMailReceiver.html的用戶界面讓用戶輸入數據,而後再傳送到JavaMailReceiver.jsp作處理。

JavaMailReceiver.html

<html>

<head>

  <title>CH10 - JavaMailReceiver.html</title>

<meta http-equiv="Content-Type" content="text/html; charset=GB2312">

</head>

<body>

<h2>利用JavaMail來接收電子郵件</h2>

<form name="Form" method="post" action="JavaMailReceiver.jsp">

  <p>郵件主機:<input type="text" name="Host" size="30" maxlength="30"></p>

  <p>賬號:<input type="text" name="User" size="30" maxlength="30"></p>

  <p>密碼:<input type="password" name="Password" size="30" maxlength="30"></p>

  <input type="submit" value="接收">

  <input type="reset" value="清除">

</form>

</body>

</html>

JavaMailReceiver.html的執行結果如圖10-10所示,其中包括郵件主機、在郵件主機上註冊的賬號、密碼。當用戶填好數據後,按下【接收】,就會將窗體數據傳送到JavaMailReceiver.jsp作接收電子郵件的工做。

圖10-10 JavaMailReceiver.html執行結果

JavaMailReceiver.jsp

<%@ page import="javax.mail.*" %>

<%@ page import="javax.mail.internet.*" %>

<%@ page import="javax.activation.*" %>

<%@ page import="java.util.*,java.io.*" %>

<%@ page contentType="text/html;charset=GBK" %>

<html>

<head>

  <title>CH10 - JavaMailSend.jsp</title>

</head>

<body>

<h2>利用JavaMail來接收電子郵件 </h2>

<%   

//設置中文參數的編碼

request.setCharacterEncoding("GBK");

//接收相應的參數

String host   = request.getParameter("Host");

String user   = request.getParameter("User");

String password   = request.getParameter("Password");

try {

  Properties props=new Properties();

  //指定的POP3郵件服務器

  props.put("mail.pop3.host",host);

  //建立郵件會話

  Session mailsession=Session.getDefaultInstance(props);

  //建立Store對象

  Store store=mailsession.getStore("pop3");

  //登陸到Store

  store.connect(host,user,password);

  //得到INBOX文件夾

  Folder inbox=store.getDefaultFolder().getFolder("INBOX");

  //以讀寫模式打開INBOX文件夾

  inbox.open(Folder.READ_WRITE);

  //從INBOX文件夾中取得全部的消息對象              

  Message[] message=inbox.getMessages();

  //循環讀取消息

  for (int i = 0; i < message.length; i++) {

    message[i].setFlag(Flags.Flag.DELETED,true);

    out.println("郵件主題:"+message[i].getSubject()+"<br>");

    out.println("郵件發送者:"+message[i].getFrom()[0]+"<br>");

    out.println("發送時間:"+message[i].getSentDate()+"<br>");

    out.println("內容:"+message[i].getContent()+"<br>");   

  }  

  //關閉文件夾,並刪除標記爲刪除的消息

  inbox.close(true);

  //關閉登陸的Store

  store.close();

}

catch (MessagingException ex) {

  ex.printStackTrace();

}

%>

</body>

</html>

圖10-11 JavaMailReceiver.jsp執行結果

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

Multipart消息

 

前面我講述的郵件消息都是隻包含文本的消息,在實際應用中一個郵件消息一般除了文本內容以外還包含圖片、HTML網頁和附件文件等。在JavaMail中一條郵件消息可由多個部分組成,每一部分是一個BodyPart(報文部分),或更特殊一點,在操做MIME消息時則是MimeBodyPart。不一樣的報文部分組合到一個稱爲Multipart的容器中,或者又更特殊一點,是一個MimeMultipart容器(如圖 10-12 所示)。要發送一個複雜的郵件消息您要建立每個用於消息文本的部分,並將這多個部分組合成一個multipart(多個部分)。而後您能夠把這個multipart添加到一個合適的註明地址的消息中併發送它。建立Multipart消息的步驟如圖10-13所示。

【例10-2】發送帶附件的郵件

接下來將演示發送一個內容爲HTML格式而且帶有附件的郵件消息指導讀者如何構造Multipart消息。示例的作法是:先將處理好的郵件內容存入到MimeBodyPart對象中;而後將文件存入到另外一個MimeBodyPart對象中;最後把兩個MimeBodyPart對象(一份是郵件內容自己,另外一份是文本或HTML部分)所有存入到Multipart對象,合而爲一加入Message對象中,發送到收信人的郵件服務器。附件的功能須要使用到上傳文件的機制,所以使用了歐萊禮的文件上傳組件。

JavaMailAttachment.html頁面用於接受用戶郵件消息數據錄入並將請求傳送給JavaMailAttachment.jsp處理,JavaMailAttachment.html頁面的源代碼以下。

JavaMailAttachment.html

<html>

<head>

  <title>CH10 - JavaMailAttachment.html</title>

<meta http-equiv="Content-Type" content="text/html; charset=GB2312">

</head>

<body>

<h2>利用JavaMail來傳送電子郵件 - 附件</h2>

<form name="SendMessage" Method="post" action="JavaMailAttachment.jsp" enctype="multipart/form-data">

  <p>郵件主機:<input type="text" name="Host" size="30" maxlength="30"></p>

  <p>賬號:<input type="text" name="User" size="30" maxlength="30"></p>

  <p>密碼:<input type="password" name="Password" size="30" maxlength="30"></p>

  <p>寄信人:<input type="text" name="From" size="30" maxlength="30"></p>

  <p>收信人:<input type="text" name="To" size="30" maxlength="30"></p>

  <p>主題:<input type="text" name="Subject" size="30" maxlength="30"></p>

  <p>格式:<select name="Type" size="1">

<option value="text/plain">Text</option>

<option value="text/html">HTML</option>

           </select></p>

  <p>附件:<input type="file" name="FileName" size="20" maxlength="20"></p>         

  <p>內容:</p><p><textarea name="Message" cols=40 rows=5></textarea></p>

  <input type="submit" value="傳送">

  <input type="reset" value="清除">

</form>

</body>

</html>

JavaMailAttachment.html頁面的運行結果如圖 10-14所示。

圖10-14 avaMailAttachment.html執行結果

JavaMailAttachment.jsp

<%@ page import="javax.mail.*" %>

<%@ page import="javax.mail.internet.*" %>

<%@ page import="javax.activation.*" %>

<%@ page import="java.util.*,java.io.*" %>

<%@ page import="com.oreilly.servlet.MultipartRequest" %>

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

  <title>CH17 - JavaMail2.jsp</title>

</head>

<body>

<h2>利用JavaMail來傳送電子郵件 - 附件</h2>

<%

InternetAddress[] address = null;

request.setCharacterEncoding("GBK");

MultipartRequest multi = new MultipartRequest(request , "." , 5*1024*1024 , "GBK");

String host   = multi.getParameter("Host");

String user   = multi.getParameter("User");

        String password   = multi.getParameter("Password");

        String From   = multi.getParameter("From");

String to           = multi.getParameter("To");

String Subject      = multi.getParameter("Subject");

String type    = multi.getParameter("Type");

String messageText  = multi.getParameter("Message");

String FileName     = multi.getFilesystemName("FileName");

try {

  // 設定所要用的Mail 服務器和所使用的傳輸協議

   Properties props = new Properties();

                 props.put("mail.smtp.host", host); //指定SMTP服務器

                 props.put("mail.smtp.auth", "true"); //指定是否須要SMTP驗證

  // 產生新的Session 服務

   Session mailSession = Session.getDefaultInstance(props);

   Message msg = new MimeMessage(mailSession);

  // 設定傳送郵件的發信人

  msg.setFrom(new InternetAddress(From));

  // 設定傳送郵件至收信人的信箱

  address = InternetAddress.parse(to,false);

  msg.setRecipients(Message.RecipientType.TO, address);

  // 設定信中的主題 

  msg.setSubject(Subject);

  // 設定送信的時間

  msg.setSentDate(new Date());

  if (FileName != null)

  {

      File file = new File(FileName);

 // 若是有附件,先將郵件內容部分存起來

          MimeBodyPart mbp1 = new MimeBodyPart();

   // 設定郵件內容的類型爲 text/plain 或 text/html

  mbp1.setContent(messageText, type + ";charset=GB2312");

          // 再來對附件做處理

          MimeBodyPart mbp2 = new MimeBodyPart();

          FileDataSource fds = new FileDataSource(FileName);

          mbp2.setDataHandler(new DataHandler(fds));

          mbp2.setFileName(MimeUtility.encodeText(fds.getName(), "GB2312", "B"));

          // 最後再將二者整合起來,看成一份郵件送出

          Multipart mp = new MimeMultipart();

          mp.addBodyPart(mbp1);

          mp.addBodyPart(mbp2);

          msg.setContent(mp);

   }else{

          // 若沒有附件時,就直接存郵件內容

         msg.setContent(messageText,type + ";charset=GB2312");

   }

        Transport transport = mailSession.getTransport("smtp");

        transport.connect(host, user, password);

        transport.sendMessage(msg, msg.getAllRecipients());

        transport.close();

        out.println("郵件已順利發送至:"+to);

}catch (MessagingException mex){

mex.printStackTrace();

}

%>

</body>

</html>

執行結果如圖 10-15所示:

圖10-15 JavaMailAttachment.jsp的執行結果

郵件服務器上的顯示結果如圖 10-16所示。

圖10-16 郵件服務器上顯示結果

【專家提示】JavaMail API只支持ASCII單字節字符串處理,爲了解決附件中文文件名的問題,咱們必須加上一段程序來作轉碼工做。

mbp2.setFileName(MimeUtility.encodeText(fds.getName(), "GB2312", "B"));

其功能是將多字節Unicode字符串轉化爲單字節US-ASCII字符串。

【專家提示】發送附件郵件存在支持附件大小的問題,郵件消息的大小要受到您的SMTP服務器的限制,而不是由JavaMail API限制的。

 
 
 
 

第 10 章:JavaMail做者:鄧子云赫斌等    來源:希賽網    2014年03月06日

 

小結

 

JavaMail含有一組用於發送和接收郵件消息的API,通常地發送郵件使用SMTP協議,接收郵件使用POP3協議。

Message類是一個抽象類,可帶有消息的尋址信息和內容;Folder類是一個抽象類,包含子文件夾和消息等內容;Store類是一個抽象類,定義用於訪問文件夾和檢索消息的協議, 要查看文件夾和消息,須要使用它的connect()方法;編寫發送郵件的程序經常使用Transport類的send()方法發送消息;Multipart消息是Message類的對象,Multipart消息能夠有多個BodyPart。

【思考1】JavaMail組件中爲何Message、Folder和Store都被定義爲抽象類?咱們若是取得它們相應的實例對象?

答:JavaMail API定義了一個用來管理郵件的通用接口,而且JavaMail容許程序員經過API裏的接口來撰寫本身的應用程序,而後在執行時期再請求使用某種類型的處理。這樣程序員採用JavaMail編寫郵件消息收發程序具備適應於任何郵件服務器的通用性和跨平臺的優勢。Message類咱們通常使用其相應的子類MimeMessage建立實例,Store類實例用Session的getStore()方法取得,Folder類實例用Store的getFolder()方法取得。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

表達式語言簡介

 

第11章  表達式與標籤

【本章專家知識導學】

JSP標籤是在JSP頁面中對JavaBean的封裝功能進一步補充,從而實現Java代碼與HTML分離的一種服務器端程序。這樣作的目的是讓程序的實現與顯示分離,分離的好處是讓美工專心作界面,開發人員專心實現業務。

本章旨在引導讀者學習表達式語言(EL)和JSTL標籤以及如何自定義標籤,將詳細介紹EL的語法和各類運算符的使用,JSTL標籤中的核心標籤、格式標籤、SQL標籤、XML標籤等標籤的用法,最後介紹自定義標籤的實現。經過學習本章內容後讀者應可以利用EL和標籤來開發Web應用,取代傳統直接在頁面上嵌入Java程序的作法,以提升程序的可閱讀性和可維護性。

11.1  表達式語言簡介

表達式語言(EL)是JSP技術的主要特色之一。Java社區組織(JCP,Java Community Process)的JSP標準標籤庫專家組和JSP2.0專家組共同開發了表達式語言。取代傳統直接在頁面上嵌入Java腳本程序以完成複雜功能的作法,以提升程序的閱讀性、維護性和方便性。EL表達式可用於:

靜態文本:包含EL表達式,其值在運行時計算出來。求值後,EL表達式被計算值替換。

標準標籤和自定義標籤的屬性,以幫助顯示網頁上的動態內容。

讀取JavaBean屬性,使用EL表達式能夠簡潔地讀出JavaBean的屬性值。

下面演示一個JSP使用EL示例程序。

【例11-1】在JSP中應用EL的示例

el_example.jsp

<%@ page language="java" contentType="text/html; charset=GBK"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>       

    <title>EL表達式示例</title>

 </head>  

  <body>

    ${"請選購商品"} <br>

    <form action="el_example1.jsp" method="post">

    <select name="trade">

    <option value="專家導學JSP應用開發">專家導學JSP應用開發</option>

<option value="專家導學Java面向對象編程">專家導學Java面向對象編程</option>

    </select>

    單價:<input type="text" name="price"/>

    數量:<input type="text" name="count"/>

    <input type="submit" value="提交">

    </form>

  </body>  

</html>

el_example.jsp運行結果如圖11-1所示。

圖11-1 el_example.jsp運行結果

選擇相應的商品填寫單價和購買數量後點擊「提交」按鈕將參數提交至el_example1.jsp頁面處理。el_example1.jsp將利用JavaBean接收參數並用EL顯示購買結果。

TradeBean.java

package eldemo;

/**

 * 定義接收商品定單信息的JavaBean

 * @author Administrator * 

 */

public class TradeBean {

private String trade;// 商品名稱

private int count;// 購買數量

private float price;//單價

public int getCount() {

return count;

}

public void setCount(int count) {

this.count = count;

}

public float getPrice() {

return price;

}

public void setPrice(float price) {

this.price = price;

}

public String getTrade() {

return trade;

}

public void setTrade(String trade) {

this.trade = trade;

}

}

el_example1.jsp

<%@ page language="java" contentType="text/html; charset=GBK"%>

<jsp:directive.page import="eldemo.TradeBean"/>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>     

    <title>EL表達式示例</title>

  </head>  

  <%request.setCharacterEncoding("GBK"); %>

  <jsp:useBean id="myorder" class="eldemo.TradeBean">

  <jsp:setProperty name="myorder" property="*"/>

  </jsp:useBean>

  <body>

    您購買的商品是: ${myorder.trade}<br>

    商品單價是:${myorder.price}<br>

    您購買的數量是:${myorder.count}<br>

    您應支付的總金額是:${myorder.price*myorder.count }

  </body>

</html>

el_example1.jsp的運行結果如圖11-2所示。

圖11-2 el_example1.jsp的運行結果

【專家提示】倘若您所用的JSP容器只支持Servlet 2.3/JSP 1.2,如:Tomcat 4.1.29,就不能在JSP 網頁中直接使用EL,須要配合JSTL標籤一塊兒使用,直接使用EL必須安裝支持Servlet 2.4/JSP2.0或以上版本的JSP容器如:Tomcat5.0以上的版本。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

EL使用語法

 

JSP中EL表達式語言的使用語法以下:

${EL expression}

其中:

「$」表示EL中表達式的開始;

「{」是起始分隔符;

EL_expression指定表達式;

「}」是結束分隔符;

接下來將從變量,常量、隱式對象、算術運行符和保留字等多個方面講解EL的具體使用方法。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

.與 [ ] 運算符

 

EL 提供「.」和「[ ]」兩種運算符來存取數據。下列二者所表明的意思是同樣的:

${myorder.trade}

等同於

${ myorder["trade"] }

. 和 [ ] 也能夠同時混合使用,以下:

${pageScope[「myorder」].trade}

回傳結果爲你選購中商品的名稱。

不過,如下狀況,二者會有差別:

當要存取的屬性名稱中包含一些特殊字符,如 . 或 – 等並不是字母或數字的符號,就必定要使用「[ ]」,例如:

${ myorder.trade-Name }

上述是不正確的方式,應當改成:

${ myorder ["trade-Name"] }

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

變量與文字常量

 

EL變量能夠用於存儲和訪問JSP程序中的值。默認狀況下,JSP表達式${myorder}的計算結果與調用pageContext.findAttribute("myorder")同樣。EL表達式中的變量能夠引用存儲在標準範圍(page、request、session和application範圍)中的屬性。變量在標準範圍中的默認搜索順序是page、request、session和application。若是須要,能夠使用toString()方法將變量的返回值轉換成爲字符串;若是找不到變量,則返回null值。

在 EL 表達式中,數字、字符串、布爾值和 null 均可以被指定爲文字值。字符串能夠用單引號或雙引號定界。布爾值被指定爲 true 和 false 。

6.5E+3(或6.5E3) 表示雙精度值6500.0;

7D 表示雙精度值7.0;

.01f 表示單精度值0.01;

'Welcome you'和"Welcom you"都是合法的字符串。

【專家提示】在EL中,"應表示爲\",'應表示爲 \', \應表示爲\\,\(斜槓)稱爲轉義符。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

EL保留字

 

EL保留字如表11-1所示。

表11-1    EL保留字

 

程序員編程過程當中,若是要給變量命名,應該避開上述的名字,以避免程序編譯時發生錯誤。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

隱式對象

 

EL隱式對象總共有11 個,詳見表11-2所示。

表11-2 EL隱式對象

表 11-2 中列出了 11 個 EL 隱式對象的標識符。不要將這些對象與 JSP 隱式對象混淆,其中只有一個對象是它們所共有的。儘管 JSP 和 EL 隱式對象中只有一個公共對象( pageContext ),但經過 EL 也能夠訪問其它 JSP 隱式對象。緣由是 pageContext 擁有訪問全部其它八個 JSP 隱式對象的特性。

其他全部 EL 隱式對象都是映射,能夠用來查找對應於名稱的對象。能夠用它們來查找特定做用域中的標識符,而不用依賴於 EL 在缺省狀況下使用的順序查找過程。

接下來咱們經過一個示例演示EL中隱式對象的使用方法。

【例11-2】使用EL隱式對象

UserBean.java

package eldemo;

public class UserBean {

    private String name;

    private String age;

    public UserBean() {

    }

    public void setName(String name) {

        this.name = name;

    }

    public void setAge(String age) {

        this.age = age;

    }

    public String getName() {

        return name;

    }

    public String getAge() {

        return age;

    }

}  

setimplicit.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="eldemo.*" %>

<html>

<head>

<title>

setimplicit

</title>

</head>

<body bgcolor="#ffffff">

<%

UserBean user=new UserBean();  

user.setName("張三");

user.setAge("18");

request.setAttribute("user",user);

UserBean user1=new UserBean();

user1.setName("李四");

user1.setAge("18");

session.setAttribute("user",user1);

pageContext.forward("getimplicit.jsp?bar=foo");

%>

</body>

</html>

getimplicit.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<head>

<title>

getimplicit

</title>

</head>

<body bgcolor="#ffffff">

我是${user.name}<br>

我仍是${sessionScope['user'].name}<br>

參數是:${param.bar}<br>

主機是:${header['host']}<br>

你的瀏覽器是:${header['User-Agent']}

</body>

</html>

setimplicit.jsp往JSP容器的不一樣做用域中存入變量,而後調用getimplicit.jsp將其取。運行結果如圖11-3所示。

圖11-3 setimplicit.jsp運行結果

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

EL運算符

 

EL 還包括了幾個用來操做和比較 EL 表達式所訪問數據的運算符,表11-3 中彙總了這些運算符。

表11-3    EL運算符

 

算術運算符支持數值的加法、減法、乘法和除法。還提供了一個求餘運算符。對幾個 EL 表達式應用算術運算符的結果是將該算術運算符應用於這些表達式返回的數值所得的結果。 

【例11-3】使用EL的算術運算符

Arithmetic.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

  <head>

    <title>

      基本的算述運算

    </title>

  </head>

  <body bgcolor="#ffffff">

    <h1>

      基本的算述運算表達式

    </h1>

    <table border="1">

      <thead>

        <td><b>EL Expression</b></td>

        <td><b>Result</b></td>

      </thead>

      <tr>

        <td>\${1}</td>

        <td>${1}</td>

      </tr>

      <tr>

        <td>\${1 + 2}</td>

        <td>${1 + 2}</td>

      </tr>

      <tr>

        <td>\${1.2 + 2.3}</td>

        <td>${1.2 + 2.3}</td>

      </tr>

      <tr>

        <td>\${1.2E4 + 1.4}</td>

        <td>${1.2E4 + 1.4}</td>

      </tr>

      <tr>

        <td>\${-4 - 2}</td>

        <td>${-4 - 2}</td>

      </tr>

      <tr>

        <td>\${21 * 2}</td>

        <td>${21 * 2}</td>

      </tr>

      <tr>

        <td>\${3/4}</td>

        <td>${3/4}</td>

      </tr>

      <tr>

        <td>\${3 div 4}</td>

        <td>${3 div 4}</td>

      </tr>

      <tr>

        <td>\${3/0}</td>

        <td>${3/0}</td>

      </tr>

      <tr>

        <td>\${10%4}</td>

        <td>${10%4}</td>

      </tr>

      <tr>

        <td>\${10 mod 4}</td>

        <td>${10 mod 4}</td>

      </tr>

      <tr>

        <td>\${(1==2) ? 3 : 4}</td>

        <td>${(1==2) ? 3 : 4}</td>

      </tr>

    </table>

  </body>

</html>

頁面運行結果如圖11-4所示。

圖11-4 Arithmetic.jsp運行結果

關係運算符容許比較數字或文本數據,比較的結果做爲布爾值返回。邏輯運算符容許合併布爾值,返回新的布爾值,還能夠將 EL 邏輯運算符應用於嵌套的關係或邏輯運算符的結果。

最後一種 EL 運算符是 empty ,它對於驗證數據特別有用。 empty 運算符采用單個表達式做爲其變量(也即, ${empty input} ),並返回一個布爾值,該布爾值表示對錶達式求值的結果是否是「空」值。求值結果爲 null 的表達式被認爲是空,即無元素的集合或數組。若是參數是對長度爲零的 String 求值所得的結果,則 empty 運算符也將返回 true 。

【例11-4】使用EL的關係運算符

Comparisons.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

  <head>

    <title>

      基本的關係運算

    </title>

  </head>

  <body bgcolor="#ffffff">

    <h1>

      基本的關係運算示例

    </h1>

    <blockquote>

      <u><b>數字處理</b></u>

      <code>

        <table border="1">

          <thead>

            <td><b>EL Expression</b></td>

            <td><b>Result</b></td>

          </thead>

          <tr>

            <td>\${1 < 2}</td>

            <td>${1 < 2}</td>

            </tr>

            <tr>

              <td>\${1 lt 2}</td>

              <td>${1 lt 2}</td>

            </tr>

            <tr>

              <td>\${1 &gt; (4/2)}</td>

              <td>${1 > (4/2)}</td>

            </tr>

            <tr>

              <td>\${1 &gt; (4/2)}</td>

              <td>${1 > (4/2)}</td>

            </tr>

            <tr>

              <td>\${4.0 &gt;= 3}</td>

              <td>${4.0 >= 3}</td>

            </tr>

            <tr>

              <td>\${4.0 ge 3}</td>

              <td>${4.0 ge 3}</td>

            </tr>

            <tr>

              <td>\${4 &lt;= 3}</td>

              <td>${4 <= 3}</td>

              </tr>

              <tr>

                <td>\${4 le 3}</td>

                <td>${4 le 3}</td>

              </tr>

              <tr>

                <td>\${100.0 == 100}</td>

                <td>${100.0 == 100}</td>

              </tr>

              <tr>

                <td>\${100.0 eq 100}</td>

                <td>${100.0 eq 100}</td>

              </tr>

              <tr>

                <td>\${(10*10) != 100}</td>

                <td>${(10*10) != 100}</td>

              </tr>

              <tr>

                <td>\${(10*10) ne 100}</td>

                <td>${(10*10) ne 100}</td>

              </tr>

            </table>

          </code>

          <br>

            <u><b>字符的處理</b></u>

            <code>

              <table border="1">

                <thead>

                  <td><b>EL Expression</b></td>

                  <td><b>Result</b></td>

                </thead>

                <tr>

                  <td>\${'a' &lt; 'b'}</td>

                  <td>${'a' < 'b'}</td>

                  </tr>

                  <tr>

                    <td>\${'hip' &gt; 'hit'}</td>

                    <td>${'hip' > 'hit'}</td>

                  </tr>

                  <tr>

                    <td>\${5 &gt; '4'}</td>

                    <td>${5 > '4'}</td>

                  </tr>

                </table>

              </code>

            </blockquote>

          </body>

</html>

頁面的運行結果如圖11-5所示。

圖11-5 Comparisons.jsp運行結果

【例11-5】使用EL的邏輯運算符

logic.jsp

<%@ page contentType="text/html; charset=GBK"%>

<html>

<body>

<h1>

邏輯 EL

</h1>

<table border="1">

<tr>

<td>

<b>運算</b>

</td>

<td>

<b>EL 表達式</b>

</td>

<td>

<b>結果</b>

</td>

</tr>

<tr>

<td>

</td>

<td>

${'${'}true and true}

</td>

<td>

${true and true}

</td>

</tr>

<tr>

<td>

</td>

<td>

${'${'}true && false}

</td>

<td>

${true && false}

</td>

</tr>

<tr>

<td>

</td>

<td>

${'${'}true or true}

</td>

<td>

${true or true}

</td>

</tr>

<tr>

<td>

</td>

<td>

${'${'}true || false}

</td>

<td>

${true || false}

</td>

</tr>

<tr>

<td>

</td>

<td>

${'${'}not true}

</td>

<td>

${not true}

</td>

</tr>

<tr>

<td>

</td>

<td>

${'${'}!false}

</td>

<td>

${!false}

</td>

</tr>

</table>

${empty user.name}

</body>

</html>

頁面的運行結果如圖11-6所示。

11-6 logic.jsp運行結果

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

禁用EL表達式計算

 

JSP EL表達式包含在符號「${」與「}」之間。在某些特殊應用中我須要Java服務器不自動執行EL表達式計算工做。所以,有時須要禁用EL表達式,在JSP2.0中默認啓用JSP EL表達式。

在JSP頁面中禁用EL表達式計算語法以下:

<%@page  isELIgnored="true|false"%>

其中,page表示頁面指令,isELIgnored肯定是否應忽略對EL表達式進行計算。

若是isELIgnored設置爲true,當EL表達式在靜態文本或標籤屬性中出現時將被忽略;若是isELIgnored設置爲false,EL表達式則由JSP容器進行計算。

下面的例子將演示如何經過使用page指令來禁用或啓用EL表達式計算。

【例11-6】禁用EL表達式

eldisable.jsp

<%@ page contentType="text/html; charset=GBK" isELIgnored="true"%>

<html>

<head>

<title>演示表達式的禁用</title>

</head>

<body bgcolor="#ffffff">

<h1>

EL表達式禁用

</h1>

<%

for (int i = 0; i < 10; i++) {

%>

${header["host"]}

<br>

<%

}

%>

</body>

</html>

頁面的運行結果如圖11-7所示。

圖11-7 eldisable.jsp運行結果

能夠看到頁面把EL表達式完整輸出了,並無進行運算,這是由於禁用了EL表達式後,Web容器並能識別EL表達式。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

JSTL標籤

 

JSTL(JavaServer Pages Standard TagLibrary,JSP標準標籤庫)包含用於編寫和開JSP頁面的一組標準標籤,它可爲用戶提供一個無腳本環境,在此環境中,用戶能夠使用標籤編寫代碼,而無需使用Java腳本。JSTL包含有許多實用的標籤,其中迭代標籤和條件標籤用於處理頁面流程控制,國際化標籤爲用戶提供所需的特定區域的語言和輸出格式,SQL標籤用於訪問數據庫和更新數據庫表,XML標籤庫用於操做和解析XML數據。

圖11-8 JSTL標籤庫

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

安裝使用JSTL1.1

 

JSTL1.1 必須在支持Servlet 2.4 且JSP 2.0 以上版本的容器中才可以使用。JSTL 主要由Apache組織的Jakarta Project 所實現。讀者能夠到以下的網址下載獲得JSTL的安裝包:

http://jakarta.apache.org/builds/jakarta-taglibs/releases/standard/ 

下載後獲得的文件爲jakarta-taglibs-standard-current.zip。下載完後解壓縮,將lib目錄 中的jstl.jar、standard.jar 複製到當前Web應用的「WEB-INF\lib」中,此後就能夠在當前Web應用的JSP 網頁中使用JSTL了。除了複製 .jar 文件外,最好也把tld 文件的目錄也複製到WEB-INF 中,以便往後使用。接下來將介紹幾類經常使用的JSTL標籤的使用方法。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

核心標籤庫:通用標籤

 

JSTL標籤核心標籤庫包含通用標籤、條件標籤、迭代標籤、URL標籤。通用標籤用於操做JSP頁面建立存儲在隱式對象中的變量;條件標籤用於對JSP頁面中的代碼進行條件判斷和處理;迭代標籤用於循環遍歷一個對象集合;URL標籤用於控制頁面的跳轉動做。

圖11-9 JSTL的核心標籤庫

要在JSP頁面中使用核心標籤庫,首先須要導入核心標籤庫的URI。

<%taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

【專家提示】上述的功用在於聲明將使用JSTL 的核心標籤庫。倘若沒有上述聲明指令,將沒法使用JSTL的核心功能,這是讀者在使用JSTL 時要特別注意的地方。

在通用標籤中,下面將重點介紹<c:set>、<c:out>、<c:remove>三個標籤的使用方法。

<c:set>標籤主要用來將變量儲存至JSP 隱式對象中或是JavaBean 的屬性中,其語法爲:

語法1:將 value 的值儲存至範圍爲scope 的 varName 變量之中

<c:set value="value" var="varName" [scope="{ page|request|session|application }"]/>

語法2:將本體內容的數據儲存至範圍爲scope 的 varName 變量之中

<c:set var="varName" [scope="{ page|request|session|application }"]>

本體內容

</c:set>

value:要被儲存的值

var:欲存入的變量名稱

scope:指定變量的JSP 範圍

<c:out>標籤主要用來顯示數據的內容,就像是 <%= scripting-language %> 同樣,其語法爲:

語法1:沒有本體(body)內容

<c:out value="value" [escapeXml="{true|false}"] [default="defaultValue"] />

語法2:有本體內容

<c:out value="value" [escapeXml="{true|false}"]>

default value

</c:out>

value:須要顯示出來的值。

Default:若是value 的值爲null,則顯示default 的值。

escapeXml:是否轉換特殊字符,如:<轉換成&lt;

<c:remove>標籤主要用來移除變量,其語法爲:

<c:remove var="varName" [scope="{ page|request|session|application }"] />

var:欲移除的變量名稱。

scope:var變量的JSP 範圍

接下來看一個使用通用標籤的演示示例。

【例11-7】使用通用標籤

coredemo1.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>

<head>

<title>JSTL標籤庫中通用標籤</title>

</head>

<body bgcolor="#ffffff">

<P>

該 JSP 頁面在一個 session 做用域內的變量中存儲 sessionvariable, 此 Web 應用程序中的其餘 JSP

頁面能夠訪問此變量.

</p>

<c:set var="sessionvariable" scope="session">

      ${80+8}

    </c:set>

在刪除 sessionvariable 以前先顯示它的值:

<c:out value="${sessionScope.sessionvariable}" />

<c:remove var="sessionvariable" scope="session" />

<br>

顯示並刪除後的 sessionvariable 的值.

<br>

<c:out value="${sessionvariable}"> sessionvariable爲NULL </c:out>

</body>

</html>

頁面的運行結果如圖11-10所示。

圖11-10 coredemo1.jsp運行結果

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

核心標籤庫:條件標籤

 

條件標籤中將重點介紹<c:if>、<c:choose>、<c:when>和<c:otherwise>四個標籤的使用方法。

<c:if>標籤用於有條件地執行代碼。若是test屬性的值爲true,則會執行<c:if>標籤的標籤體。該標籤是一個容器標籤,其語法爲:

語法1:沒有標籤體內容(body)

<c:if test="testCondition" var="varName"

[scope="{page|request|session|application}"]/>

語法2:有標籤體內容

<c:if test="testCondition" [var="varName"]

[scope="{page|request|session|application}"]>

本體內容

</c:if>

test:若是表達式的結果爲true,則執行標籤體內容,false則相反

var:用來儲存test 運算後的結果,即true 或false

scope:變量的JSP 範圍

<c:choose>標籤相似於Java語言的switch語句,它用於執行條件語句塊。

<c:choose>

本體內容( <when> 和 <otherwise> )

</c:choose>

<c:when>標籤的用途就和Java程序中用的when 同樣。

<c:otherwise>標籤在同一個 <c:choose>標籤中,當全部 <c:when>標籤的條件都沒有成立時,則執行<c:otherwise>標籤的標體內容。

【例11-8】使用條件標籤

coredemo2.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>

  <head>

    <title>

      JSTL標籤庫中條件標籤

    </title>

  </head>

  <body bgcolor="#ffffff">

    <%

    int i=(int)(Math.random()*10);

    pageContext.setAttribute("signalStrength",new Integer(i));

    %>

  <c:if test="${pageScope.signalStrength < 5}">

        <c:set var="signalFailure" value="true"

        scope="page" />

    </c:if>

    <h1> 使用 If 和 Choose</h1>

    <c:choose>

        <c:when test="${pageScope.signalFailure == true}">

            信號斷開

        </c:when>

        <c:otherwise>

            信號打開

        </c:otherwise>

    </c:choose>

  </body>

  </html>

頁面的運行結果如圖11-11所示。

圖11-11 coredemo2.jsp運行結果

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

核心標籤庫:迭代標籤

 

在跌代標籤中咱們將介紹<c:forEach>標籤和<c:forTokens>標籤這兩個標籤的使用方法。

<c:forEach>標籤爲循環控制,它能夠將集合(Collection)中的成員循序瀏覽一遍。運做方式爲當條件符合時,就會持續重複執行<c:forEach>標籤的標籤體內容。其語法爲:

語法1:迭代一集合對象之全部成員

<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"] 

[begin="begin"][end="end"] [step="step"]>

本體內容

< /c:forEach>

語法2:迭代指定的次數

<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin" end="end"

[step="step"]>

本體內容

</c:forEach>

var:用來存放當前指到的成員。

items:被迭代的集合對象(集合對象類型爲Arrays、Collection、Iterator、Enumeration、Map)。

varStatus:用來存放當前指到的相關成員信息。

begin:開始的位置,倘若有begin 屬性時,begin 必須大於等於 0。

end:結束的位置默認值最後一個成員,倘若有end 屬性時,end必須大於begin。

step:每次迭代的間隔數,倘若有step 屬性時,step 必須大於等於0。

<c:forTokens>標籤用來瀏覽一字符串中全部的成員,其成員是由定義符號(delimiters)所分隔的。使用語法以下:

<c:forTokens items="stringOfTokens" delims="delimiters" [var="varName"]

[varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"]>

本體內容

</c:forTokens>

var:用來存放如今指到的成員。

items:被迭代的字符串。

delims:定義用來分割字符串的字符。

varStatus:用來存放如今指到的相關成員信息。

begin:開始的位置,倘若有begin 屬性時,begin 必須大於等於 0。

end:結束的位置,倘若有end 屬性時,end必須大於begin。。

step:每次迭代的間隔數,倘若有step 屬性時,step 必須大於等於0。

接下來咱們來看一個跌代標籤的示例程序。

【例11-9】使用迭代標籤

coredemo3.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%@ page import="java.util.*"%>

<html>

<head>

<title>JSTL標籤庫中跌代標籤</title>

</head>

<body bgcolor="#ffffff">

<%

String[] numbers = { "1", "2", "3", "4" };

pageContext.setAttribute("numbers", numbers);

Vector vnumbers = new Vector();

vnumbers.add("1");

vnumbers.add("2");

vnumbers.add("3");

vnumbers.add("4");

vnumbers.add("5");

pageContext.setAttribute("vnumbers", vnumbers);

%>

<c:set var="member" value="Joe:Petter;Ryan|John" scope="page" />

<h1>

數組跌代

</h1>

<c:forEach var="numbering" items="${numbers}">

<c:out value="${numbering}" />

<br>

</c:forEach>

<h1>

集合類跌代

</h1>

<c:forEach var="vnumbering" items="${vnumbers}">

<c:out value="${vnumbering}" />

<br>

</c:forEach>

<h1>

自變量循環

</h1>

<c:forEach var="i" begin="1" end="10" step="1">

<c:out value="${i}" />

<br />

</c:forEach>

<h1>

字符串分割

</h1>

<c:forTokens items="${pageScope.member}" delims=":;|" var="membername">

<c:out value="${membername}" />

<br />

</c:forTokens>

</body>

</html>

頁面的運行結果如圖11-12所示。

圖11-12 coredemo3.jsp運行結果

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

核心標籤庫:URL標籤

 

下面將介紹URL標籤中的<c:import>、<c:redirect>和<c:url>三個標籤的使用方法。

<c:import>標籤能夠把其餘靜態或動態文件包含至自己JSP 網頁。它和JSP動做指令的<jsp:include>最大的差異在於:<jsp:include>只能包含和本身同一個Web應用下的文件;而<c:import>除了能包含和本身同一個web application 的文件外,亦能夠包含不一樣Web應用或者是其餘網站的文件。

語法1:

<c:import url="url" [context="context"] [var="varName"]

[scope="{page|request|session|application}"] [charEncoding="charEncoding"]>

本體內容

</c:import>

語法2:

<c:import url="url" [context="context"]

varReader="varReaderName" [charEncoding="charEncoding"]>

本體內容

</c:import>

url:被包含文件的地址 。

context:在相同Web容器下,其餘web應用必須以「/」開頭。

var:儲存被包含的文件的內容(以String類型存入) 。

scope:變量的JSP 做用域 。

charEncoding:被包含文件以內容的編碼格式 。

varReader:儲存被包含的文件的內容(以Reader類型存入)。

例如:

<c:import url="http://www.csai.cn" />的功能是:用<c:import>把http://www.csai.cn 的內容加到網頁中。

<c:url>標籤主要用來產生一個URL。

語法1:沒有標籤體內容

<c:url value="value" [context="context"] [var="varName"]

[scope="{page|request|session|application}"] />

語法2:有標籤體內容表明查詢字符串(Query String)參數

<c:url value="value" [context="context"] [var="varName"]

[scope="{page|request|session|application}"] >

<c:param> 標籤

</c:url>

value:執行的URL。

context:在相同Web容器下,其餘web應用必須以「/」開頭。

var:儲存被包含文件的內容(以String 類型存入)。

scope:變量的JSP做用域。

例如:

<c:url value="http://www.csai.cn">

<c:param name="figure " value="希賽顧問"/>

</c:url> 

會產生一個「http://www.csai.cn?figure=希賽顧問」的超連接。

<c:redirect>標籤能夠將客戶端的請求從一個JSP 網頁導向到其餘文件。

語法1:沒有標籤體內容

<c:redirect url="url" [context="context"] />

語法2:有標籤體內容表明查詢字符串(Query String)參數

<c:redirect url="url" [context="context"] > <c:param> </c:redirect >

url:導向的目標地址 。

context:相同Container 下,其餘web 站臺必須以「/」開頭。

例如:

<c:redirect url="http://www.csai.cn" />,那麼網頁將會自動導向到http://www.csai.cn。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

I18N與格式化標籤庫

 

國際化(I18N)與格式化標籤庫可用於建立國際化的Web應用程序,它們對數字和日期、時間的輸出進行了標準化。國際化的應用程序支持多語言。在JSP頁面中導入國際化與格式化標籤庫的語法是:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

本章中咱們將重點介紹經常使用的<fmt:setLocale>、<fmt:bundle>、<fmt:setBundle>、<fmt:message>幾個經常使用標籤的使用方法。

<fmt:setLocale>標籤用於重寫客戶端指定的區域設置。它將區域設置存儲在javax.servlet.jsp.jstl.fmt配置變量中。setLocale是一個空標籤,其使用語法爲:

<fmt:setLocale value="setting" variant="variant"

 scope="page/request/session/application"/>

value:包含一個含有兩個小寫字母的語言代碼和一個含有兩個大寫字母的國家或地區代碼。語言和國家或地區代碼應該用連字符或下劃線分隔如:zh_CN。

variant:指定特定於瀏覽器的變量,它是可選的。

scope:指定配置變量的範圍。

接下來看一個使用<fmt:setLocale>示例

【例11-10】使用<fmt:setLocale>標籤

fmt_setlocal.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ page import="java.util.*"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

<html>

<head>

<title>設置local方式來顯示不一樣數值,日期,時間格式</title>

</head>

<body bgcolor="#ffffff">

<%

Date now = new Date();

pageContext.setAttribute("now", now);

out.println("本地:" + request.getLocale().toString() + "<br>");

%>

<H2>

數字格式示例

</H2>

<B>123.41234"</B> 格式化爲:

<fmt:formatNumber value="123.41234" type="number"

maxFractionDigits="2" />

<BR>

<HR>

<H2>

貨幣格式示例

</H2>

<c:set var="salary" value="125000" />

工資:

<c:out value="${salary}" />

<BR>

<fmt:setLocale value="en_US" />

用本機的

<B>en_US</B> 將工資格式化爲:

<fmt:formatNumber type="currency" value="${salary}" />

<BR>

日期:

<fmt:formatDate value="${now}" />

<br>

<fmt:setLocale value="zh_CN" />

用本機的

<B>zh_CN</B> 將工資格式化爲:

<fmt:formatNumber type="currency" value="${salary}" />

<BR>

日期:

<fmt:formatDate value="${now}" />

<br>

<HR>

</body>

</html>

頁面的運行結果如圖11-13所示。

圖11-13 fmt_setlocal.jsp運行結果

<fmt:bundle>標籤用於建立一個I18N本地化上下文,並將它的資源包加載到其中。資源包的名稱由<fmt:bundle>標籤的basename屬性指定。此標籤的語法爲:

<fmt:bundle basename="basename">

本體內容

</fmt:bundle>

<fmt:message>標籤用於給出資源包的輸出值。<fmt:message>標籤的語法爲:

<fmt:message key="messagekey ">

其中,key屬性指定消息的關鍵字。

接下來經過一個示例演示<fmt:bundle>和<fmt:message>的用法。

定義好的資源包文件存放在web應用目錄下的「WEB-INF/classes」目錄下,如:

input.properties

title=this is fmtdemo!

hello=hello world

中文內容版爲input_zh_CN1.properties

title=國際演示!

hello=朋友你好

country=你的國家

因爲Java對於資源文件的處理只支持單字節,因此對中文資源須要使用:

 native2ascii -encoding gb2312   input_zh_CN1.properties input_zh_CN.properties

對中文資源文件進行編碼生成單字節的input_zh_CN.properties資源文件。

 title=\u56fd\u9645\u6f14\u793a!

hello=\u670b\u53cb\u4f60\u597d

country=\u4f60\u7684\u56fd\u5bb6

【例11-11】用標籤使用資源文件

Fmt_resouce1.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<html>

<head>

<fmt:bundle basename="input">

<title><fmt:message key="title" /></title>

</head>

<body bgcolor="#ffffff">

<h1>

<fmt:message key="hello" /> 

</h1>

</fmt:bundle>

</body>

</html>

運行結果,如圖11-14所示。

圖11-14 Fmt_resouce1.jsp運行結果

接下來按圖 11-15所示的方式修改瀏覽器的語言設置。

圖11-15 修改瀏覽器的語言設置

修改後Fmt_resouce1.jsp的運行結果,如圖11-16所示。

圖11-16 Fmt_resouce1.jsp運行結果

<fmt:setBundle>:建立一個I18N本地化上下文,並將它存儲在範圍變量中。該標籤是一個空標籤。其語法爲:

<fmt:setBundle basename="basename" var="varName"

 scope="page/request/session/application"/>

basename:指定資源包的名稱。

var:指定導出的範圍變量的名稱,它存儲I18N本地化上下文。

scope:指定var的範圍。

接下來經過一個示例程序看看如何使用<fmt:setBundle>。

【例11-12】使用<fmt:setBundle>標籤

Fmt_resouce.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<html>

<head>

<fmt:setLocale value="zh_CN" scope="page" />

<fmt:setBundle basename="input" scope="page" />

<title><fmt:message key="title" /></title>

</head>

<body bgcolor="#ffffff">

<h1>

<fmt:message key="hello" />   

</h1>

</body>

</html>

Fmt_resouce.jsp的運行結果如圖11-17所示。

圖11-17 Fmt_resouce.jsp運行結果

採用這種方式載入資源包會發現就算採用圖11-15的方式修改瀏覽器的語言設置其運行結果始終如圖11-17所示。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

SQL標籤庫

 

JSTL的SQL標籤用於訪問各類關係數據庫,是爲了基於Web的小型應用程序而設計的。它提供的各類標籤可用於在JSP頁面內直接訪問數據庫,在JSP頁面中導入SQL標籤庫的語法是:

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>

這樣每一個SQL標籤庫中的標籤都冠以一個<sql>前綴,本章咱們將重點介紹<sql:setDataSource>、<sql:query>、<sql:update>、<sql:transaction>等幾個經常使用標籤的使用方法。

<sql:setDataSource>標籤用於爲數據庫設置數據源。它是一個空標籤,容許用戶爲數據庫設置數據源信息,其語法爲:

<sql:setDataSource DataSource="datasource"  url="jdbcurl" 

driver="driverclassdriver" user="username" password="usepwd" 

var="varname" scope="page|request|session|application"/>

DataSource:能夠是Java命名和目錄接口(JNDI,Java Naming and Directory Interface)資源的路徑或JDBC參數字符串。

url:是與數據庫關聯的URL。

driver:是一個JDBC參數,其值爲驅動程序的類名。

user:是數據庫的用戶名。

password:是用戶的密碼。

var:是指定數據源的導出範圍變量的名稱。

scope:指定範圍。

【專家提示】在<sql:setDataSource>中,若是使用了DataSource屬性,則沒法使用url屬性。

<sql:query>標籤用於搜索數據庫並返回包含數據行的結果集。其語法爲:

<sql:query var="varname" dataSource="datasource" 

scope="page|request|session|application" maxRows="maxrows"

startRow="startRow">

要執行的SQL語句

<sql:param/>

</sql:query>

var:爲查詢結果指定導出的範圍變量的名稱。

scope:指定變量的範圍。

dataSource:指定與要查詢的數據庫關聯的數據源。

maxRows:指定結果中所包含的數據的最大行數。

startRow:指定從指定索引開始的數據行。

<sql:update>標籤用於執行INSERT、UPDATE和DELETE語句。若是全部數據行都沒有受到插入、更新或刪除操做的最響,則會返回0。其語法爲:

<sql:update datasource="datasource" var="varName"

scope="page|request|session|application ">

SQL語句

<sql:param/>

</sql:update>

其中:

SQL語句:指定UPDATE、INSERT或DELETE語句。

dataSource:是與要更新的數據庫關聯的數據源。

var:爲數據庫更新的結果指定導出的範圍變量的名稱。

scope:指定變量的範圍。

<sql:transaction>標籤用於爲<sql:query>標籤和<sql:update>標籤創建事務處理上下文。

<sql:transaction dataSource="datasource" isolation="isolationLevel">

使用<sql:query>或<sql:update>語句

</sql:transaction>

dataSource:設置SQL的數據源,它能夠是字符串或一個DataSource對象。

isolation:設置事務處理的隔離級別。隔離級別能夠是read_committed、read_uncommitted、repeatable_read或serializable。

接下來演示一個使用SQL標籤的示例程序。

【例11-13】使用SQL標籤

sqldemo.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>

<html>

<head>

<title>sqldemo</title>

</head>

<body bgcolor="#ffffff">

<h1>

使用 SQL 標籤庫

</h1>

<c:set var="valprice" value="1000" />

<sql:setDataSource

driver="com.microsoft.jdbc.sqlserver.SQLServerDriver"

url="jdbc:microsoft:sqlserver://localhost:1433;DataBaseName=pubs"

user="sa" password="" var="conn" />

<sql:transaction dataSource="${conn}">

<sql:update var="newTable">

CREATE TABLE ProductDetails

(

ProductId int IDENTITY (1000, 1) NOT NULL primary key,

ProductName varchar (20) NOT NULL ,

ProductType varchar (15) NOT NULL ,

Price varchar (5) NOT NULL ,

Brand varchar (25) NOT NULL ,

Description varchar (50) NOT NULL

)

</sql:update>

</sql:transaction>

<sql:update var="newrow" dataSource="${conn}">

INSERT INTO ProductDetails(ProductName, ProductType,

Price, Brand, Description)

VALUES('JSP專家導學 ', '編程書籍', '1000', 'Lee', '適合大專院校的教材或參考書籍')

</sql:update>

<sql:query var="products" dataSource="${conn}">

select * from ProductDetails

</sql:query>

<table border="1">

<c:forEach items="${products.rows}" var="row">

<tr>

<td>

${row.ProductName}

</td>

<td>

${row.ProductType}

</td>

<td>

${row.Price}

</td>

<td>

${row.Description}

</td>

</tr>

</c:forEach>

</table>

</body>

</html>

頁面的運行結果如圖11-18所示。

圖11-18 sqldemo.jsp運行結果

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

XML標籤庫

 

JSTL提供了一些有關XML的標籤,讓開發人員能夠不用深刻了解SAX和DOM等API,就能夠輕易地處理XML文件。在JSP頁面中導入XML標籤庫的語法是:

<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>

這裏將介紹<x:parse>、<x:out>和<x:set>幾個標籤的使用方法。

<x:parse>標籤用來解析XML文件。使用<x:parse>標籤的語法爲:

<x:parse {var="var" [scope="{page|request|session|application}"] |varDom="var" 

[scopeDom="{page|request|session|application}"]}

[systemId="systemId"] [filter="filter"]>

須要解析的XML文檔

</x:parse>

var:儲存解析後的XML文件。

scope:變量的JSP範圍。

varDom:儲存解析後的XML文件(類型爲org.w3c.dom.Document)。

scopeDom:的範圍。

systemId :XML文件的URI。

filter:XMLFilter過濾器。

<x:out> 標籤主要用來取出XML中的節點值。

<x:out select=」XPathExpression」 [escapeXml=」{true|false}」]/>

其中:

select XPath語句。

escapeXml 是否轉換特殊字符,例如:<轉換成&It;

【專家提示】有關XPath的內容請讀者參考本系列叢書中《專家導學Java與XML應用開發》相關內容。

<x:set> 將從XML文件中取得內容存儲至JSP範圍中。

語法爲:

<x:set select="XPathExpression" var="var" 

[scope="{page|request|session|application}"]/>

其中:

select:XPath語句。

var:將從XML文件中取得的內容儲存至varName中。

scope:變量的JSP範圍。

【例11-14】使用XML標籤

Books.xml

<?xml version="1.0" encoding="GBK"?>

<books>

<book lang="java">

<title>《Java 編程思想》</title>

<author>Bruce Eckel</author>

</book>

<book lang="java">

<title>《JSP 專家導學》</title>

<author>希賽顧問團</author>

</book>

<book lang=".net">

<title>《專家導學.NET開發框架》</title>

<author>希賽顧問團</author>

</book>

</books>

xmldemo.jsp

<%@ page language="java"  contentType="text/html; charset=GBK"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>

<html>

  <head>   

    <title>XML標籤示例程序</title>

  </head>  

  <body> 

    <x:parse var="sampleXml">

    <c:import charEncoding="GBK" url="Books.xml"/>

    </x:parse>

    <h3>裝載XML文件成功</h3>    

    <h3>顯第一本書的標題:</h3>    

    <x:out select="$sampleXml//title"/><br/>    

    <h3>查找.net書:</h3>    

    <x:set select="$sampleXml//book[@lang='.net']" var="DoNetBook"  />    

    <x:out select="$DoNetBook"/>

  </body>

</html>

頁面的運行結果如圖11-19所示。

圖11-19 xmldemo.jsp運行結果

【專家提示】使用XML標籤時,Web應用環境中除在「WEB-INF/lib」目錄下加入jstl.jar和standard.jar外還應加入xalan.jar和xercesImpl.jar兩個文件。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

自定義標籤

 

標籤把服務器端複雜的處理邏輯封裝起來,提供給表示層的編寫人員調用,書寫標籤就象書寫HTML代碼同樣容易,同時也容易被理解和閱讀。然而,JSTL提供的標籤畢竟有限,有時,程序員也須要本身編寫標籤,封裝一些處理邏輯。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

簡單標籤(Simple Tag)

 

在JSP1.1時,新增了JSP標籤函數,它最大的功用在於讓用戶可以自行制訂一個標籤,例如前面所講的JSTL標籤都是屬於此類。以往開發標籤時,不是繼承TagSupport,就是繼承BodyTagSupport類,而後實現doStartTag()、doEndTag()或doAfterBody()方法,並且還要搞清楚這些方法的回傳值,如:EVAL_BODY_INCLUDE,EVAL_PAGE、SKIP_BODY、SKIP_PAGE、EVAL_BODY_AGAIN等等。

JSP2.0爲了簡化開發標籤的複雜性,所以增長了一個製做Simple Tag的SimpleTagSupport類。SimpleTagSupport類是實現SimpleTag接口的,它只需要實現一個doTag()的方法便可,而再也不須要一堆回傳值。使用標籤處理程序實現自定義標籤三個步驟:

編寫標籤處理程序(Java 類)。

編寫標籤庫描述符(提供有關標籤和庫文件的元信息的 XML 文件)

JSP 實現(包含自定義標籤的 JSP 文件)

【例11-15】開發簡單的自定義標籤

標籤處理程序的源代碼以下。

SimpleTagDemo.java

package customtag;

import javax.servlet.jsp.tagext.*;

import java.io.*;

import java.util.*;

import javax.servlet.jsp.*;

/**

 * @author Administrator

 *

 */

public class SimpleTagDemo extends SimpleTagSupport {

private int num;

public void setNum(int num) {

this.num = num;

}

public void doTag() throws JspException, IOException {

JspWriter out = this.getJspContext().getOut();

out.println("<h1>演示" + num + "次輸出標籤體的內容</h1>");

for (int i = 0; i < num; i++) {

getJspContext().setAttribute("count", String.valueOf(i + 1));

getJspBody().invoke(null);

}

}

}

標籤描述tld文件的內容以下。

simpledemo.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"

version="2.0">

<description>

A tag library exercising SimpleTag handlers.

</description>

<tlib-version>1.0</tlib-version>

<short-name>SimpleTagLibrary</short-name>

<uri>/SimpleTagLibrary</uri>

<tag>

<description>Outputs Hello, World</description>

<name>simpletagdemo</name>

<tag-class>customtag.SimpleTagDemo</tag-class>

<body-content>scriptless</body-content>

<attribute>

<name>num</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

</tag>

</taglib>

tlib-version:是必須元素,指定標記庫函數的版本號,例如:

<tlib-version>1.0.123.123.234</tlib-version>。

short-name:爲標記庫指定一個縮略名稱,用它能夠做爲標記庫的缺省名字空間,如:

< short-name >demotaglib</ short-name >

info:用來描述標記的文檔信息,缺省值爲空

uri:用來指定鏈接到標記的附加源文件,即TLD的公共可用副本。

tag:是標記描述文件中最重要的一個元素,與其它元素不一樣的是,它能夠有子元素。tag元素有六個子元素:name、tagclass、teiclass、bodycontent、info、attribute。name子元素用戶指定的標記名稱;tag-class子元素指定標記處理類,此處應該是全限定名稱,即帶包名的類;bod-ycontent子元素說明標記體的類型,分爲四種:empty、jsp、scriptless、tagdependent,empty表示沒有標記體,jsp表示標記體能夠爲jsp代碼,scriptless表示標記中不能用jsp腳本,tagdependent表示標籤中的內容交給標記處理程序去進行處理;info記錄標記的描述信息;attribute用來指定零個或者多個標記屬性,這個元素又有三個子元素:name, required, rtextprvalue,name子元素是必須設定的元素,用來表示大小寫敏感屬性名稱,required子元素是必須設定的元素,標識屬性是否必定要存在,默認爲false,若是設置爲flase,則在標記處理程序中不會自動去調用屬性的setAttribute方法,rtextprvalue子元素用來講明屬性是否能夠是動態生成的,但設定爲true時,屬性既能夠是一個常量值,也能夠由表達式動態生成。

simpletagdemo.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib uri="/WEB-INF/simpledemo.tld" prefix="mytag"%>

<html>

<head>

<title>simpletagdemo演示示例</title>

</head>

<body bgcolor="#ffffff">

<h1>

結果

</h1>

<mytag:simpletagdemo num="7">

    重複輸出數據:${count} of 7<br>

</mytag:simpletagdemo>

</body>

</html>

頁面的運行結果如圖11-20所示。

圖11-20 simpletagdemo.jsp運行結果

【思考1】JSP標記與JavaBean有何區別?

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

標籤文件

 

標籤文件是JSP2.0新增的主要功能之一。根據JSP2.0規範中的定義:所謂的Tag File就是讓JSP網頁開發人員能夠直接使用JSP語法來製做標籤,而不須瞭解Java語言。

全部Tag File文件的擴展名都爲.tag或.tagx。倘若Tag File包含其餘完整或片斷的Tag File,JSP2.0規範建議擴展名爲.tagf。

JSP2.0標籤文件的新特性有:

Tag File的七個隱式對象

request、response、out、jspContext、session、application、config。

Tag File的指令

新增的幾個動做

<jsp:attribute>標籤用來指定自定義標籤屬性塊,必要時能夠做爲代碼段輸出。

<jsp:doBody>標籤告訴容器去處理body,而且將處理結果添加到response中。你能夠有選擇性的使用「var」 屬性,捕獲處理的結果,並在下一步進行處理。 

<jsp:invoke>標籤對做爲屬性傳遞的特定參數進行操做

【例11-16】開發與使用標籤文件

datetag.tag

<%@tag pageEncoding="GBK"%>

<%@tag import="java.util.*,java.text.*"%>

<%@variable name-given="fulldate" scope="AT_BEGIN"%>

<%

  DateFormat fullformate = DateFormat.getDateInstance(DateFormat.FULL);

  Date now = new Date();

  jspContext.setAttribute("fulldate", fullformate.format(now));

%>

<jsp:doBody/>  

simpletagdemo2.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib prefix="mytag" tagdir="/WEB-INF/tags/"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>

<head>

<title>datetag</title>

</head>

<body bgcolor="#ffffff">

<h1>

日期tag標籤文件演示

</h1>

<mytag:datetag>

  標籤體的輸出:${fulldate}<br>

</mytag:datetag>

頁面的輸出:${fulldate}

</body>

</html>

頁面的運行結果如圖11-21所示。

圖11-21 simpletagdemo2.jsp運行結果

sumtag.tag

<%@tag pageEncoding="GBK"%>

<%@attribute name="items" required="true" rtexprvalue="true"%>

<%@attribute name="great" fragment="true"%>

<%@attribute name="less" fragment="true"%>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@variable name-given="sum" variable-class="java.lang.Object"%>

<c:if test="${not empty items}">

<c:forEach items="${items}" var="item">

<c:set var="sum" value="${item+sum}" />

</c:forEach>

<c:if test="${sum>=1000}">

<jsp:invoke fragment="great" />

</c:if>

<c:if test="${sum<1000}">

<jsp:invoke fragment="less" />

</c:if>

</c:if>

sumtag.jsp

<%@ page contentType="text/html; charset=GBK"%>

<%@ taglib prefix="mytag" tagdir="/WEB-INF/tags/"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>

<head>

<title>sumtag</title>

</head>

<body bgcolor="#ffffff">

<h1>

tag標籤文件演示

</h1>

<mytag:sumtag items="111,222,333">

<jsp:attribute name="great">

<font color="red"> SUM: ${sum}</font>

</jsp:attribute>

<jsp:attribute name="less">

<font color="blue"> SUM: ${sum}</font>

</jsp:attribute>

</mytag:sumtag>

</body>

</html>

頁面的運行結果如圖11-22所示。

圖11-22 sumtag.jsp 運行結果

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

小結

 

經過本章學習讀者應能掌握EL表達式語言的語法及各類運算符的使用;熟練運用掌握JSTL標籤核心標籤、I18N與格式化標籤庫、SQL標籤庫和XML標籤使用方法;還能用兩種自定義標籤的定義方法(簡單標籤和標籤文件)來開發標籤。在學習完本章後讀者應可以利用EL和標籤技術來開發Web應用,取代傳統直接在頁面上嵌入Java程序的作法,以提升程序的閱讀性、維護性和方便性。

 
 
 
 

第 11 章:表達式與標籤做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

思考解答

 

【思考1】JSP標記與JavaBean有何區別?

答:JavaBean存在先天的不足,它只是可複用的組件,獨立於運行環境而包裝了一些數據和業務邏輯功能,沒法得到運行環境信息,沒法與jsp頁面進行更加深層次的交互。

自定義標記機制,解決了JavaBean的這種缺陷,標記庫的處理類,不但具備javabean的功能,並且能夠jsp的環境信息傳送到類中間,不但能獲得jsp傳遞過來的屬性,並且還能得與jsp共用頁面環境,jsp 頁面中能夠經過session、page與標記處理程序進行數據通訊,這一點是javaBean所不能實現的。

 

 

第12章  Web圖表開發

【本章專家知識導學】

Web統計圖形和報表的開發每每是令程序員感到頭痛、棘手的問題,但在各類管理信息系統倒是很常見的,好在JSP開發如今已經有了許多開源的組件,有了這些組件,程序員就沒必要再編寫大量的代碼,也沒必要關注Java底層的圖形圖象知識,只需編寫少許的代碼便可快速開發出漂亮的統計圖形和報表,還能實現打印、導出成Excel、Word文件等強大的功能。

本章將給讀者介紹兩款快速進行Web統計圖形和報表的開發工具——JFreeChart和JavaReport。JFreeChart用於圖形的開發;JavaReport既可用於圖形的開發也可用於報表的開發。掌握這兩個組件來開發出適用的圖形和報表並不難,下面就一塊兒來學習。

12.1 JFreeChart組件介紹

程序員開發Java Web系統常常碰到須要開發Web圖形與報表的情形,若是是C/S模式的開發,由於有集成開發工具的支持,如Microsft Visual Studio,開發圖形與報表變得快捷,然而Web開發就顯得比較麻煩了。

有程序員可能嘗試過調用Office的ocx組件的方式來顯示圖形,這要求客戶端必需要安裝有office軟件,但有時客戶端使用的多是WPS Office或其它的辦公軟件,這就使得Web系統失去了通用性。那麼有沒有別的方法實現呢?JDK中帶有圖形開發的軟件包AWT,然而,從事應用軟件系統開發的程序員並不是圖形圖像方面的專家,短期內沒法掌握JDK中AWT的開發,何況這還要求程序員瞭解較多的底層API。所以,能夠考慮使用比較成熟的第三方的組件包來實現。

JFreeChart是一個開源的組件包,它提供了Java中經常使用統計圖形的快速開發API,程序員只要掌握少許的接口就能繪製出漂亮的圖形,並且這些圖形不只可用於帶有客戶端界面的Java應用程序中,也能夠是在JSP, Servlet, Java Applet中。本章中將主要介紹在JSP中如何使用JFreeChart組件包開發經常使用的圖形,若是要在Servlet、應用程序或Java Applet中實現相似的功能,可自行參考JSP編程方法實現的程序來編寫代碼。

JFreeChart可用於建立餅圖、線圖、柱狀圖、散點圖、甘特圖等。能夠從以下的網址獲得許多有關於JFreeChart的詳細信息:

http://www.jfree.org/jfreechart/ 

本書使用的JFreeChart版本是至本書成稿之日最新的1.0.5,可從以下的網址下載獲得:

http://downloads.sourceforge.net/jfreechart/jfreechart-1.0.5.zip?modtime=1174667923&big_mirror=0

從如下的地址能夠獲得JFreeChart1.0.5的HTML格式的詳細API說明文檔:

http://downloads.sourceforge.net/jfreechart/jfreechart-1.0.5-javadocs.zip?modtime=1174668033&big_mirror=0

要在JSP中用JFreeChart開發Web圖表,就須要安裝JFreeChart組件包。將JFreeChart的zip壓縮包jfreechart-1.0.5.zip解壓縮,解壓縮軟件能夠使用WinRar、WinZip等。在解壓後獲得的目錄的lib子目錄中的全部jar包拷貝到Web應用的WEB-INF/lib目錄下,便可在JSP中使用JFreeChart了。

【專家提示】上段所述的這種安裝方法僅對當前Web應用有效,若是要讓當前網站中的全部的Web應用均可以使用JFreeChart1.0.5,則應將jar包拷貝到Tomcat5的安裝目錄的common/lib子目錄中。

JFreeChart1.0.5須要JDK1.3版本或更高版本的JDK環境做爲支持,使用了JDK中的Java 2D API來做圖。JFreeChart1.0.5還使用到了JCommon組件,能夠從以下的地址獲得有關JCommon的更多信息:

http://www.jfree.org/jcommon/index.html

JFreeChart1.0.5的lib子目錄中已帶用JCommon組件包jcommon-1.0.9.jar,沒必要再行安裝JCommon組件。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

JFreeChart的應用

 

下面開始學習使用JFreeChart。這裏並不想立刻就介紹JFreeChart的類、API等參考性的內容,先看簡單的實例,再學會一些複雜一點的實例,再給出經常使用的類及其API參考。若是須要給圖形制做一些特效或細膩的顯示效果,請讀者參考JFreeChart的javadocs以瞭解更詳細的API。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

建立第一個簡單的餅圖

 

用JFreeChart建立Web圖形須要通過三個步驟:

第一步:建立一個包含要在Web圖形中顯示的數據的數據集對象。

第二步:建立一個用於做圖的JFreeChart對象。

第三步:向目標做圖。Web圖表的做圖目標爲response.getOutputStream(),即response對象的輸出流。

【例12-1】 一個簡單的餅圖

下面以建立一個簡單的餅形圖(用戶年齡階段分佈統計圖)爲例。

第一步:建立一個包含要在Web圖形中顯示的數據的數據集對象。代碼以下:

String dataName[]=new String[]{"0-30歲","30-50歲","50-70歲","70歲以上"};//顯示數據系列

int dataValueCount[]={4,5,4,6};//數據系列對應的值

DefaultPieDataset pieDataset = new DefaultPieDataset();

for(int i=0;i<dataName.length;i++)

pieDataset.setValue(dataName[i],dataValueCount[i]);

【專家提示】餅圖的數據集對象能夠是實現了JFreeChart組件中的PieDataset接口的類的實例,讀者能夠自行編寫類實現,也能夠使用JFreeChart組件中已有的已實現了PieDataset接口的DefaultPieDataset類,更加方便和快捷。

第二步:建立一個用於做圖的JFreeChart對象。代碼以下:

String titleString="用戶年齡階段分佈統計圖";//圖的標題

JFreeChart chart = ChartFactory.createPieChart(titleString,//圖形標題

pieDataset,//數據集

true, //是否顯示圖例

true, //是否有工具提示

false//是否有URL

);

ChartFactory是一個工廠類,可用於建立JFreeChart對象。這裏使用的方法是createPieChart()方法,參數做了簡單的設置。建立JFreeChart對象的方法還有許多種形式,這裏僅給出簡單的一種,有興趣能夠參考本章後續的JFreeChart經常使用類的說明。

第三步:向目標做圖。代碼以下:

ChartUtilities.writeChartAsJPEG(response.getOutputStream(),chart,500,300);

下面結出本實例的完整代碼。

firstPie.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="org.jfree.chart.JFreeChart,org.jfree.chart.ChartUtilities,

org.jfree.chart.ChartFactory,org.jfree.data.general.DefaultPieDataset"%>

<html>

<body>

<%

//第一步:建立一個包含要在Web圖形中顯示的數據的數據集對象

String dataName[]=new String[]{"0-30歲","30-50歲","50-70歲","70歲以上"};//顯示數據系列

int dataValueCount[]={4,5,4,6};//數據系列對應的值

DefaultPieDataset pieDataset = new DefaultPieDataset();

for(int i=0;i<dataName.length;i++)

pieDataset.setValue(dataName[i],dataValueCount[i]);

//第二步:建立一個用於做圖的JFreeChart對象

String titleString="用戶年齡階段分佈統計圖";//圖的標題

JFreeChart chart = ChartFactory.createPieChart(titleString,pieDataset,true,true, false);

//第三步:向目標做圖。

ChartUtilities.writeChartAsJPEG(response.getOutputStream(),chart,500,300);

%>

</body>

</html>

程序的運行效果如圖12-1所示。

圖12-1    第一個簡單的餅圖

【專家提示】若是數據集中的數據來源於數據庫中,則能夠在第一步中編寫程序從數據庫中取出數據,再設置數據集中的數據,第二步與第三步仍照舊,便可以圖形方式顯示數據庫中的數據了。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

建立條形圖

 

用JFreeChart建立條形圖主要須要用實現了CategoryDataset接口或IntervalXYDataset接口的類的實例來做爲數據集對象,經常使用JFreeChart中自帶的已實現了CategoryDataset接口的DefaultCategoryDataset類。

【例12-2】 建立條形圖

建立條形圖一樣須要經歷與建立餅形圖相似的三步。本例將生成一個表示用戶年齡階段分佈的條形圖。

第一步:建立一個包含要在Web圖形中顯示的數據的數據集對象。代碼以下:

String dataName[]=new String[]{"0-30歲","30-50歲","50-70歲","70歲以上"};//顯示數據系列

int dataValueCount[]={4,5,4,6};//數據系列對應的值

//------建立數據集,並設置值------

DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset();

for(int i=0;i<dataName.length;i++)

categoryDataset.addValue(dataValueCount[i],dataName[i],dataName[i]);

第二步:建立一個用於做圖的JFreeChart對象。代碼以下:

String titleString="用戶年齡階段分佈統計圖";//圖的標題

JFreeChart chart = ChartFactory.createBarChart(titleString,//圖形標題

"用戶年齡階段",//分類軸標籤(默認爲橫向)

"數量",//數值軸標籤(默認爲縱向)

categoryDataset,//數據集

PlotOrientation.VERTICAL,//圖形顯示方向,豎向

true,//是否顯示圖例

true,//是否有工具提示

false//是否有URL

);

第三步:向目標做圖。

ChartUtilities.writeChartAsJPEG(response.getOutputStream(),chart,500,300);

下面結出本實例的完整代碼。

barChartd.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="org.jfree.chart.JFreeChart,org.jfree.chart.ChartUtilities,

org.jfree.chart.ChartFactory,

org.jfree.chart.plot.PlotOrientation,

org.jfree.data.category.DefaultCategoryDataset"%>

<html>

<body>

<%

//第一步:建立一個包含要在Web圖形中顯示的數據的數據集對象

String dataName[]=new String[]{"0-30歲","30-50歲","50-70歲","70歲以上"};//顯示數據系列

int dataValueCount[]={4,5,4,6};//數據系列對應的值

//------建立數據集,並設置值------

DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset();

for(int i=0;i<dataName.length;i++)

categoryDataset.addValue(dataValueCount[i],dataName[i],dataName[i]);

//第二步:建立一個用於做圖的JFreeChart對象

String titleString="用戶年齡階段分佈統計圖";//圖的標題

JFreeChart chart = ChartFactory.createBarChart(titleString,"用戶年齡階段","數量",

categoryDataset,PlotOrientation.VERTICAL,true,true,false);

//第三步:向目標做圖。

ChartUtilities.writeChartAsJPEG(response.getOutputStream(),chart,500,300);

%>

</body>

</html>

程序的運行效果如圖12-3所示。

圖12-3    建立條形圖

條形圖的顯示也能夠做一些定製性的修改,經常使用的修改有:

(1)修改圖形的背景顏色

修改條形圖的背景顏色使用以下的方法:

chart.setBackgroundPaint(new Color(0xBBBBDD));

chart是JFreeChart實例的名稱。

(2)修改圖形的柱狀條顏色

修改圖形的柱狀條顏色須要使用setSeriesPaint()方法,但這個方法並不是JFreeChart類的方法,而須要先用JFreeChart類的實例的getCategoryPlot()獲得一個CategoryPlot對象,再用CategoryPlot對象的getRenderer()方法獲得一個BarRenderer對象,用BarRenderer對象的setSeriesPaint()方法來設置柱狀條的顏色,如:

CategoryPlot plot = chart.getCategoryPlot();

BarRenderer renderer = (BarRenderer) plot.getRenderer();

renderer.setSeriesPaint(0, Color.red);

renderer.setSeriesPaint(1, Color.green);

renderer.setSeriesPaint(2, Color.blue);

(3)柱狀條的間距

JFreeChart容許修改類型軸的一些設置,如:

第一條柱狀條與數值軸之間的空白間距。

柱狀條之間的空白間距。

最後一條柱狀條後的空白距離。

此三項的設置方法示例以下:

CategoryPlot plot = chart.getCategoryPlot();

CategoryAxis axis = plot.getDomainAxis();

axis.setLowerMargin(0.02); //百分之二

axis.setCategoryMargin(0.10); //百分之十

axis.setUpperMargin(0.02); //百分之二

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

建立線形圖

 

JFreeChart也能夠建立線形圖,這時使用的數據集能夠是CategoryDataset接口或XYDataset的實現類的實例。

【例12-3】 建立線形圖

建立線形圖一樣須要經歷與建立餅形圖相似的三步。本例將實現輸出一個學生物理、化學、數學三門課程6次考試成績的線圖。

第一步:建立一個包含要在Web圖形中顯示的數據的數據集對象。代碼以下:

//------數據線------

String dataLine1="物理";

String dataLine2="化學";

String dataLine3="數學";

//------數據列------

String dataCol1="1";

String dataCol2="2";

String dataCol3="3";

String dataCol4="4";

String dataCol5="5";

String dataCol6="6";

//------建立數據集,並設置值------

DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset();

categoryDataset.addValue(60,dataLine1,dataCol1);

categoryDataset.addValue(70,dataLine1,dataCol2);

categoryDataset.addValue(83,dataLine1,dataCol3);

categoryDataset.addValue(90,dataLine1,dataCol4);

categoryDataset.addValue(92,dataLine1,dataCol5);

categoryDataset.addValue(85,dataLine1,dataCol6);

categoryDataset.addValue(63,dataLine2,dataCol1);

categoryDataset.addValue(45,dataLine2,dataCol2);

categoryDataset.addValue(67,dataLine2,dataCol3);

categoryDataset.addValue(76,dataLine2,dataCol4);

categoryDataset.addValue(90,dataLine2,dataCol5);

categoryDataset.addValue(87,dataLine2,dataCol6);

categoryDataset.addValue(50,dataLine3,dataCol1);

categoryDataset.addValue(76,dataLine3,dataCol2);

categoryDataset.addValue(84,dataLine3,dataCol3);

categoryDataset.addValue(96,dataLine3,dataCol4);

categoryDataset.addValue(88,dataLine3,dataCol5);

categoryDataset.addValue(80,dataLine3,dataCol6);

第二步:建立一個用於做圖的JFreeChart對象。代碼以下:

//------建立線圖------

String titleString="XXXXXX學生成績線圖";//圖的標題

JFreeChart chart = ChartFactory.createLineChart(titleString,//圖形的標題

"第幾回考試",//區域軸標籤

"成績",//數值軸標籤

categoryDataset,//數據集

PlotOrientation.VERTICAL,//圖形顯示方向,豎向

true,//是否顯示圖例

true,//是否有工具提示

false//是否有URL

);

第三步:向目標做圖。代碼以下

ChartUtilities.writeChartAsJPEG(response.getOutputStream(),chart,500,300);

下面結出本實例的完整代碼。

lineChart.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="org.jfree.chart.JFreeChart,org.jfree.chart.ChartUtilities,

org.jfree.chart.ChartFactory,

org.jfree.chart.plot.PlotOrientation,

org.jfree.data.category.DefaultCategoryDataset"%>

<html>

<body>

<%

//------數據線------

String dataLine1="物理";

String dataLine2="化學";

String dataLine3="數學";

//------數據列------

String dataCol1="1";

String dataCol2="2";

String dataCol3="3";

String dataCol4="4";

String dataCol5="5";

String dataCol6="6";

//------建立數據集,並設置值------

DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset();

categoryDataset.addValue(60,dataLine1,dataCol1);

categoryDataset.addValue(70,dataLine1,dataCol2);

categoryDataset.addValue(83,dataLine1,dataCol3);

categoryDataset.addValue(90,dataLine1,dataCol4);

categoryDataset.addValue(92,dataLine1,dataCol5);

categoryDataset.addValue(85,dataLine1,dataCol6);

categoryDataset.addValue(63,dataLine2,dataCol1);

categoryDataset.addValue(45,dataLine2,dataCol2);

categoryDataset.addValue(67,dataLine2,dataCol3);

categoryDataset.addValue(76,dataLine2,dataCol4);

categoryDataset.addValue(90,dataLine2,dataCol5);

categoryDataset.addValue(87,dataLine2,dataCol6);

categoryDataset.addValue(50,dataLine3,dataCol1);

categoryDataset.addValue(76,dataLine3,dataCol2);

categoryDataset.addValue(84,dataLine3,dataCol3);

categoryDataset.addValue(96,dataLine3,dataCol4);

categoryDataset.addValue(88,dataLine3,dataCol5);

categoryDataset.addValue(80,dataLine3,dataCol6);

//------建立線圖------

String titleString="XXXXXX學生成績線圖";//圖的標題

JFreeChart chart = ChartFactory.createLineChart(titleString,"第幾回考試","成績",

categoryDataset,PlotOrientation.VERTICAL,true,true,false);

ChartUtilities.writeChartAsJPEG(response.getOutputStream(),chart,500,300);

%>

</body>

</html>

程序的運行效果如圖12-4所示。

圖12-4    生成線形圖

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

經常使用API介紹

 

JFreeChart的組件包中的類至關之多,須要對圖形多越多的個性化設置或要開發越複雜的圖形,就須要瞭解這些組件包中更多的類及其API。JFreeChart中經常使用有以下一些包:

(1)org.jfree.chart:這個包包含了JFreeChart最爲重要也是最爲經常使用的幾個類和接口。

(2)org.jfree.chart.data:數據集相關的接口和類。

(3)org.jfree.chart.plot:繪圖相關的類和接口。

(4)org.jfree.chart.data.general:經常使用的數據集相關的接口和類。

還有許多其它的包,就再也不一一介紹,有興趣的讀者可進一步參考JFreeChart的開發參考手冊。

下面介紹開發中最爲經常使用的幾個類(或接口)。

(1)JFreeChart類

即org.jfree.chart.JFreeChart,這個類用於協調整個畫圖的處理過程。生成這個類一般使用ChartFactory類。JFreeChart主要的方法有:

public void draw(Graphics2D g2, Rectangle2D area)

此方法用於在圖形設備上的特定區域畫圖。參數g2代碼一個圖形,參數area表包容這個圖形的矩形容器。Java中提供了幾個圖形設備:屏幕、打印機、圖形緩衝區。JFreeChart繪圖是由不一樣的Java.awt.Graphics2D包中的抽象類實現的,只有利用它們,JFreeChart才能向不一樣的圖形設備輸出圖形。

(2)ChartFactory類

這個類是一個工廠類,即org.jfree.chart.ChartFactory,它提供了一些比較方便的建立圖形對象的方法。此類經常使用的方法有:

public static JFreeChart createPieChart(String title,PieDataset dataset, boolean legend, boolean tooltips, boolean urls)

此方法用於建立一個標準的餅圖。參數title爲要建立的餅圖的標題;參數dataset爲建立餅圖所使用的特定的數據集(能夠爲空);參數legend表是不是一個圖例;參數tooltips用於配置圖形是否生成提示信息,參數urls配置圖形是否生成URL。

public static JFreeChart createBarChart(String title,String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset,PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls)

此方法用於根據dataset數據集生成條形圖;參數categoryAxisLabel指定橫向軸(分類軸)的提示字符串;參數valueAxisLabel指出豎向軸(值軸)的提示字符串,其它參數的含義同createPieChart()方法;參數orientation指出條形圖是橫向的仍是豎向的,若是爲豎向的其值可設爲PlotOrientation.VERTICAL。

public static JFreeChart createLineChart(String title,String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset,PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls)

此方法根據dataset數據集生成線圖,其它參數的含義同createBarChart()方法。

(3)ChartUtilities類

即org.jfree.chart.ChartUtilities,經過ChartUtilities類可從chart對象生成PNG格式或JPEG格式的圖片,也可生成帶有點擊範圍的HTML圖片,這些生成圖片的方法都是靜態的。ChartUtilities類有以下經常使用的方法:

public static void writeChartAsPNG(OutputStream out, JFreeChart chart, int width, int height) throws IOException

JFreeChart經過一個開源的PNG格式圖片的解碼器來生成PNG圖片。ChartUtilities類提供了一些方便使用的方法來直接經過輸出流(OutputStream)生成圖片。參數width爲圖形的寬度,參數heigth爲圖形的高度。

public static void writeChartAsJPEG(OutputStream out, JFreeChart chart, int width, int height) throws IOException

public static void writeChartAsJPEG(OutputStream out, JFreeChart chart, int width, int height, ChartRenderingInfo info)

這兩個方法用於生成JPEG格式的圖片。參數的含義同writeChartAsPNG()方法。

(4)PlotOrientation類

即org.jfree.chart.plot.PlotOrientation,此類用於表示圖形的顯示方向,這個類主要有兩個屬性,分別用於表示圖形顯示的兩個方向:橫向和縱向。

PlotOrientation.HORIZONTAL:圖形橫向顯示。

PlotOrientation.VERTICAL :圖形縱向顯示。

(5)DefaultCategoryDataset接口

即org.jfree.data.category.DefaultCategoryDataset,這是一個默認狀況下使用的分類數據集接口。它的構造函數以下:

public DefaultCategoryDataset()

這個函數將生成一個空的數據集。也能夠使用DatasetUtilities類的靜態方法以數組做爲參數來生成一個新的數據集,並用這個數組做爲數據集中的數據。

public addValue(Number value, Comparable rowKey, Comparable columnKey)

此方法用於向數據集中加入一個值。向數據要中增長值時,若是已經存在則會覆蓋。

public setValue(Number value, Comparable rowKey, Comparable columnKey)

此方法的功能同addValue()方法。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

JavaReport組件介紹

 

JSP程序員總以爲在開發Web系統時報表是個老大難的問題,要麼須要程序員編寫一大堆的程序,要麼須要使用到第三方的組件以快速開發。在Web系統中通常程序員不能專一於開發報表,諸於調整報表格式之類的工做,而應當把精力集中放在實現系統的業務邏輯、數據邏輯,所以筆者提倡使用成熟的第三方報表組件。

如今市場上林林總總不下20 家專業報表工具,若是再加上各家公司本身開發、用於項目的報表控件、程序等等,用數以百計來形容報表工具的種類並不過度。這裏並不想列羅出各類報表工具,而只是想介紹一款實用的,支持快速開發,可知足大多數應用場合下的報表開發工具——JavaReport。

JavaReport由偉才工做室開發,這個組件簡單易用,只須編寫少許的代碼便可開發出複雜的報表和圖形,中文支持較好,較爲實用。JavaReport可從網上免費下載獲得,網址以下:

http://www.javareport.com.cn/download.htm

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

JavaReport介紹

 

JavaReport是純Java的實時的Web報表開發平臺。是B/S結構應用系統的報表解決方案。系統採用HTML的方式顯示展現,同時可直接導出Word,Excel,PDF,CSV等各類格式文件,而且保持樣式一致。JavaReport主要有以下優勢:

(1)支持實時的、動態的報表Web統計報表。

(2)具備豐富統計圖形接口,有良好的圖表混合報表擴展能力。

(3)支持純HTML的Web報表展示方式,且無需安裝任何插件。

(4)自動實現數據分頁功能、上下翻頁等功能。

(5)報表能夠動態導出成Word,Excel,PDF,CSV各類格式的文檔。

(6)中文支持不錯,不存在多種編碼亂碼問題,爲程序員省心很多。

有許多的問題在JavaReport組件內已經解決,如報表的導出功能、打印功能和數據的分頁處理等。在不少B/S結構體系的系統開發時,分頁是開發過程當中要重點考慮的問題。但在JavaReport中,就不須要考慮上下翻頁,跨頁分頁,由於這些問題報表引擎已經實現了。在設計報表的過程當中,把Report類看成容器類,統計圖類,表格類,標籤類,圖片類等,把它們看成組件類。至於跨頁分頁,上下翻頁由報表引擎自動完成。JavaReport系統中有自動跨頁分頁的功能,當表格超過當前頁的大小時,系統會自動把接着部分放到下一頁。報表設計在開發過程當中是感受不到要跨頁的存在,只有一個所有數據完整的表格對象。

若是要把引入圖片文件加入到報表中,可以使用報表系統的Report類,經過這個類的addImage()方法把Image對象加進來,若是須要自定義圖像,可經過第三方畫圖程序(例如是JFreeChart程序)生產須要的統計圖/圖片,而後再把圖像加到報表中去。

本書中使用的JavaReport版本是V3.0,JavaReport根據客戶的應用須要,按照功能和性能的等級,分紅三個版本:專業版,服務器版,企業版。本書使用企業版。JavaReport三個版本產品都是無償使用的。也就是說這三個版本都不須要購買License許可,能夠自由使用JavaReport的全部功能。

專業版客戶(Client)的IP最大鏈接數限制爲10個,也就是JavaReport同時並行處理線程的最大數受限制。限制是爲了不繫統資源佔用過大,使系統反應遲鈍。該版本適合中小型的應用系統,保障應用系統正常運行。

服務器版在最大鏈接數沒有受限,它能充分發揮服務器的個部分硬件設備的做用;相對要求服務器的設備配置高,保障最優性能效率。該版本適合大中型的應用系統使用。

企業版提供垃圾回收機制管理,自動處理在內存中無用對象的引用;支持多服務器處理模式,提供在多個服務器的集羣功能和服務器之間負載均衡功能。提升服務器羣的負載能力和和快速響應能力。該版本適合負載繁重的應用系統使用。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

安裝JavaReport

 

在下載獲得的文件中找到JavaReport-V3-Enterprise-Released.jar這個jar文件,把這個文件的路徑加入到classpath系統變量中,這樣本機上的全部Web應用均可以使用JavaReport了。若是隻須要讓某個Web應用可以使用JavaReport,則應當把jar文件拷貝到Web應用的WEB-INF\lib目錄下。

【專家提示】若是Web應用的WEB-INF目錄下沒有lib子目錄,就新建一個lib子目錄。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

經常使用的JavaReport類

 

JavaReport生成的報表在顯示時的狀況如圖12-5所示。

圖12-5    JavaReport生成的報表顯示時的狀況

最上面的一欄中有許多的按鈕,稱爲報表導航按鈕,其中就有將報表導出成文件的按鈕,鼠標在按鈕上懸停不久後即會有文字提示按鈕的功能。報表導航按鈕的後面預留了一些空餘的地方,用於程序員自定義一些按鈕。JavaReport把一張報表分爲表頭、報表中的內容、表尾三個部分,一張報表中能夠有多個表格。

JavaReport的組件包中有許多的類,體系龐大而複雜,在這裏僅列出一些經常使用的類來做出說明,有興趣的可參考詳細的API手冊。

(1)WebReportEngine類

即com.javareport.http.WebReportEngine,這個類是整個JavaReport中的Web引擎的開發接口。全部的JSP或Servlet從這個類繼承下來,程序員只須要覆蓋createReport()函數就能實現報表開發工做中大部分的需求,諸如怎樣在Web上顯示、怎樣造成Word、PDF文件等之類的功能由JavaReport報表引擎來完成,程序員就沒必要再考慮這些實現的細節了。

若是是在JSP頁面中,在首部需加入以下的語句:

<%@ page extends="com.javareport.http.WebReportEngine"%>

表示JSP頁面類繼承自com.javareport.http.WebReportEngine。

【專家提示】有的讀者可能以爲不理解,什麼叫JSP類?JSP實質上就是一個Java類,我表面上看來它是一個動態的網頁,在Web引擎中會最終將它編譯成一個Java類,再執行這個Java類。

若是是在Servlet中,相應的Servlet類聲明時語句以下:

public class Servlet類名稱 extends WebReportEngine{

……

}

WebReportEngine類經常使用的方法有:

public Report createReport(javax.servlet.http.HttpServletRequest request)

throws java.lang.Exception

public java.lang.String validate(javax.servlet.http.HttpServletRequest request)

public java.lang.String getStartScript(javax.servlet.http.HttpServletRequest request)

public java.lang.String getEndScript(javax.servlet.http.HttpServletRequest request)

public java.lang.String getToolbarScript(javax.servlet.http.HttpServletRequest request)

public boolean isShowToolbar()

public int getAllEchoButton()

createReport()方法用於創建報表,並返回報表的實例。這個報表實例能夠在Web上顯示,同時也能夠導出Word, Excel, PDF, CSV, HTML等格式的文檔以供使用。方法中的參數request可用於獲取全部的動態請求的數據。

validate()方法用於對上一個頁面Form提交的參數進行檢查,因爲實時報表須要動態的參數,在這裏進行數據校驗。方法中的參數request可用於獲取全部的動態請求的數據;方法的返回值爲null時表明經過,其餘內容則爲參數錯誤的提示信息。

getStartScript()方法用於構造報表內容在Web頁面上顯示以前執行的JavaScript或VBScript腳本,若是要定製則要重載這個方法。方法中的參數request可用於獲取全部的動態請求的數據;方法返回值爲null時表明沒有腳本內容。

getEndScript()方法用於構造報表內容在Web頁面上顯示以後執行的JavaScript或VBScript腳本,若是要定製則要重載這個方法。方法中的參數request可用於獲取全部的動態請求的數據;方法返回值爲null時表明沒有腳本內容。

getToolbarScript()方法用於定製Web報表在頁面首部顯示的工具欄爲標準的樣式(上下翻頁,導出文件),能夠在此擴展工具欄的內容,如:添加公司主頁的連接,返回上一層連接的「返回」按鈕,若是要定製則要重載這個方法。方法中的參數request可用於獲取全部的動態請求的數據;方法返回值爲null時表明不添加內容。

isShowToolbar()方法用於設定是否在頁面上顯示報表工具欄。若是不想在頁面上顯示報表工具欄,可重載這個方法,並設定返回值爲false。須要注意的是,若是是多頁報表,上下翻頁按鈕就沒法使用。

getAllEchoButton()方法用於自定義顯示在Web頁面中的報表導出文件的按鈕,好比應用中只導出PDF文件,其餘的不須要,就能夠這裏設定。按鈕值從Word按鈕開始是(1,2,4,8,...),須要顯示的按鈕則將它們的值相加就能夠了。要做自定義,須要重載這個方法,並將返回值設爲要顯示的按鈕對應的和值。默認狀況下工具欄上的按鈕如圖12-6所示:

圖12-6    默認狀況下工具欄上的按鈕

(2)Report類

即com.javareport.beans.Report,報表類。這個類的對象用於表明一張報表,是全部報表元素的容器,這是整個系統的核心,也是在瀏覽器上顯示和生成電子文檔(Word,Excel,PDF,Html等)的基礎。

Report類經常使用的方法有:

//--在報表的頁眉添加一條橫直線,參數num表示橫直線的粗細程度,數字越大線越粗

public java.lang.String addHeaderSeparator(int num)

//--在頁眉中添加若干個空格,參數num是要添加的空格的個數

public java.lang.String addHeaderSpace(int num)

//--用於在頁眉中添加若干個【Tab】鍵,參數num是要添加的【Tab】鍵的個數

public java.lang.String addHeaderTab(int num)

//--在頁眉中添加一個換行符號,緊跟後面的內容則從下行第一個字符的位置開始

public java.lang.String addHeaderBreak()

//--在頁眉中添加文本信息內容,緊跟後面的內容則從下行第一個字符的位置開始

public java.lang.String addHeaderText(java.lang.String text)

//--在報表中添加圖表信息內容,參數chart是要添加的圖表

public java.lang.String addChart(ChartImpl chart)

//--設置報表當前的字體,參數是要設置的字體對象,爲Java中java.awt.*包中的Font對象

public void setCurrentFont(java.awt.Font font)

//--設置報表當前的背景顏色

public void setCurrentBackground(java.awt.Color color)

//--設置報表當前的前景顏色

public void setCurrentForeground(java.awt.Color color)

//--在報表中添加圖片信息內容

public java.lang.String addImage(java.awt.Image image)

//--添加項目符號的表示符號。第一種形式添加默認的項目符號(圓點)的表示符號,

//--第二種形式用自定義的圖片內容代替默認的圓點內容

public java.lang.String addBullet()或

public java.lang.String addBullet(java.awt.Image image)

//--在報表中添加一個換行符號,緊跟後面的內容則從下行第一個字符的位置開始。

//--參數num表明換行的數量,即屢次換行

public java.lang.String addNewline(int num)

//--在報表中添加一條橫直線,參數num表示橫直線的粗細程度

public java.lang.String addSeparator(int num)

//--添加若干個空格,參數num表明空格的個數

public java.lang.String addSpace(int num)

//--在報表中添加若干個【Tab】鍵,參數num是要添加的【Tab】鍵的個數

public java.lang.String addTab(int num)

//--在報表中添加文本信息內容,緊跟後面的內容則從下行第一個字符的位置開始

//--參數text爲要添加的文本信息內容

public java.lang.String addText(java.lang.String text)

//--添加報表中的表格信息內容,參數table是要添加的表格

public java.lang.String addTable(Table table)

//--在頁尾添加一條橫直線,參數num爲橫直線的粗細程度

public java.lang.String addFooterSeparator(int num)

//--在頁尾添加若干個空格,參數num表明要添加的空格的個數

public java.lang.String addFooterSpace(int num)

//--在頁尾添加若干個【Tab】鍵,參數num爲要添加的【Tab】鍵的個數

public java.lang.String addFooterTab(int num)

//--在頁尾添加一個換行符號,緊跟後面的內容則從下行第一個字符的位置開始

public java.lang.String addFooterBreak()

//--在頁尾添加文本信息內容,緊跟後面的內容則從下行第一個字符的位置開始

public java.lang.String addFooterText(java.lang.String text)

addHeaderText ()方法和addFooterText()方法中的參數text是要添加的文本信息內容。其中,{P}表明當前頁,{N}表明總頁數,如:「第{P}頁,共{N}頁」。

(3)Table類

即com.javareport.beans.Table,表格類。這個類的對象屬於報表對象Report中的元素。表格在報表中是不可缺乏的,整齊排列着數據內容。表格單元裏面的內容能夠是文本內容,也能夠是圖形和其餘元素,同時這個對象也是表套表的基礎。JavaReport會自動處理表格的跨頁、分頁問題和新頁中的表頭顯示問題,開發過程當中把它想象成連續的就能夠了。

Table類的經常使用方法有:

//--構造函數,參數data爲填充表格內容的二維數組

public Table(java.lang.Object[][] data)

(4)Chart類

即com.javareport.beans.Chart,圖表類。這個類的對象屬於報表對象Report中的元素。統計圖在報表中不可缺乏的,使用戶瀏覽更加直觀,能夠用這個類生成十幾種報表統計圖。Chart類經常使用的方法有:

//--設置圖表中指定的單元或全部單元的數據

public void setData(int i,int j,java.lang.Number data)或

public void setData(java.lang.Number[][] data)

//--設置統計圖的類型,統計圖能夠是:曲線圖,百分比圖等。

public void setStyle(int type)

setData()方法的第一種形式參數說明以下:

參數i指定的二維數據單元的座標x的值;參數j指定的二維數據單元的座標y的值;參數data用於給指定的單元賦值,數據能夠是Byte, Double, Float, Integer, Long, Short,這些數據類型都是Number類的子類。

setData()方法的第二種形式參數data是一個二維的數據,數據能夠是Byte、Double、Float、Integer、Long、Short。

setStyle()方法中的參數type是指定的統計圖類型,總共有十多種,經常使用常量來表示,經常使用的有如下幾種。

Chart.CHART_PIE3D:立體餅圖

Chart.CHART_STACKBAR3D:立體條形圖

Chart.CHART_CURVE:曲線圖

Chart.CHART_LINE:線圖

Chart.CHART_POINT:點圖

Chart.CHART_INVERTED_CURVE:反向曲線圖

Chart.CHART_INVERTED_LINE:反向線圖

Chart.CHART_INVERTED_STACKBAR:橫向的條形圖

(5)RsTable類

即com.javareport.beans.RsTable,記錄集表格類。這個類的對象屬於報表對象Report中的元素。RsTable類具備Table類的所有功能,是針對統計報表中顯示記錄集是一個很是頻繁使用的動做而設計的,開發者使用它時可以用幾行代碼就可把一個JDBC記錄集裏的數據以表格形式列舉顯示出來。RsTable類經常使用的方法有:

//--構造函數,參數rs是填充表格內容的記錄集;參數as是記錄集中列的名稱映射表,

//--好比記錄值中「ID」映射爲「編號」,則報表的表頭名稱列顯示爲「編號」

public RsTable(java.sql.ResultSet rs)或

public RsTable(java.lang.String[] as,java.sql.ResultSet rs)

//--設置表頭與列名的映射關係,參數as是映射關係中的對照表,是一個二維數組

public void setMapping(java.lang.String[][] as)

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

JavaReport的應用

 

JavaReport不只能用來開發報表,也能開發統計圖形。下面來看看一些常見的使用場合下JavaReport是如何被應用的。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

開發Web報表的方法

 

在JSP頁面中與在Servlet中開發Web報表的用法有所不一樣。

(1)在JSP頁面中開發Web報表

開發JSP時,自定義的JSP須要從WebReportEngine類繼承下來:

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="javax.servlet.*"%>

<%@ page import="com.javareport.beans.*"%>

<%@ page extends="com.javareport.http.WebReportEngine"%>

<%!

public Report createReport(HttpServletRequest request) throws Exception {

……

}

……

%>

根據以上的代碼,大多數狀況下重載了createReport()方法就能知足須要了,報表的樣式和內容等設置就在這函數裏來實現;若是須要也能夠重載其餘函數。更詳細的一個編程參考以下:

JSP報表開發模板

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="javax.servlet.*"%>

<%@ page import="com.javareport.beans.*"%>

<%@ page extends="com.javareport.http.WebReportEngine"%>

<%!

/******************************************************************************

 * 這是報表系統在應用中給開發人員的JSP模板文件,能夠根據須要調整接口內容。部分函

 * 數能夠適當刪除。在開發中通常是實現createReport()函數就能夠,造成實時動態報表

 * 就是在這個函數裏實現的。剩下的工做(怎樣在Web上顯示,怎樣造成Work,PDF文件等)

 * 交給報表引擎自動實現。

******************************************************************************/

/**

 * 創建報表,返回報表的實例。這個報表實例能夠在Web上顯示,同時也能夠導出Word,Excel,

 * PDF,CSV,HTML等格式的文檔供使用。

 */

public Report createReport(HttpServletRequest request) throws Exception{

  Report report = new Report();

  report.addText("This is a template !");

  return report;

}

/**

 * 這是對上一個頁面Form提交的參數進行檢查,因爲實時報表須要動態的參數,在這裏進

 * 行數據校驗。

 * 返回值爲null時表明經過,其餘內容則爲參數錯誤的提示信息。

 */

public String validate(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,內容顯示出來前執行的腳本,腳本內容通常爲JavaScript腳

 * 本或VBScript腳本。

 * 返回值爲null時表明經過沒有腳本內容。

 */

public String getStartScript(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,內容顯示出來後執行的腳本,腳本內容通常爲JavaScript腳

 * 本或VBScript腳本。

 * 返回值爲null時表明經過沒有腳本內容。

 */

public String getEndScript(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,上面的工具欄爲標準的樣式(上下翻頁,導出文件)。能夠在

 * 此擴展工具欄的內容,通常能夠添加公司主頁的連接,返回上一層連接的「返回」按鈕就是

 * 在這裏添加腳本的。

 * 返回值爲null時表明不添加內容。

 */

public String getToolbarScript(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,若是不想讓工具欄顯示出來,就讓函數的返回值就false就能夠。

 * 注意:若是是多頁報表,上下翻頁按鈕就沒法使用。

 */

public boolean isShowToolbar(){

  return true;

}

/**

 * 這是報表在Web上顯示時,導出文件的按鈕能夠自定義,好比應用中只要導出PDF文件,

 * 其餘的不須要,就能夠這裏設定。按鈕值從Work按鈕開始是(1,2,4,8,...),須要

 * 顯示的按鈕則將它們的值相加就能夠了。

 */

public int getAllEchoButton(){

  return 0xFFFF;

}

%>

(2)在Servlet中開發Web報表

在Servlet中,自定義的servlet須要從WebReportEngine類繼承下來,以下所示:

import javax.servlet.http.*;

import com.javareport.beans.*;

public class ReportExam extends WebReportEngine {

public Report createReport(HttpServletRequest request) throws Exception {

……

}

……

}

下面給出一個Servlet報表開發的詳細模板,以供參考。

Servlet報表開發模板

<%@ page contentType="text/html; charset=GBK" %>

import javax.servlet.http.*;

import com.javareport.beans.*;

public class Template extends WebReportEngine {

/******************************************************************************

 * 這是報表系統在應用中給開發人員的JSP模板文件,能夠根據須要調整接口內容。部分函

 * 數能夠適當刪除。在開發中通常是實現createReport()函數就能夠,造成實時動態報表

 * 就是在這個函數裏實現的。剩下的工做(怎樣在Web上顯示,怎樣造成Work,PDF文件等)

 * 交給報表引擎自動實現。

******************************************************************************/

/**

 * 創建報表,返回報表的實例。這個報表實例能夠在Web上顯示,同時也能夠導出Word,Excel,

 * PDF,CSV,HTML等格式的文檔供使用。

 */

public Report createReport(HttpServletRequest request) throws Exception{

  Report report = new Report();

  report.addText("This is a template !");

  return report;

}

/**

 * 這是對上一個頁面Form提交的參數進行檢查,因爲實時報表須要動態的參數,在這裏進

 * 行數據校驗。

 * 返回值爲null時表明經過,其餘內容則爲參數錯誤的提示信息。

 */

public String validate(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,內容顯示出來前執行的腳本,腳本內容通常爲JavaScript腳

 * 本或VBScript腳本。

 * 返回值爲null時表明經過沒有腳本內容。

 */

public String getStartScript(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,內容顯示出來後執行的腳本,腳本內容通常爲JavaScript腳

 * 本或VBScript腳本。

 * 返回值爲null時表明經過沒有腳本內容。

 */

public String getEndScript(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,上面的工具欄爲標準的樣式(上下翻頁,導出文件)。能夠在

 * 此擴展工具欄的內容,通常能夠添加公司主頁的連接,返回上一層連接的「返回」按鈕就是

 * 在這裏添加腳本的。

 * 返回值爲null時表明不添加內容。

 */

public String getToolbarScript(HttpServletRequest request){

  return null;

}

/**

 * 這是報表在Web上顯示時,若是不想讓工具欄顯示出來,就讓函數的返回值就false就能夠。

 * 注意:若是是多頁報表,上下翻頁按鈕就沒法使用。

 */

public boolean isShowToolbar(){

  return true;

}

/**

 * 這是報表在Web上顯示時,導出文件的按鈕能夠自定義,好比應用中只要導出PDF文件,

 * 其餘的不須要,就能夠這裏設定。按鈕值從Work按鈕開始是(1,2,4,8,...),須要

 * 顯示的按鈕則將它們的值相加就能夠了。

 */

public int getAllEchoButton(){

  return 0xFFFF;

}

%>

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

用JavaReport開發Web統計圖

 

【例12-4】 用JavaReport在Web中輸出統計圖

JavaReport支持多種統計圖,本例將實現用JavaReport來在JSP頁面中顯示一維數據的圖形,共實現了8種統計圖。

chartReport.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="com.javareport.beans.*"%>

<%@ page extends="com.javareport.http.WebReportEngine"%>

<%!

public Report createReport(HttpServletRequest request) throws Exception{

    //圖片類型數組

    int[] chartType = new int[]{

Chart.CHART_PIE3D,Chart.CHART_STACKBAR3D,

Chart.CHART_CURVE,Chart.CHART_LINE,

Chart.CHART_POINT,Chart.CHART_INVERTED_CURVE,

Chart.CHART_INVERTED_LINE,Chart.CHART_INVERTED_STACKBAR};

//單元數據的顯示標籤字符串數組

    String[] labels = new String[] {"湖南省","湖北省","廣西壯族自治區","廣東省"};

//實例化報表對象

    Report report = new Report();

    //在頁眉中添加文本信息內容

    report.addHeaderText("希賽軟考學院各省報名人數狀況");

    //在報表的頁眉添加一條橫直線

    report.addHeaderSeparator(1);

    //在頁尾添加一條橫直線

    report.addFooterSeparator(1);

    //在頁尾添加文本信息內容

    report.addFooterText("第{P}頁, 共{N}頁");

//循環輸出各類類型的圖片

    for (int i = 0; i < chartType.length; i++) {

        try {

        //實例化一個圖表對象

            Chart chart = new Chart((Number[][])getData(request));

            //設置圖表中的單元數據的顯示的標籤

            chart.setLabels(labels);

            //設置統計圖的類型

            chart.setStyle(chartType[i]);

            //設置統計圖中顯示的時候把具體的數值也顯示出來

            chart.setShowValue(true);

            //在報表中添加文本信息內容

            report.addText("報表中常見的報表統計圖表("+i+"): ");

            //在報表中添加圖表信息內容

            report.addChart(chart);

            //在報表中添加換行符號

            report.addBreak();

            report.addBreak();

            report.addBreak();

        }

        catch (Exception ex) {

            ex.printStackTrace();

        }

    }

    return report;

}

//讀者可根據須要設置數組的值,或從數據庫中取出值放入數組中以動態顯示數據

public Double[][] getData(HttpServletRequest request){

    Double[][] data = new Double[1][4];

    data[0][0] = new Double(50);

    data[0][1] = new Double(50);

    data[0][2] = new Double(35);

    data[0][3] = new Double(55);

    return data;

}

//定製Web報表在頁面首部顯示的工具欄爲標準的樣式,增長一個"返回"按鈕,返回到首頁

public String getToolbarScript(HttpServletRequest request){

    return "<a href=\"../index.htm\"><img src=\""+request.getRequestURI()+

"?op=Resource&name=/resource/back.gif\" border=\"0\" alt=\"返回\"></a>";

}

%>

程序的運行結果如圖12-7所示。

圖12-7    用JavaReport輸出Web統計圖

程序中首先是重載了createReport()方法,在這個方法的方法體中,先用「new Report()」生成了一個報表Report對象report,再設置了報表的頁眉頁腳,而後再用一個for循環輸出了8種Web統計圖。

重載getData()方法的目的是爲了設置顯示的Web統計圖所要表示的數據,這個方法的返回值是一個Double類型的二維數組,因爲第一維只有一行,即至關於一維數據。方法的返回值就是Web統計圖要表示的數據。

重載getToolbarScript()方法的目的是爲了定製Web報表在頁面首部顯示的工具欄爲標準的樣式,增長了一個「返回」按鈕,當點擊時返回到網站的首頁。

從上可見,JavaReport只使用了少許的代碼就輸出了美觀而又實用的Web圖形;實際工程中一維數據的數據來源經常來自於對數據庫中數據查詢的結果,這須要讀者自行編寫代碼實現,有興趣的讀者不妨試試。

例12-4中的代碼只是實現了一維數據的展示,有時也須要展示二維的數據。二維數據圖形與一維數據圖形的區別就是在數據展示上加大了數據的展示量,在同一個單元數據標籤處可顯示屬於同一個單元數據的多個數據。修改一下例12-4中getData()方法的內容,修改後的代碼以下:

public Double[][] getData(HttpServletRequest request){

    Double[][] data = new Double[4][4];

    data[0][0] = new Double(200); data[0][1] = new Double(250);

    data[0][2] = new Double(220); data[0][3] = new Double(280);

    data[1][0] = new Double(500); data[1][1] = new Double(700);

data[1][2] = new Double(520); data[1][3] = new Double(900);

    data[2][0] = new Double(350); data[2][1] = new Double(400);

data[2][2] = new Double(380); data[2][3] = new Double(320);

    data[3][0] = new Double(550); data[3][1] = new Double(590);

data[3][2] = new Double(337); data[3][3] = new Double(340);

    return data;

}

則程序運行的結果如圖12-8所示。

圖12-8    用JavaReport輸出二維數據圖形

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

用JavaReport輸出報表

 

【例12-5】 用JavaReport輸出報表

table.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="java.awt.*"%>

<%@ page import="com.javareport.beans.*"%>

<%@ page extends="com.javareport.http.WebReportEngine"%>

<%!

public Report createReport(HttpServletRequest request) throws Exception{

    //實例化報表對象

    Report report = new Report();

    //在頁眉中添加文本信息內容

    report.addHeaderText("報表輸出示例");

    //在報表的頁眉添加一條橫直線

    report.addHeaderSeparator(1);

    //在頁尾添加一條橫直線

    report.addFooterSeparator(1);

    //在頁尾添加文本信息內容

    report.addFooterText("第{P}頁, 共{N}頁");

//在報表中添加文本信息內容

    report.addText("銷售狀況一覽表(合併表格):");

    //在報表中添加換行符號

    report.addBreak();

    //在報表中添加表格

    report.addTable(getTable());

    //在報表中添加換行符號

    report.addBreak();

    return report;

}

//------獲得銷售狀況一覽表(合併表格)對象------

public Table getTable(){

    String[][] data = getTotalData();

    Table table = new Table(data);

    table.setAlignment(Table.H_CENTER + Table.V_CENTER);

    table.setColAutoSize(true);

    table.setRowBackground(0,Color.LIGHT_GRAY);

    table.setRowBackground(1,Color.LIGHT_GRAY);

    table.setColBackground(0,Color.LIGHT_GRAY);

    table.setRowBackground(7,new Color(255,255,128));

    table.setHeaderRowCount(2);

    table.setHeaderColCount(1);

    table.setRowBorder(table.LINE_THIN);

    table.setColBorder(table.LINE_THIN);

    table.setCellSpan(0,0,new Dimension(1,2));

    table.setCellSpan(0,1,new Dimension(2,1));

    table.setCellSpan(0,3,new Dimension(2,1));

    table.setCellSpan(0,3,new Dimension(2,1));

    return table;

}

//生成銷售狀況數據,實際工程中通常從數據庫中獲取

public String[][] getData(){

    String[][] data = new String[6][4];

    data[0][0] = "區域"; data[0][1] = "第一季度"; data[0][2] = "第二季度"; data[0][3] = "第三季度";

    data[1][0] = "華南地區"; data[1][1] = "¥2,000,000";

data[1][2] = "¥2,500,000"; data[1][3] = "¥2,200,000";

    data[2][0] = "華東地區"; data[2][1] = "¥6,000,000";

data[2][2] = "¥4,500,000"; data[2][3] = "¥4,800,000";

    data[3][0] = "華中地區"; data[3][1] = "¥500,000";

data[3][2] = "¥400,000"; data[3][3] = "¥700,000";

    data[4][0] = "華北地區"; data[4][1] = "¥3,000,000";

data[4][2] = "¥3,200,000"; data[4][3] = "¥2,500,000";

    data[5][0] = "東北地區"; data[5][1] = "¥4,000,000";

data[5][2] = "¥5,000,000"; data[5][3] = "¥4,400,000";

    return data;

}

//獲得銷售彙總統計數據,實際工程中通常從數據庫中獲取

public String[][] getTotalData(){

    String[][] data = new String[8][5];

    data[0][0] = "區域"; data[0][1] = "上半年"; data[0][3] = "下半年";

    data[1][1] = "第一季度"; data[1][2] = "第二季度"; 

data[1][3] = "第三季度";data[1][4] = "第四季度";

    data[2][0] = "華南地區"; data[2][1] = "¥2,000,000"; data[2][2] = "¥2,500,000";

data[2][3] = "¥2,200,000";data[2][4] = "¥0";

    data[3][0] = "華東地區"; data[3][1] = "¥6,000,000"; data[3][2] = "¥4,500,000";

data[3][3] = "¥4,800,000";data[3][4] = "¥0";

    data[4][0] = "華中地區"; data[4][1] = "¥500,000"; data[4][2] = "¥400,000";

data[4][3] = "¥700,000";data[4][4] = "¥0";

    data[5][0] = "華北地區"; data[5][1] = "¥3,000,000"; data[5][2] = "¥3,200,000";

data[5][3] = "¥2,500,000";data[5][4] = "¥0";

    data[6][0] = "東北地區"; data[6][1] = "¥4,000,000"; data[6][2] = "¥5,000,000";

data[6][3] = "¥4,400,000";data[6][4] = "¥0";

    data[7][0] = "總計"; data[7][1] = "¥15,500,000"; data[7][2] = "¥15,600,000";

data[7][3] = "¥14,600,000";data[7][4] = "¥0";

    return data;

}

//定製Web報表在頁面首部顯示的工具欄爲標準的樣式,增長一個"返回"按鈕,返回到首頁

public String getToolbarScript(HttpServletRequest request){

    return "<a href=\"../index.htm\"><img src=\""+request.getRequestURI()+

"?op=Resource&name=/resource/back.gif\" border=\"0\" alt=\"返回\"></a>";

}

%>

程序運行的結果如圖12-9所示。

圖12-9    用JavaReport輸出報表

讀者對照圖12-9再分析一下源代碼應當不難。程序中用到了table類的許多方法,用於設置表格中的各類格式,如合併單元格,背景顏色,前景顏色等。

【專家提示】實際工程中,報表的數據每每來自於數據庫中,所以須要在getTotalData()方法中編寫代碼從數據庫中獲得統計數據,統計的方法是能夠使用特定的SQL語句或取出數據後在Java語句中統計。

輸出報表還有一種更直接的方法,就是用SQL語句查詢出數據庫中的數據後會獲得一個ResultSet對象,如rs,再用以下的語句:

RsTable rsTable = new RsTable(rs)

rsTable對象取爲RsTable類的一個實例。重載以下的方法:

public RsTable getRsTable(HttpServletRequest request)  throws Exception

將返回值設爲rsTable便可將數據庫查詢的結果做爲二維表格中的數據直接輸出了,而沒必要再轉換成二維數組中的數據再輸出到報表中,這樣能夠大大減小程序員須要編寫的代碼量。

 
 
 
 

第 12 章:Web圖表開發做者:鄧子云赫斌等    來源:希賽網    2014年03月10日

 

小結

 

JFreeChart是一個開源的組件包,它提供了Java中經常使用統計圖形來快速開發API,程序員只須掌握少許的接口就能繪製出漂亮的圖形,並且這些圖形不只可用於帶有客戶端界面的Java應用程序中,也能夠是在JSP、Servlet、Java Applet中。JFreeChart可用於建立餅圖、線圖、柱狀圖、散點圖和甘特圖等,本章重點介紹了條形圖和線形圖的開發。若是讀者想要開發出更復雜和豐富多彩的圖形,可對JFreeChart的API做進一步的研究。

JavaReport是一款國產的第三方組件包,可用於開發Web報表,報表中能夠有數據,也能夠使用其簡單的統計圖形編程接口,以少許的代碼開發出所需的報表,並可導出成PDF、EXCEL等格式文件,且中文支持較好,較爲實用。

 
 
 
 

第 13 章:Struts開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

Struts概述

 

第13章  Struts開發

【本章專家知識導學】

Struts是近年來至關流行的一種web開發框架,是在Model 2的基礎上實現的一個MVC框架,其目標就是但願分離Web程序的表示層、控制層和後臺模型層,使程序員能將更多的精力投入到後臺的業務邏輯設計與開發中,而不是底層的Web基礎架構。

本章首先對Stuts做了簡要的概述,包括MVC模式、JSP模式的發展及Struts的工做原理;接着介紹了Struts的安裝及其配置文件的功能及使用;而後以一個Struts應用程序實例講解了Struts開發Web程序的過程,最後介紹了標籤庫的使用。

這一章旨在讓你們對Struts框架有一個總體認識,讀者可以靈活地運用Struts自行開發各類Web應用程序。

13.1  Struts概述

Struts是一種web開發框架,是在Model 2的基礎上實現的一個MVC框架,能夠在Java Servlet和JSP中用來構建Java Web應用程序,是Apache軟件基金下Jakarta項目的一部分。

爲何叫Struts呢?Struts這個名字來源於在建築和舊式飛機中使用的支持金屬架。當創建一個物理建築時,建築工程師會使用支柱爲建築的每一層提供支持。一樣,軟件工程師能夠使用Struts爲業務應用的每一層提供支持。它的目的是就是幫助你減小運用MVC設計模型開發Web應用時的時間。

爲了更好地理解Struts,讀者須要對MVC模式和Model 2有一個認識,下面就先來說解MVC模式。

 
 
 
 

第 13 章:Struts開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

MVC模式

 

MVC是目前普遍流行的一種軟件設計模式,早在20世紀70年代,IBM就推出了Sanfronscisico項目計劃,這其實就是MVC設計模式的研究。 

MVC是Model-View-Controller的簡稱,即把一個應用程序的輸入、處理、輸出流程按照View 、Model、Controller的方式進行分離,這樣一個應用被分紅三個層——視圖層、模型層和控制層。圖13-1顯示了MVC模式各個模塊的功能及相互關係。

圖13-1 MVC模式

一、視圖(View)

視圖是模型的表示,是用戶看到並與之交互的界面,對於Web應用來講,能夠歸納爲HTML界面,但也有可能爲XHTML、XML或Applet。隨着應用的複雜性和規模性,界面的處理也變得具備挑戰性。一個應用可能有不少不一樣的視圖,MVC設計模式對於視圖的處理僅限於視圖上數據的採集和處理,以及用戶的請求,而不包括在視圖上的業務流程的處理。業務流程的處理交予模型(Model)處理。 

二、模型(Model)

模型是應用程序的主體,負責業務流程、業務狀態的處理以及業務規則的制定。業務流程的處理過程對其餘層來講是黑箱操做,模型接受視圖請求的數據,並返回最終的處理結果。業務模型的設計能夠說是MVC最主要的核心。目前流行的EJB模型就是一個典型的應用例子,它從應用技術實現的角度對模型作了進一步的劃分,以便充分利用現有的組件,但它不能做爲應用設計模型的框架。它僅僅告訴你按這種模型設計就能夠利用某些技術組件,從而減小了技術上的困難。對一個開發者來講,就能夠專一於業務模型的設計。MVC設計模式告訴咱們,把應用的模型按必定的規則抽取出來,抽取的層次很重要,這也是判斷開發人員是否優秀的設計依據。抽象與具體不能隔得太遠,也不能太近。MVC並無提供模型的設計方法,而只告訴你應該組織管理這些模型,以便於模型的重構和提升重用性。咱們能夠用對象編程來作比喻,MVC定義了一個頂級類,告訴它的子類你只能作這些,但無法限制你能作這些。這點對編程的開發人員很是重要。  

三、控制器(Controller)

控制器主要負責View和Model之間的流程控制,也就是完成兩個方向的動做:一個是將View的操做映射到具體的Model,以完成具體的業務邏輯;另外一個是將經過Model處理完的業務數據及時反映到View上。控制層的做用就像是一個分發器,它清楚地告訴你應該選擇什麼樣的模型,選擇什麼樣的視圖,能夠完成什麼樣的用戶請求,而它並不作任何的數據處理。當用戶經過某個視圖的控制器改變了模型的數據時,全部其它依賴於這些數據的視圖都會反映這些變化。所以,不管什麼時候發生了何種數據變化,控制器都會將變化通知全部的視圖,致使顯示的更新。應次,模型、視圖與控制器的分離,使得一個模型可能對應多個視圖,一個視圖可能對應多個模型。 

MVC設計模式基於如下設計理念:在一個應用系統中,用戶界面發生變更的可能性最大,控制部分次之,而業務邏輯是最穩定的。所以爲業務邏輯編寫的代碼不該該和反應用戶界面的代碼混雜在一塊兒,而是彼此應該儘量地獨立,由控制器來擔當二者交互的中介。下面咱們以一個基於Internet的電信交話費這一過程爲例介紹一下基於MVC模式的實現,處理過程如圖13-2所示。

圖13-2 電信交話費過程基於MVC模式的實現

 
 
 
 

第 13 章:Struts開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

JSP模式的發展

 

JSP開發模式的發展主要經歷瞭如下三個階段:

一、階段1

早期的Java Web開發應用中,全部工做都交給JSP來處理,如圖13-3所示。

圖13-3 JSP Model

在這種模式下,JSP文件不只要負責生成網頁、控制網頁流程,還要負責處理業務邏輯,給WEB開發帶來了一系列的問題

①強耦合。HTML和Java強耦合在一塊兒,致使頁面設計與邏輯處理沒法分離。

②調試困難。

③可讀性差,不利於維護。在須要更改業務處理邏輯或數據時,可能要牽扯到多個網頁。

二、階段2

隨着技術的進一步發展,JSP頁面功能開始逐步劃分,引入了JavaBean與JSP頁面共同協做完成任務,這就是JSP Model 1,如圖13-4所示。在Model 1 架構中,JSP 直接處理Web 瀏覽器送來的請求,並輔以JavaBean 處理應用相關邏輯。Model 1 架構單純編寫比較容易,但在Model 1 中JSP 可能同時肩負View 與Controller 角色,兩類程序代碼有可能混雜而不易維護。

圖13-4  Model 1

三、階段3

功能進一步劃分,在Model 1的基礎上又引入了Servlet,造成Model 2,如圖13-5所示。Model 2 中將Servlet 歸入架構中扮演前端Controller 角色,將Web 瀏覽器送出的請求集中送至Servlet,Servlet再視需求轉向給對應的JSP 處理。在這一模式中,JSP負責生成動態的網頁,Servlet負責流程控制,JavaBean負責業務邏輯。Model 2 中採用了較佳的MVC 模式,但Model2 容易使系統出現多個Controller,而且對頁面導航的處理也比較複雜,有些人以爲model 2仍不夠好,因而Craig R. McClanahan 於2000年5月提交了一個WEB framework給Java Community,這就是後來的Struts。2001年7月,Struts1.0正式發佈。

圖13-5  Model 2

 
 
 
 

第 13 章:Struts開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

Struts的工做原理

 

做爲一個MVC的框架,Struts對Model、View和Controller都提供了對應的實現組件,圖13-6顯示了Struts框架響應客戶請求時各個組成部分的工做原理。

圖13-6  Struts的組件結構

一、視圖

Struts應用程序中的View主要採用JSP技術和通用標籤庫技術實現。利用Struts提供的自定義標記庫(tag libraries)定義的標記建立的JSP表單,能夠實現和Model部分中的ActionForm的映射,完成對用戶數據的封裝,同時這些自定義標記還提供了像模板定製等多種顯示功能。

二、模型

Struts爲Model部分提供了Action和ActionForm對象:全部的Action處理器對象都是開發者從Struts的Action類派生的子類。Action處理器對象封裝了具體的處理邏輯,調用業務邏輯模塊,而且把響應提交到合適的View組件以產生響應。Struts提供的ActionForm組件對象,它能夠經過定義屬性描述客戶端表單數據。開發者能夠從它派生子類對象,利用它和Struts提供的自定義標記庫結合能夠實現對客戶端的表單數據的良好封裝和支持,Action處理器對象能夠直接對它進行讀寫,而再也不須要和request、response對象進行數據交互。經過ActionForm組件對象實現了對View和Model之間交互的支持。

三、控制器

在Struts中,Controller功能由圖中ActionServlet和ActionMapping對象實現。ActionServlet接受客戶端的請求,而ActionServlet包括一組基於配置的ActionMapping對象,每一個ActionMapping對象實現了一個請求到一個具體的Model部分中Action處理器對象之間的映射。因此,Controller的做用是從客戶端接受請求,而且選擇執行相應的業務邏輯,而後把響應結果送回到客戶端。

Struts的工做流程歸納以下:

一、用戶提出請求,Controller ActionServlet接受此請求並在struts-config.xml文件中檢索與用戶請求相匹配的ActionMapping實例,若是找不到則返回用戶請求路經無效的信息。

二、若是找到,則利用配置的ActionMapping對象把請求映射到Action處理器對象進行處理。Action處理對象訪問ActionForm中的數據,處理和響應客戶請求。Action處理器對象根據處理結果通知Controller,Controller進行下一步的處理。

三、Controller最後將Model處理的結果經過調用View呈現給用戶。

Struts可到以下的網址下載獲得:

http://struts.apache.org/downloads.html

目前Struts的版本比較多,在這兒咱們以struts-1.3.8版本爲例介紹它的安裝方法。解壓後的目錄結構如圖13-7所示。

圖13-7  Struts1.3.8目錄結構

要使用Struts開發應用程序,就必須把Struts的解壓包lib文件夾下的庫文件拷到應用程序的「WEB-INF\lib」文件夾下;把全部擴展名爲tld的標籤庫文件拷到WEB-INF文件夾下,以便使用標籤庫中提供的標記來建立JSP視圖。在Struts1.3.8中,讀者能夠到「src\taglib\src\main\resources\META-INF\tld」文件夾下找到標籤庫文件。此外,開發應用程序時所建立的struts-config.xml和web.xml配置文件也要放到WEB-INF\文件夾下。下面就來給介紹Struts的這兩個配置文件。

一、web.xml文件

web.xml文件是整個web工程的配置文件,它負責對Web工程的ActionServlet類、Struts標籤庫等進行配置。

web.xml文件

<!--web.xml文件以一個xml頭開始,聲明能夠使用的xml版本爲1.0, -->

<!--並給出文件的字符編碼爲UTF-8-->

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<!--頂層根元素爲web-app -->

<!--注意:xml元素大小寫敏感,如WEB-APP、WEB-app都是非法的,只能寫爲web-app-->

<!--xml還對元素次序敏感,如xml頭和web-app的次序不能改變-->

<!--下面的servlet元素也必須出如今全部servlet-mapping元素以前-->

<!--元素次序不對時,服務器能夠拒絕執行web應用-->

<web-app  xmlns="http://java.sun.com/xml/ns/j2ee" 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" 

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

>

<servlet>

<!--<servlet-name>元素定義用於Web應用的servlet-->

<!--<servlet-name>和<servlet-class>指定由ActionServlet接受請求,並肯定其如何響應-->

<servlet-name>action</servlet-name>

<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

<!--<init-param>元素定義servlet初始化參數-->

<init-param>

<param-name>config</param-name>

<param-value>/WEB-INF/struts-config.xml</param-value>

</init-param>

<!--下面的debug爲整數值,指定將處理的詳細信息寫到控制檯的程度-->

<!--默認值爲0,表示記錄相對最少的日誌信息-->

<init-param>

<param-name>debug</param-name>

<param-value>3</param-value>

</init-param>

<!--detail參數指示將「映射」詳細信息寫到控制檯的程度-->

<init-param>

<param-name>detail</param-name>

<param-value>3</param-value>

</init-param>

<!--使用<load-on-startup>實如今啓動應用程序時裝入servlet的功能-->

<load-on-startup>0</load-on-startup>

</servlet>

<!--<servlet-mapping>元素指定URL結尾的命名模式-->

<servlet-mapping>

<servlet-name>action</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>

<!--<welcome-file-list>元素指定歡迎頁面-->

<welcome-file-list>

<welcome-file>hello.jsp</welcome-file>

</welcome-file-list>

<!--聲明web應用所使用的Struts標籤庫,也可聲明用戶自定義標籤庫-->

<taglib>

<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>

<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>

</taglib>

<taglib>

<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>

<taglib-location>/WEB-INF/struts-html.tld</taglib-location>

</taglib>

<taglib>

<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>

<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>

</taglib>

</web-app> 

二、struts-config.xml文件

struts-config.xml是建立Struts框架的配置文件,在此文件中對Struts用到的視圖、模型和控制器進行配置。Struts框架容許把應用劃分紅多個組件以提升開發速度,而Struts框架的配置文件struts-config.xml能夠把這些組件組裝起來,決定如何使用它們。

struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"

"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>

<!-- <form-beans>元素配置了一個ActionForm Bean,名叫HelloForm -->

<!-- 其對應的類爲hello.HelloForm -->

    <form-beans>

        <form-bean name="HelloForm"  type="hello.HelloForm"/>

    </form-beans>

<!-- <action-mappings>元素配置了一個Action組件-->

<!--parh屬性指定請求訪問Action的路徑爲HelloWorld.do -->

<!--type屬性指定Action的完整路徑爲hello.HelloWorld -->

<!--scope屬性指定ActionForm Bean的存放範圍爲request -->

<!-- validate屬性指定是否執行表單驗證-->

<!--input屬性指定當表單驗證失敗時的轉發路經爲hello.jsp -->

  <action-mappings>

    <action     path = "/HelloWorld"

               type = "hello.HelloAction"

               name= "HelloForm"

               scope = "request"

               validate = "true"

               input = "/hello.jsp"

     >

     <!--<action>元素還包含<forward>子元素,來定義請求轉發路經-->

        <forward  name="SayHello" path="/hello.jsp" />

    </action>

  </action-mappings>

<!--<message-resources>元素定義了Resources  Bundle使用的資源文件-->

<!-- parameter屬性定義了該資源文件的文件名爲hello. ApplicationResources -->

<!--全名爲hello. ApplicationResources .properties-->

<!--存放路徑爲WEB-INF/classes/hello/ ApplicationResources.properties-->

  <message-resources  parameter="hello.ApplicationResources "/>

<!--< plug-in >元素配置Struts插件,能夠包含零個或多個<set-property >子元素-->

<!--本例配置了驗證規則Validator插件-->

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

    <set-property  value="/WEB-INF/validator-rules.xml,

/WEB-INF/asset-validation.xml"   property="pathnames" />

</plug-in>

</struts-config> 

本例中的<action>元素配置了HelloAction組件,對應的類爲hello.HelloAction,請求訪問路徑爲HelloWorld.do,當Action類被調用時,Struts框架應該把已經包含表單數據的HelloForm Bean傳給它,HelloForm Bean存放在request範圍內,而且在調用Action類以前,應該進行表單驗證(表單驗證規則存在於validator-rules.xml 和asset-validation.xml文件中)。若是表單驗證失敗,請求將被轉發到接收用戶輸入的網頁hello.jsp,讓用戶糾正錯誤。

三、ApplicationResources.properties文件

ApplicationResources.properties是Struts中的消息資源文件,用來支持國際化和本地化。除了默認的消息資源文件(使用本地語言編寫)之外,一個web應用能夠包含不少個用不一樣語言編寫的消息資源文件。下面咱們來看一下用Strtus實現國際化和本地化的步驟:

首先要定義資源文件的名稱,通常命名爲ApplicationResources.properties。這個文件包含了用默認語言編寫的在程序中會出現的全部消息,這些消息以「關鍵字-值」的形式存儲。ApplicationResources.properties文件的內容以下:

login.title=Struts Demo

login.heading=<h1>Welcome to the StrutsDemo !</h1>

lgoin.message=Welcome to the StrutsDemo !

login.inputPassword=Please input Password :

login.inputName=Please input Username :

loginOK.title= User Login Successfull

loginOK.message=<h1>Login Successfull !</h1>

error.username.required=<h3><font color="red">UserName is Required !</font></h3>

error.password.required=<h3><font color="red">Password is Required !</font></h3>

error.username.wrong=<h3><font color="red">UserName is Wrong !</font></h3>

error.password.wrong=<h3><font color="red">Password is Wrong !</font></h3>

errors.footer=</ul><hr>

errors.header=<h3><font color="red">Validation Error</font></h3>You must correct the following error(s) before proceeding:<ul>

error.email.exist=<h3><font color="red">emaail 已經存在 !</font></h3>

error.emailpwd.error=<h3><font color="red">emaail 兩次輸入密碼不一致!</font></h3>

error.dlzh.exist=<h3><font color="red">登陸賬號 已經存在 !</font></h3>

error.dlzhpwd.error=<h3><font color="red">登陸賬號 兩次輸入密碼不一致!</font></h3>

這個文件須要存儲在類的路徑下,並且它的路徑要做爲初始化參數傳送給ActionServlet,做爲參數進行傳遞時,路徑的格式要符合完整Java類的標準命名規範。在struts-config.xml中已給你們講過定義方法,在此再也不累述。

其次,爲了實現國際化,全部的資源文件必須都存儲在基本資源文件所在的目錄中。基本資源文件就是用默認地區語言-本地語言編寫的消息。若是基本資源文件的名稱是ApplicationResources.properties,那麼用其餘特定語言編寫的資源文件的名稱就應該是ApplicationResources_xx.properties(xx爲ISO編碼,如英語是en)。這些文件應包含相同的關鍵字,但關鍵字的值是用特定語言編寫的。

最後,ActionServlet的區域初始化參數必須與一個true值一塊兒傳送,這樣ActionServlet就會在用戶會話中的Action.LOCALE_KEY關鍵字下存儲一個特定用戶計算機的區域對象。

 
 
 
 

第 13 章:Struts開發做者:鄧子云赫斌等    來源:希賽網    2014年03月07日

 

如何利用Struts開發Web應用

 

Struts能夠集成到不少開發環境中去來開發Web應用程序,在這裏選用MyEclipse+Tomcat +Struts的環境配置。

【例13-1】  第一個Struts程序

下面以一個最簡單的例子來給你們講解一下Struts的應用。該例子將實現一個簡單的用戶登錄功能。處理邏輯如圖13-8所示。

圖13-8  用戶登錄處理流程圖

首先用戶進入登錄界面login.jsp,輸入用戶名和密碼(設都爲struts)。此登陸頁將調用LoginAction 來執行用戶的登陸操做。若是出現驗證錯誤或問題,LoginaAction 將引導用戶返回 login.jsp 頁面。然而,若是登陸成功,應用將轉向 loginSuccess.jsp 頁面,用戶可從新輸入。實現步驟以下:

一、先建立一個 Web Project,經過菜單 File > New > Project > MyEclipse>J2EE Projects> Web Project ,出現如圖13-9所示界面。

圖13-9 配置Web工程

輸入工程名ch13,其它項默認,而後單擊Finish按鈕,這樣咱們就建立了一個Web工程。

二、爲ch13工程添加Struts組件。 選中ch13工程,點擊右鍵,MyEclipse > Add  Struts Capabilities… 。出現如圖13-10所示界面。 

圖13-10  配置Struts  Capabilities

這兒咱們將該項目所建立的類存放到test包下,其它選項默認,點擊Finish按鈕,這樣咱們就把Struts所需的組件添加到項目ch13中,添加後的項目的目錄結構如圖13-11所示。

圖13-11 ch13的目錄結構

四、建立Struts應用。咱們先來建立login.jsp及其ActionForm 和 Action。

經過菜單選擇 File > New > Other... > Web-Struts > Struts 1.1> Struts 1.1 Form,Action & JSP, 如圖13-12所示。

圖13-12  New Form對話框

在Use case中輸入登錄用例的名字login(注意:Use case的名字必須輸入),則Name與Form type兩項則會自動填充。而後選中Form Properties標籤項,點擊Add按鈕,出現如圖13-13所示界面,爲login.jsp表單添加兩個屬性name和password。其中,須要把password屬性的JSP input type設爲password,這樣能夠在輸入密碼時不顯示輸入的內容。

圖13-13  添加表單屬性

而後選中Methods標籤,使複選框處於非選中狀態;選擇JSP標籤,選中複選框,併爲建立的JSP文件指定存放路經。如圖13-14所示。

圖13-14  建立JSP頁面

設置完畢後,單擊 Next 按鈕,出現 New Action 對話框,如圖13-15所示。在此對話框爲一些選項提供了默認值,在此無需修改。

圖13-15 New Action對話框

在此對話框可單擊 Forwards 標籤來定義重定向的屬性,定義後的屬性如圖13-16所示。

圖13-16 定義ActionForwards

至此就完成了login用例的JSP、Action和ActionForm的建立。MyEclipse 會自動更新 struts-config.xml 文件。建立成功後的各文件代碼以下:

login.jsp

<%@ page language="java"%>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> 

<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>

<html> 

<head>

<title>JSP for loginForm form</title>

</head>

<body>

<html:form action="/login">

name : <html:text property="name"/><html:errors property="name"/><br/>

password : <html:password property="password"/>

<html:errors property="password"/><br/>

<html:submit/><html:cancel/>

</html:form>

</body>

</html>

LoginForm..java

package test.form;

import org.apache.struts.action.ActionForm;

public class LoginForm extends ActionForm {

private String password;

private String name;

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

 public String getName() {

return name;

 }

public void setName(String name) {

this.name = name;

}

}

LoginAction.java

package test.action;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

import test.form.LoginForm;

public class LoginAction extends Action {

/** 

* Method execute

* @param mapping

* @param form

* @param request

* @param response

* @return ActionForward

*/

public ActionForward execute(

ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response) {

  LoginForm loginForm = (LoginForm) form;

  if(loginForm.getName().equals("struts")  && 

loginForm.getPassword().equals("struts")) 

  { 

     request.setAttribute("Name", loginForm.getName()); //蔣獲取的輸入的用戶名賦給Name,以便在登錄成功頁面顯示登錄成功的用戶名

     return mapping.findForward("success"); 

  } 

 return mapping.findForward("failure"); 

}

}

Struts-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>

  <data-sources />

  <form-beans >

    <form-bean name="loginForm" type="test.form.LoginForm" />

  </form-beans>

  <global-exceptions />

  <global-forwards />

  <action-mappings >

    <action

      input="/login.jsp"

      name="loginForm"

      path="/login"

      scope="request"

      type="test.action.LoginAction">

      <forward name="failure" path="/login.jsp" />

      <forward name="sucess" path="/loginSuccess.jsp" />

    </action>

  </action-mappings>

  <message-resources parameter="test.ApplicationResources" />

</struts-config>

五、下面還須要建立登錄成功的頁面loginSuccess.jsp。這只是單純的一個JSP頁面,咱們只需經過New>JSP,出現如圖13-17所示對話框。

圖13-17  new JSP page對話框

點擊Finish後,編寫代碼以下:

loginSuccess.jsp

<%@ page language="java" pageEncoding="UTF-8" %>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-template" prefix="template" %>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-nested" prefix="nested" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html:html locale="true"> 

<head> 

<title>loginSuccess.jsp</title> 

</head> 

<body> 

<h2>Hello,<bean:write name="Name" scope="request" />! you successfully logged in!</h2> 

</body> 

</html:html>

五、把建立的應用程序部署到 Tomcat5服務器 。單擊工具條上的 Deploy J2EE Project to Server…按鈕,按鈕如圖13-18所示,出現圖13-19所示的對話框,在此對話框中,從Project下拉列表框選擇ch13,而後點擊Add按鈕,在彈出的對話框中選擇Tomcat 5,肯定以後顯示Successfully deployed說明部署成功。

圖13-18 Deploy Project按鈕

 

圖13-19 Project Deployments對話框

  六、運行應用程序。在圖13-18所示的工具條中點擊Open MyEclipse Web Browser按鈕,而後在地址欄內輸入http://localhost:8080/ch13/login.jsp,則運行效果如圖13-20所示。

圖13-20 運行login.jsp

若是在兩文本框中分別輸入’」struts」,則顯示圖13-21所示頁面,說明登錄成功。

圖13-21 登錄成功界面

 
 
 
 

第 13 章:Struts開發做者:鄧子云赫斌等    來源:希賽網    2014年03月10日

 

Struts標籤庫

 

Struts主要提供瞭如下幾類標籤庫:

一、HTML標籤:用來生成HTML標籤,提供顯示HTML對象的簡便方法。

二、Bean 標籤:用於訪問JavaBeans及其關聯屬性,以及定義一個新的bean。 

三、Logic 標籤:用於在JSP中控制流程、支持邏輯構造,管理條件產生的輸出和對象集產生的循環 。

四、Template 標籤:使用動態模板構造普通格式的頁面。 

五、Nested標籤:用於表達JavaBean之間的嵌套關係

在本書中咱們只給你們介紹前三個經常使用的標籤庫。

 
 
 
 

第 13 章:Struts開發做者:鄧子云赫斌等    來源:希賽網    2014年03月10日

 

HTML標籤庫

 

在文件struts-html.tld中定義了HTML 標籤庫的標記庫描述器。Struts HTML標記能夠大體地分爲如下幾個部分:

一、基本元素

(1)<html:html>標記

<html:html>標記在文件的起始位置產生<html>元素。該標記在1.2之前版本中有一個local屬性,但到了1.2版本之後被lang屬性所取代。以下的語句是使用<html:html>標記的一個示例:

<html:html lang="true">

當使用lang="true"屬性時,頁面將根據客戶端瀏覽器提供的Accept-Language頭部,來設置其locale值。

(2)<html:base>標記

<html:base>標記在文件的<head>處產生一個<base>的HTML元素,用於生成當前網頁的絕對URL路經。這個標籤只有內嵌在head標籤中才有效。

(3)<html:img>標記

<html:img>標記用來指定所顯示的圖像,屬性page用來指定圖像文件的路徑,還可經過heignt、width屬性來指定圖像顯示時的大小。以下的語句是使用<html:img>標記的一個示例:

<html:img page="/logo.gif"  height="50" width="200"> 

這個語句的功能是顯示logo圖像,高度爲50像素,寬度爲200像素。

(4)<html:link>標記和<html:rewrite>標記

<html:link>標記用來產生HTML中的<a>標記,而<html:rewrite>標記只能用來建立超連接中的URI部分,並不生成HTML的<a>元素。以下的語句是使用<html:link>標記的一個示例:

<html:link page="/index.html">Click Here</html:link>

二、基本表單元素

(1)<html:form>標記

<html:form>標記用來顯示HTML表單,能夠在此標記中指定AcitonForm bean的名稱和它的類名。若是沒有設置這些屬性,就須要有配置文件來指定ActionMapping以代表當前輸入的是哪一個JSP頁,以及從映射中檢索的bean名和類。若是在ActionMapping指定的做用域中沒有找到指定的名稱,就會建立並存儲一個新的bean,不然將使用找到的bean。

咱們下面所介紹的各類HTML輸入字段要內嵌在<html:form>標記中。<html:form>標記屬性如表13-1所示。

表13-1  <html:form>標記屬性

以下的語句是使用<html:form>標記的一個示例:

<html:form action="validateEmploee.do" method="post"/>

與表單相關的操做路徑是validateEmployee,而表單數據是經過POST傳遞的。對於這個表單來講,ActionForm bean的其餘信息,如bean名稱類型、做用域,都是從表單指定操做的ActionMapping中檢索獲得的。

(2)<html:text>和<html:textarea>標記

<html:text>和<html:textarea>標記分別表示HTML文�

相關文章
相關標籤/搜索