- 搞定J2EE核心技術與企業應用
- 常建功 王向華編著
- 6605字
- 2018-12-29 13:49:35
1.2 JavaEE核心技術
JavaEE為了適應大型企業級系統開發的需要,制定和規范了大量的技術,JavaEE核心技術平臺如圖1.5所示。

圖1.5 JavaEE核心技術平臺
下面對JavaEE所涉及的核心技術進行簡要講解。
1.2.1 JSP(Java服務頁面)
JSP(Java Server Pages)是由Sun公司組織其他公司一起建立的一種動態網頁技術標準。JSP技術的推出是為了對抗ASP,但它又有點類似ASP技術,它可以在傳統的網頁HTML文件中插入Java程序段和腳本文件及JSP標記。用JSP開發的Web應用是跨平臺的,既能在Linux下運行,也能在其他操作系統上運行。
JSP的運行方式是:當客戶端向服務器發出請求時,被請求的JSP首先被Web應用服務器編譯成Servlet并執行,然后將所產生的結果作為一個HTML文件傳給瀏覽器。如果該JSP文件沒有被修改過,當客戶端再次向服務器發出請求時,JSP文件將不會再被編譯,而是直接執行已編譯好的Servlet,從而加快了訪問速度。
JSP內置了6種對象,它們分別是:
● Request,該對象封裝了用戶提交的信息,通過調用該對象相應的方法可以獲取用戶提交的信息。
● Response,該對象對客戶的請求做出動態的響應,向客戶端發送數據。
● Session,該對象在第一個JSP頁面被裝載時自動創建,同時產生一個ID號,JSP引擎同時將這個ID號發送到客戶端,存放在Cookie中,當客戶再次訪問連接該服務器的其他頁面時,不再分配給客戶新的Session對象,這樣Session對象和客戶之間就建立了一一對應的關系。直到客戶關閉瀏覽器后,服務器端該客戶的Session對象才被取消,并且和客戶的會話對應關系消失,當客戶重新打開瀏覽器再次連接到該服務器時,服務器為該客戶再創建一個新的Session對象。
● Application,當服務器啟動時該對象自動創建,當客戶在所訪問網站的各個頁面之間瀏覽時,共享同一個Application對象,直到服務器關閉。與Session對象不同的是所有客戶端共享一個Application對象,而Session對象是一個客戶共享一個Session對象。
● Out,該對象是一個輸出流,用來向客戶端輸出各種數據。
● Cookie,該對象是服務器保存在客戶端硬盤上的一段文本,它以“關鍵字=值”的格式來保存內容,并且允許用戶自己創建和讀取它。
1.2.2 Servlet
借助Java的跨平臺特性,Servlet被設計成一種獨立于平臺和協議的服務器端的Java應用程序,可以生成動態的Web頁面。Servlet由Web服務器進行加載,該Web服務器必須包含支持Servlet的Java虛擬機。Servlet不是獨立的Java應用程序,沒有main方法,它不是由用戶直接調用,而是由容器調用的。
JSP編譯后就是Servlet,但它并沒有增強Servlet的功能,只是比直接使用Servlet進行編程更加方便。Servlet采用請求響應的工作方式,Servlet技術作為Web服務器功能的增強器,其功能涵蓋了從客戶端請求響應動態生成文檔到保證會話安全、訪問后臺數據庫服務器等。
每個Servlet都有自己的生命周期,都包含init和destroy方法,每個Servlet都需要實現Servlet接口,其主要的邏輯將集中在service方法中。當一個請求映射到一個Servlet時,該容器執行下列步驟:
01 如果一個Servlet的實例并不存在,Web容器將加載Servlet類,創建一個Servlet類的實調用init方法初始化Servlet實例。
02 調用service方法,傳遞一個請求和響應對象。
03 如果該容器要移除這個Servlet,可調用Servlet的destroy方法來結束該Servlet。Servlet的生命周期包括加載、初始化、處理客戶端請求及服務結束。
1.加載和初始化
在Servlet的生命周期中,僅執行一次init方法,它是在服務器裝入Servlet時執行的??梢耘渲梅掌鳎员阍趩臃掌骰蚩蛻魴C首次訪問Servlet時裝入Servlet。無論有多少客戶機訪問Servlet,都不會重復執行init方法。
2.處理客戶端請求
每一個請求由ServletRequest類型的對象代表,而Servlet使用ServletResponse返回該請求。這些對象被作為service方法的參數傳遞給Servlet,service方法是Servlet的核心。每當一個客戶請求一個ServletRequest對象時,該對象的service方法就要被調用。
當一個客戶通過HTML表單發出一個HTTP POST請求時,doPost方法被調用;當一個客戶通過HTML表單發出一個HTTP GET請求或直接請求一個URL時,doGet方法被調用。與GET請求相關的參數添加到URL的后面,并與這個請求一起發送。
在HTTP請求的情況下,容器必須提供代表請求和響應的HttpServletRequest和HttpServletResponse的具體實現。
3.服務結束
destroy方法和init方法一樣,僅執行一次,即在服務器停止且卸載Servlet時執行該方法。當服務器卸載Servlet時,將在所有service方法調用完成后,或在指定的時間間隔過后調用destroy方法。一個Servlet在運行service方法時可能會產生其他的線程,因此請確認在調用destroy方法時,這些線程已終止或完成。一旦destroy方法被調用,容器就不會再向該實例發送任何請求;如果容器需要再使用該Servlet,則必須創建新的實例。
1.2.3 EJB(企業級JavaBean)
EJB是一個Java服務器端組件開發的規范,定義了一個用來開發面向對象分布式應用組件的標準方法,軟件廠商根據它來實現EJB服務器。EJB主要由3種Bean組成:
● 會話Bean,用于實現業務邏輯,它可以是有狀態的,也可以是無狀態的。每當客戶端請求時,容器就會選擇一個會話Bean來為客戶端服務。
● 實體Bean,用于實現O/R(對象/關系)映射,負責將數據庫中的表記錄映射為內存中的Entity對象,事實上,創建一個實體Bean對象相當于新建一條記錄;修改一個實體Bean時,容器會自動將Entity Bean的狀態和數據庫同步;刪除一個實體Bean會同時從數據庫中刪除對應記錄。
● 消息驅動Bean,它基于JMS消息,只能接收客戶端發送的JMS消息然后處理。它實際上是一個異步的無狀態會話Bean,客戶端調用消息驅動Bean后無須等待,立刻返回,消息驅動Bean將異步處理客戶端請求。
Java程序員可以將一些EJB組件組合起來,從而方便、快捷地構建起分布式應用程序。EJB規范在簡化分布式應用程序開發復雜性方面也做了大量的工作,EJB程序員不必太擔心事務處理、多線程、資源管理等方面的問題,可以專注于支持應用所需的商業邏輯,而不用擔心周圍框架的實現問題。使用EJB可以使整個程序分塊明確,并且EJB可以使用其他EJB或JDBC等服務,從而增強了分布式應用程序的可擴展性和性能;另外,EJB的使用增強了整個系統程序的可靠性、可管理性和可移植性。
EJB的調用過程由如下幾步組成:先初始化上下文InitialContext,然后獲取遠程的或者本地的Home接口,再進行Home.create(),獲取遠程EJB對象,最后通過EJB對象調用業務方法。
1.2.4 JDBC(Java數據庫連接)
JDBC是Java提供的用來執行SQL語句的Java API,可以為多種關系數據庫提供統一訪問。它由一組用Java語言編寫的類和接口組成,是用于Java應用程序連接數據庫的標準方法。有了JDBC,向各種關系數據發送SQL語句就是一件很容易的事了。像ODBC一樣,JDBC對開發者屏蔽了一些細節問題;另外,JDBC對數據庫的訪問也具有平臺無關性,JDBC使用已有的SQL標準并支持與其他數據庫連接標準。
JDBC用來和數據庫打交道的一般步驟是:加載驅動程序、與數據庫建立連接、發送SQL語句、處理結果。示意代碼如下:
//加載驅動程序 Class.forName("com.ibm.db2.jcc.DB2Driver"); //建立連接 Connection con = DriverManager.getConnection (" jdbc:db2://10.1.1.10:50000/ db2 ","db2admin"," db2admin "); //創建Statement,發送SQL語句 Statement stmt = con.createStatement(); //獲取結果集 ResultSet rs = stmt.executeQuery(" select * from user "); //循環獲取結果集中的值 while(r.next()){ String s=r.getString("name"); }
目前,比較常見的JDBC驅動程序可分為以下4類。
● JDBC-ODBC橋+ODBC驅動程序:JDBC橋產品利用ODBC驅動程序提供JDBC訪問。這種類型的驅動程序最適合于企業網,或者用Java編寫的具有三層結構的應用程序服務器。
● 本地API:這種類型的驅動程序把客戶機API上的JDBC調用轉換為Oracle、Sybase、Informix、DB2或其他DBMS的調用。
● JDBC網絡純Java驅動程序:這種驅動程序將JDBC轉換為與DBMS無關的網絡協議,之后這種協議又被某個服務器轉換為一種DBMS協議。這種網絡服務器中間件能夠將它的純Java客戶機連接到多種不同的數據庫上,所用的具體協議取決于提供者。這是最為靈活的JDBC驅動程序,有可能所有的這種解決方案的提供者都提供適合于Intranet用的產品。
● 本地協議純Java驅動程序:這種類型的驅動程序將JDBC調用直接轉換為DBMS所使用的網絡協議。這將允許從客戶機上直接調用DBMS服務器,是Intranet訪問的一個很實用的解決方法。由于許多這樣的協議都是專用的,因此數據庫提供者自己將是主要來源。
1.2.5 JTA(Java事務)
一般來說,事務處理由若干個步驟組成。作為一個整體的操作過程,所有步驟必須同時操作成功或者失敗。當所有的步驟都操作成功時,事務就算操作成功了;而當其中某一個步驟操作失敗時,該步驟之前的操作就必須撤銷。簡單來說,所謂事務就是一系列必須都成功的操作,只要有一步操作失敗,所有其他的步驟將都被撤銷。因此,事務中有提交和回滾兩個概念。
● 提交(Commit):當所有的操作步驟都被完整執行后,稱該事務被提交。
● 回滾(RollBack):由于某一操作步驟執行失敗,導致所有步驟都沒有被提交,則事務必須回滾,即回到事務執行前的狀態。
在JavaEE中,事務主要有Bean-Managed Transaction和Container-Managed Transaction兩大類,其中在Bean-Managed Transaction中還會分為JDBC Transaction和JTA Transaction兩種。JTA的英文全稱是Java Transaction API,它為JavaEE平臺提供了分布式事務服務。要用JTA進行事務界定、提交和回滾,應用程序需調用javax.transaction.UserTransaction接口中的begin、commit和rollback方法。JTA接口包含在javax.transaction和javax.transaction.xa這兩個包中,進行JTA事務處理的示意代碼如下:
public void test() { //獲取事務 UserTransaction ut = context.getUserTransaction(); try { //事務開始 ut.begin(); //執行業務代碼 … //提交事務 ut.commit(); } catch (Exception ex) { try { //事務回滾 ut.rollback(); } catch (SystemException syex) { throw new EJBException ("Rollback failed: " + syex.getMessage()); } //拋出異常 throw new EJBException ("Transaction failed: " + ex.getMessage()); } }
JTA可以實現同一事務對應不同的數據庫,但它無法實現事務的嵌套。JTA只定義了一組Java接口用于描述JavaEE中事務管理器與應用程序、資源管理器及應用服務器之間的事務通信。它主要包括高層接口(即面向應用程序的接口)、XAResource接口(即面向資源的接口)及事務管理器的接口,JTA沒有具體的實現,JTS是服務OTS的JTA的實現。簡單地說,JTS實現了JTA接口,并且符合OTS的規范。
1.2.6 JavaMail(Java郵件服務)
JavaMail是Sun公司提供給開發者處理電子郵件的編程接口,它可以方便地執行一些常用的郵件傳輸。在使用JavaMail開發郵件系統之前,有必要先了解幾個常用的郵件傳輸協議。
● SMTP:英文全稱是Simple Mail Transfer Protocol,中文意思是“簡單郵件傳輸協議”,它由RFC821定義,定義了發送郵件的機制。在JavaMail環境中,基于JavaMail的程序將和因特網服務供應商(ISP)的SMTP服務器通信,SMTP服務器會將郵件消息發送給接收方SMTP服務器,以便最終讓用戶經由POP或者IMAP獲得。
● POP:英文全稱是Post Office Protocol,中文意思是“郵局協議”,它一般被稱為POP3,代表目前的版本號是3。這個協議是由RFC1939定義的。POP是一種機制,因特網上大多數用戶用它得到郵件。
● IMAP:英文全稱是Internet Message Access Protocol,中文意思是“因特網消息訪問協議”,它是更高級的用戶接收消息的協議。這個協議由RFC2060定義,它一般被稱為IMAP4,代表目前的版本號是4。在用到IMAP時,郵件服務器必須支持這個協議。
● MIME:英文全稱是Multipurpose Internet Mail Extensions,中文意思是“多用途的因特網郵件擴展”標準,它不是郵件傳輸協議,只是定義了被傳輸內容、附件及其他信息的格式。
核心JavaMail API由7個類組成:Session、Message、Address、Authenticator、Transport、Store及Folder。通過上述類,可以完成包括發送消息、接收消息、認證、回復消息、轉發消息、管理附件等功能。使用JavaMail來發送郵件的示意代碼如下:
//創建一個格式為“mail.smtp.host”的文件用來發送信息 Properties props = new Properties(); props.put("mail.smtp.host", "smtp.jspinsider.com"); //基于JavaMail的程序都至少需要一個或全部的對話目標 Session sendMailSession; sendMailSession = Session.getInstance(props, null); //郵件的傳輸只有送出或收到兩種狀態,傳輸將送出郵件,而存儲將收取郵件 Transport transport; transport = sendMailSession.getTransport("smtp"); //封裝郵件信息 Message newMessage = new MimeMessage(sendMailSession); //設定郵件內容 newMessage.setSubject("subject"); newMessage.setSentDate(new Date()); newMessage.setText("text"); //發送郵件 transport.send(newMessage);
1.2.7 JMS(Java消息服務)
JMS是JavaEE中有關面向消息中間件的技術規范,它提供創建、發送、接收和讀取消息的服務。它的英文全稱是Java Message Service,即Java消息服務。
JMS的消息傳遞機制分為兩種:點對點式(P2P)和發布訂閱式(P/S)。兩種消息的傳遞機制都實現了異步傳遞模式,點對點式通過Queue的形式,在Consumer(消費者)和Producer (制造者)之間進行了安全連接,使得消息傳遞只在這兩者之間進行。如果應用程序開發者希望每一條消息都能夠被處理,那么應該使用P2P消息模型;發布訂閱式通過Topic的形式,實現一到多的消息廣播,如果一定程度的消息傳遞的不可靠性可以被接受的話,那么應用程序開發者也可以使用P/S消息模型。
JMS中的消息由兩部分組成:報頭和消息主體。報頭由路由信息及有關該消息的元數據組成;消息主體則攜帶著應用程序的數據或有效負載。消息可以分為5種類型:簡單文本(TextMessage)、可序列化的對象(ObjectMessage)、屬性集合(MapMessage)、字節流(BytesMessage)和原始值流(StreamMessage)。
JMS的運行機制是:客戶機將消息發送給一個主題或隊列,而其他的JMS客戶機則預訂或監聽這個虛擬通道,當JMS客戶機發送消息后,它并不等待回應,而是繼續執行下一條指令,消息可能最終轉發到一個或多個客戶機,這些客戶機都不需要做出回應。發送一個消息隊列的示意代碼如下:
TextMessage message = queueSession.createTextMessage(); //設定要發送的消息 message.setText(msg_text); //發送消息 queueSender.send(message);
接收一個消息隊列的示意代碼如下:
Message m = queueReceiver.receive(); //判斷接收到的消息類型是否是文本類型 if (m instanceof TextMessage) { TextMessage message = (TextMessage) m; } else { //進行其他類型的處理 }
1.2.8 RMI(遠程方法調用)
RMI允許開發人員使用Java編寫分布式對象,它大大增強了Java開發分布式應用的能力。RMI的英文全稱是Remote Method Invocation,即遠程方法調用,它支持存儲于不同地址空間的程序級對象之間彼此進行通信,實現遠程對象之間的無縫遠程調用。
RMI用來進行通信的協議是JRMP(Java Remote Messaging Protocol,Java遠程消息交換協議), JRMP是專為Java的遠程對象制定的協議,是分布式應用系統的Java解決方案,但RMI對于用非Java語言開發的應用系統的支持不足,不能與用非Java語言書寫的對象進行通信。
使用RMI的步驟如下:
01 定義和實現遠端接口中的參數。
02 定義和實現遠端接口。
03 編寫服務端代碼。
04 編寫客戶端代碼。
05 生成stub和skeltion,并將stub打包到客戶端JAR中,將skeltion打包到服務器端JAR中。
06 啟動rmiregistry,并將服務注冊到rmiregistry中,然后運行代碼。
1.2.9 JNDI(Java命名和目錄服務)
JNDI是Sun公司提供的一種標準的Java命名系統接口,它的英文全稱為Java Naming and Directory Interface,即Java命名和目錄服務。它是一個應用程序設計的API,為開發人員提供了查找和訪問各種命名和目錄服務的通用、統一的接口,類似于JDBC,都是構建在抽象層上。使用JNDI的示意代碼如下:
Connection conn=null; try { //初始化上下文 Context ctx=new InitialContext(); //根據JNDI獲取數據源 DataSource ds =(Datasource)ctx.lookup("java:comp/env/jdbc/mydb"); //獲取連接 Connection c=ds.getConnection(); //進行業務處理 ... //關閉連接 c.close(); } catch(Exception e) { e.printStackTrace(); } finally { //關閉連接 if(conn!=null) { try { conn.close(); } catch(SQLException e) { } } }
為了讓JNDI解析java:comp/env/jdbc/mydb,必須把<resource-ref>標簽插入到web.xml文件中。web.xml文件中的示意代碼如下:
<resource-ref> <description>JNDI</description> //設定數據源 <res-ref-name>jdbc/mydb</res-ref-name> <res-ref-type>javax.sql.DataSource</res-ref-type> <res-auth>Container</res-auth> </resource-ref>
1.2.10 XML(擴展標識語言)
XML的英文全稱是eXtensible Markup Language,它是一種簡單的數據存儲語言,使用一系列簡單的標記描述數據,而這些標記可以用方便的方式建立。雖然XML比二進制數據要占用更多的空間,但XML極其簡單且易于掌握和使用。與數據庫不同的是,XML不提供數據索引、排序、查找等功能,它僅僅是展示數據。下面展示一個XML的示例:
<?xml version="1.0"?> <employees> <employee> <name>志學</name> <sex>男</sex> <age>28</age> <department>信息化部</department> <head>項目經理</head> </employee> </employees >
SGML是所有標記語言的母語言,HTML和XML都派生自SGML,這三者之間的關系如圖1.6所示。

圖1.6 HTML、XML和SGML之間的關系
HTML、SGML和XML將憑借各自的特點繼續用于其合適的地方,它們中的任何一個都不會使其他的廢棄。HTML仍是在Web上快速發布數據的最簡單的方法;SGML在高端復雜結構的應用及規范制定方面將繼續適用;而對于數據廣泛性和靈活性有特定要求的用戶,XML則是最好的選擇。
1.2.11 JMX(Java分布式管理)
JMX是一個為應用程序、設備、系統等植入管理功能的框架,它的英文全稱是Java Management Extensions,即Java分布式管理。JMX可以跨越一系列異構操作系統平臺、系統體系結構和網絡傳輸協議,靈活地開發無縫集成的系統、網絡和服務管理應用。
JMX的體系結構圖如圖1.7所示。

圖1.7 JMX的體系結構圖
JMX的體系結構分為以下4個層次。
● 設備層:主要定義了信息模型。在JMX中,各種管理對象以管理構件的形式存在,需要管理時,向MBean服務器進行注冊。
● 代理層:主要定義了各種服務及通信模型。該層的核心是一個MBean服務器,所有的管理構件都需要向它注冊,才能被管理。
● 分布服務層:主要定義了能對代理層進行操作的管理接口和構件,這樣管理者就可以操作代理了。
● 附加管理協議API:定義的API主要用來支持當前已經存在的網絡管理協議,如SNMP、TMN、CIM/WBEM等。
1.2.12 JACC(Java容器授權合同)
JACC為了將各種授權認證服務器置入到JavaEE產品中,它在JavaEE應用服務器和特定的授權認證服務器之間定義了一個連接協議。JACC的英文全稱是Java Authorization Service Provider Contract for Containers,它是一種基于標準的方法,用于將外部安全管理器與應用服務器集成。JACC提供了將安全授權的權限檢查委托給外部提供程序的功能。由于授權檢查是在容器將控制權交給應用程序前進行的,因此JACC具有能夠清楚區分自定義授權邏輯和應用程序邏輯的優勢,從而滿足了關注點分離的需求。
1.2.13 JCA(Java連接器體系)
JCA定義了一種使JavaEE應用程序與EIS用一種安全和事務性的方式進行通信的方法。JCA的英文全稱是Java Connector Architecture,即Java連接器體系,它幫助開發者進行不同種類的EIS之間的無縫集成,用一種安全和事務性的方法連接JavaEE應用程序和非JavaEE環境。JCA連接器一方面與JavaEE應用服務器建立系統級連接,另一方面與訪問EIS資源的應用組件建立應用級連接。
JCA規范中定義了兩種級別的編程接口:
● 公共客戶機接口,任何JavaEE組件都可以用這種接口與EIS進行交互。
● 系統編程接口,它們只在應用程序服務器內部使用。
JCA的體系結構圖如圖1.8所示。

圖1.8 JCA的體系結構圖
使用JCA比使用JMS能更好地結合JavaEE應用程序和EIS,使用JCA和JMS連接JavaEE和EIS的示意圖如圖1.9所示。

圖1.9 使用JCA和JMS連接JavaEE和EIS的示意圖
- 極簡AI入門:一本書讀懂人工智能思維與應用
- Mastering Machine Learning Algorithms
- Learning C for Arduino
- 21天學通C語言
- 工業機器人應用案例集錦
- Google SketchUp for Game Design:Beginner's Guide
- 工業機器人安裝與調試
- DevOps Bootcamp
- 新編計算機圖形學
- Azure PowerShell Quick Start Guide
- 從零開始學PHP
- R Machine Learning Projects
- Visual Studio 2010 (C#) Windows數據庫項目開發
- 數字多媒體技術基礎
- 步步驚“芯”