Java EE 5 是 Java 企業(yè)級應用規(guī)范的最新標準,,它在以往版本的基礎上進行了大范圍的改進,吸取了開源領域廣泛使用的技術(例如 POJO,,IoC),,降低了 Java EE 的學習難度,簡化了企業(yè)級應用程序的開發(fā),,提高了開發(fā)效率,。
以下是 Java EE 5 中引入的五個比較重要的技術:
- Java Annotation 不是 Java EE 5 中的技術,它是 Java 5 的一個新的特性,。但是在 Java EE 5 中大量的使用了 Annotation,,因為它的使用,極大的簡化了 Java EE 應用程序的開發(fā)和維護,。
- Java Server Faces (JSF)是對 JSP 技術的一種擴展和增強,,它已經存在了一段時間,,但并沒有被包含在 J2EE 規(guī)范中,用戶需要在他們的 Web 應用中包含 JSF 的 jar 文件來支持 JSF 技術,。Java EE 5 中包含了最新的 JSF 1.2 規(guī)范,,從而在 WAS CE v2.1 上開發(fā) JSF的應用也變得更加容易。
- Java Persistence API (JPA)是用來代替 J2EE 中 Entity Bean 的一種技術規(guī)范,。在 Java EE 5 中,,Entity Bean 規(guī)范沒有進行任何更新,,舊的 Entity Bean 在 Java EE 5 中還被支持,,但新添加的 JPA 是將來 Java EE 中持久化技術的方向。使用 JPA 開發(fā)數(shù)據(jù)庫應用也變得更加簡單和容易,。
- Enterprise Java Bean (EJB) 3.0 是對 EJB 技術的一次比較大的改動,。EJB 3.0 充分利用了 Java Annotation,提供了一個新的 EJB 編程模型,,從而簡化了 EJB 應用程序的開發(fā),。
- JAX-WS 2.0 是 JAX-RPC 1.1 的一個后繼版本,JAX-RPC 不會再有新的版本,,而 JAX-WS 2.0 會成為 Java EE 5 中實現(xiàn) Web Service 的技術,。
本文將通過開發(fā)一個網上商店的具體示例,向您展示如何在 WAS CE 中使用以上技術,。
為了在 WAS CE v2.1 中展示以上所提到的新技術,,我們假設了一個網上商店:Ollivanders (Harry Potter 的魔法世界中最好的魔杖商店),簡稱 OlliShop,。OlliShop 提供了簡單的 Web 界面,,用戶可以用此 Web 界面注冊、登錄和購買魔杖,;另外 OlliShop 向第三方集成商提供了 WebService 接口,,可以通過 SOAP 協(xié)議來調用 OlliShop 的服務。您可以下載本例的源代碼,。
網上商店的架構如圖 1 所示:
圖 1. OlliShop 的架構圖
OlliShop 由 5 個功能模塊組成:
- ShopWEB 是 OlliShop 的用戶界面,,用戶只能通過瀏覽器來訪問此模塊。ShopWEB 模塊使用了 JSF 技術,。
- ShopWS 是 OlliShop 的 Web Service 接口,,它提供了其它應用程序通過 Web Service 的方式訪問 OlliShop 的服務。此模塊使用了 JAX-WS 技術,。
- ShopUtil 是一個工具包,,包含一些公用的工具類以供其它模塊使用。
- ShopEJB 是業(yè)務實現(xiàn)模塊,,主要包括一個無狀態(tài) Session Bean,,供 ShopWEB 和 ShopWS 調用。此模塊使用了 EJB 3.0 技術。
- ShopJPA 是數(shù)據(jù)庫訪問模塊,,它通過 ORM 機制把對數(shù)據(jù)庫的操作轉換成對對象的操作,。此模塊使用了 JPA 技術。
WAS CE 作為一個開源的應用服務器,,選擇一個免費且強大的開發(fā)工具是很必要的,,Eclipse 就是一個不錯的選擇。WAS CE 提供了一個 Eclipse 插件,,可以通過此插件來管理 WAS CE 應用服務器,,開發(fā)、部署和調試 Java EE 的應用,,再配合 Eclipse 中的 WTP(Web Tools Platform)插件,,對于一個小規(guī)模的應用,這樣的 IDE 已經可以勝任,。
本文使用的 Eclipse 環(huán)境如下:
- Eclipse 3.4
- Eclipse WTP 3.0M2
- WAS CE Server adapter 2.1,,此插件可以從以下網址下載:http://public.dhe.ibm.com/software/websphere/wasce/updates/
在 Eclipse 的 J2EE 視圖中的 Servers view 處創(chuàng)建 WAS CE 服務器,如圖 2 所示,。
圖2. Eclipse中的WAS CE Server
現(xiàn)在我們開發(fā) Java EE 應用程序的環(huán)境已經準備好了,,可以開始 OlliShop 應用的開發(fā)了。OlliShop 包含了多個模塊,,是一個典型的 EAR 應用程序,,整個 OlliShop 的工程視圖如圖 3,它包括 6 個工程,。在后面的描述中我們將會具體介紹每一個工程,。
圖 3. OlliShop 中包含的工程
通過 Eclipse 中的 "Enterprise Application Project" 向導創(chuàng)建一個 EAR 工程。需要注意的是,,創(chuàng)建工程時需要選擇上面創(chuàng)建的 IBM WAS CE v2.1 作為 Target Runtime,,如圖 4 所示。以下的所有工程除了 ShopUtil 外都需要 IBM WAS CE v2.1 作為 Target Runtime,。
圖 4. 創(chuàng)建 ShopEAR 工程
此工程創(chuàng)建后會自動在 EarContent\META-INF\ 目錄下生成 WAS CE 的部署計劃:geronimo-application.xml,。雙擊此文件可以打開此部署計劃的編輯界面,通過此編輯界面可以很容易的操作此部署計劃,。
通過 Eclipse 中的 ”JPA Project” 向導創(chuàng)建 ShopJPA 工程,。創(chuàng)建過程中可以把此工程加入到上面創(chuàng)建的 ShopEAR 工程中。此工程創(chuàng)建后,,Eclipse 會轉換到 JPA 視圖,。此時我們需要使用數(shù)據(jù)庫了,因此我們需要先創(chuàng)建數(shù)據(jù)庫,。
WAS CE 中默認的內置數(shù)據(jù)庫為 Derby,,我們的 OlliShop 應用就是使用了此數(shù)據(jù)庫,。通過J2EE 視圖中的 Servers view,可以啟動 WAS CE,。通過 http://localhost:8080/console/
進入 WAS CE 的管理控制臺,,默認的用戶名/口令為 system/manager。通過此控制臺可以管理Derby 數(shù)據(jù)庫,,單擊左邊菜單欄中的 "DB Manager" 進入數(shù)據(jù)庫管理界面,,創(chuàng)建名為 "shop" 的數(shù)據(jù)庫,然后可以使用以下腳本創(chuàng)建所需要的表:
清單 1. 創(chuàng)建數(shù)據(jù)庫腳本
CREATE TABLE Users ( ID INTEGER NOT NULL, UserName VARCHAR(250) NOT NULL, Password VARCHAR(250) NOT NULL ); CREATE TABLE Goods ( ID INTEGER NOT NULL, Name VARCHAR(250) NOT NULL, Price DECIMAL(14, 2) NOT NULL, Quantity DOUBLE NOT NULL ); CREATE INDEX Users_ID ON Users(ID); CREATE INDEX Goods_ID ON Goods(ID); |
JPA 需要通過數(shù)據(jù)源才能訪問到相應的數(shù)據(jù)庫,,在 WAS CE 中有兩種方式創(chuàng)建數(shù)據(jù)源:通過管理控制臺創(chuàng)建和通過部署計劃創(chuàng)建,。在這里我們使用第二種方式,所以需要修改在 ShopEAR 中的部署計劃:geroniom-application.xml,。
在 geronimo-application.xml 中添加以下代碼:
清單2. geronimo-application.xml
<ext-module> <connector>ShopDataSource</connector> <external-path xmlns:dep="http://geronimo./xml/ns/deployment-1.2"> <dep:groupId>org.tranql</dep:groupId> <dep:artifactId>tranql-connector-derby-embed-local</dep:artifactId> <dep:type>rar</dep:type> </external-path> <connector xmlns="http://geronimo./xml/ns/j2ee/connector-1.2"> <resourceadapter> <outbound-resourceadapter> <connection-definition> <connectionfactory-interface> javax.sql.DataSource </connectionfactory-interface> <connectiondefinition-instance> <name>jdbc/ShopDataSource</name> <config-property-setting name="UserName"> </config-property-setting> <config-property-setting name="Password"> </config-property-setting> <config-property-setting name="DatabaseName"> shop </config-property-setting> <config-property-setting name="CreateDatabase"> true </config-property-setting> <connectionmanager> <single-pool> <max-size>100</max-size> <min-size>0</min-size> <blocking-timeout-milliseconds> 5000 </blocking-timeout-milliseconds> <idle-timeout-minutes>30</idle-timeout-minutes> <match-one/> </single-pool> </connectionmanager> </connectiondefinition-instance> </connection-definition> </outbound-resourceadapter> </resourceadapter>> </connector> </ext-module> |
從以上代碼可以看出此數(shù)據(jù)源指定的數(shù)據(jù)庫為 shop,,創(chuàng)建的數(shù)據(jù)源的 JNDI 的名字為jdbc/ShopDataSource。
Eclipse 提供了一個創(chuàng)建 JPA Entity Bean 的工具,,此工具能夠根據(jù)數(shù)據(jù)庫中表的設置創(chuàng)建出相應的 Entity Bean。為了使用此工具,,需要先在 Eclipse 中連接到 Derby 數(shù)據(jù)庫,,在 JPA 視圖的 Data Source Explorer 中創(chuàng)建到 Derby 的連接。步驟如下:
1. 在 "Database" 的右鍵菜單中選擇 "New …"
2. 選擇 “Generic JDBC Connection”
3. 輸入連接的名字:Derby
4. 選擇 “Derby Client JDBC Driver”,,Derby JDBC Driver位于:%WASCE_HOME%\repository\org\apache\derby\derbyclient\10.2.2.0\derbyclient-10.2.2.0.jar
,。輸入以下連接屬性:
Database:shop
URL:jdbc:derby://localhost:1527/shop;create=true
User Name:user
Password:app
5. 連接剛創(chuàng)建的 Derby。
現(xiàn)在可以通過 Derby 連接創(chuàng)建相應的 Entity Bean 了,。在 shop 數(shù)據(jù)庫中只有兩個表:users 和 goods,。我們先創(chuàng)建一個類 com.ibm.wasce.shop.entity.User,此時在 JPA 視圖中就可以把此類映射到數(shù)據(jù)庫中的表 users,,如圖5所示,。
圖 5. User 類映射到表 users
在 User類 中添加 3 個屬性:id、userName,、password,,然后把它們映射到 users 表中的字段,如圖 6 所示,。
圖6. 映射屬性 id 到表 users 中的字段 id
用戶登錄時,,需要從數(shù)據(jù)庫中根據(jù)用戶輸入的用戶名查詢該用戶來驗證用戶名和密碼。在傳統(tǒng)的應用中,,我們需要從數(shù)據(jù)源中得到 Connection,,然后執(zhí)行 SQL 語句,從返回的數(shù)據(jù)集中獲得數(shù)據(jù),,再生產相應的 User 對象,。在 EJB 3.0 中,,這項工作已經大大簡化,主要是因為使用了 Annotation NamedQueries 和 EJB QL,。通過 NamedQueries,,只需要再聲明一個 EJB QL,就可以得到相應的 User 對象,,開發(fā)人員不再需要關心數(shù)據(jù)庫連接和數(shù)據(jù)轉換等繁瑣的事情,。EJB QL 是和 SQL 很像的一種語言,只是它要操作的不是數(shù)據(jù)庫中的表,,而是 JPA Entity Bean,。
最終生成的 User 類如下:
清單3. 生成 JPA 實體 Bean
@NamedQueries ( { @NamedQuery ( name = "getUserByName", query = "select u from User u where u.userName= :name" ) }) @Entity @Table(name="USERS", schema = "APP") public class User { @Id @GeneratedValue private Integer id; private String userName; private String password; // 以下的setter/getter方法省略 |
通過以上的方式,我們創(chuàng)建了與表 goods 相對應的 JPA Entity Bean,。
接下來,,我們將通過 Eclipse 中的 “EJB Project” 向導創(chuàng)建 ShopEJB 工程,同時把新創(chuàng)建的工程加入到 ShopEAR 中,。
此工程中的 EJB 采用 EJB 3.0 的方式開發(fā),。在傳統(tǒng)的EJB編程模型中,每一個Bean需要兩個接口和一個類來組成:Remote(或Local)接口,、Home 接口和 Bean 實現(xiàn)類,,而且這三個類之間需要通過某種編碼約定來規(guī)范,在部署時再由 EJB 容器生產一些魔術代碼(Magic Codes)把它們之間的調用關系連起來,。而在 EJB 3.0 中的實現(xiàn)則顯得更加簡單和直接,,一個 EJB 只需要一個接口和一個類:Remote(或 Local)接口和實現(xiàn) Remote(或 Local)接口的類。另外一個區(qū)別是在 EJB 3.0 中部署描述符(ejb-jar.xml)也不再是必須的了,,我們可以通過 Annotation 的方式來定義這些元數(shù)據(jù),。
以下是 ShopBean 的 Local 接口,它是一個普通的 Java 接口,。如果是 Remote 接口,,則需要加上 Annotation @Remote。
清單 4. ShopBean 的 Local 接口
public interface ShopBean { public boolean login( String name, String password ); public List listGoods(); public Good getGoodById( int id ); } |
以下是 ShopBean 的實現(xiàn)類,。在此類中,,唯一能感覺到它和 EJB 相關的地方就是 @Stateless
,其它的地方和普通的 Java 類沒有區(qū)別,。此類主要用來實現(xiàn)操作在 ShopJPA 中開發(fā)的 Entity Bean,。EntityManager 是 JPA 中最重要的一個接口,應用程序主要通過它來添加,、修改和查詢 Entity Bean,。通過 Annotation @PersistenceContext
,WAS CE 中的 EJB 容器會把一個 EntityManager 的實例賦給此類中的em對象,,這就是在 EJB 3.0 中被廣泛使用的依賴注入(Dependency Injection)的方法,。在這個類中,,也用到了在 ShopJPA 中定義的 NamedQuery。
清單 5. ShopBean 的實現(xiàn)
@Stateless public class ShopBeanImpl implements ShopBean { @PersistenceContext private EntityManager em; public Good getGoodById(int id) { Query query = em.createNamedQuery( "getGoodByID" ); query.setParameter("id", id); return (Good)query.getSingleResult(); } public List listGoods() { Query query = em.createNamedQuery( "getAllGoods" ); return query.getResultList(); } public boolean login(String name, String password) { try { Query query = em.createNamedQuery( "getUserByName" ); query.setParameter( "name", name ); User user = (User)query.getSingleResult(); return user != null && user.getPassword().equals( password ); } catch ( Exception e ) { return false; } } |
通過 Eclipse 中的 "Java Project" 向導創(chuàng)建 ShopUtil 工程,??梢栽?ShopEAR 工程的屬性管理頁面中,把 ShopUtil 工程加入到 ShopEAR 中,。
此工程提供了 ShopWEB 和 ShopWS 訪問 EJB 的功能,,而不需要在兩個 Web 工程中分別定義。它使用 JNDI 的方式訪問 EJB,,如清單 6 所示:
清單 6. 使用 JNDI 訪問 EJB
private EJBLocator() { try { InitialContext rootContext = new InitialContext(); shopbean = (ShopBean)rootContext.lookup( "java:comp/env/ejb/shopbean" ); } catch ( NamingException ne ) { ne.printStackTrace(); } } |
接下來,,我們將創(chuàng)建兩個 Web 工程。在創(chuàng)建的兩個 Web 工程中需要進行以下設置才可以使用:
- 在 Web 工程的屬性中:"Java Build Path" -> "Projects" 中添加 ShopUtil 工程,。
- 添加以下一行到 Web 工程的文件:WebContent\META-INF\ MANIFEST.MF,;Class-Path: ShopUtil.jar
在創(chuàng)建此工程前,需要先根據(jù) WTP 的文檔來設置 Java Server Faces,,WAS CE v2.1 提供了JSF 所需要的以下兩個 Jar 文件:
- %WASCE_HOME%\repository\org\apache\myfaces\core\myfaces-api\1.2.0\myfaces-api-1.2.0.jar
- %WASCE_HOME%\repository\org\apache\myfaces\core\myfaces-impl\1.2.0\myfaces-impl-1.2.0.jar
設置完 JSF 后,,通過 Eclipse 中的 “Dynamic Web Project” 向導創(chuàng)建 ShopWEB 工程,Configurations-> JavaServer Faces v1.2 Project,,同時把新創(chuàng)建的工程加入到 ShopEAR 中,。
新生成的工程中會包含 JSF 的配置文件:faces-config.xml,雙擊此文件可打開 JSF 配置編輯器,,如圖 7 所示。
圖 7. faces-config.xml 的編輯器
通過此編輯器中的 ManageBean 頁面,,可以生成 JSF 中的 Managed Bean,。在本例中,有兩個Managed Bean:GoodsBean 和 LoginBean,。
WST 還提供了一個 JSF 頁面編輯器,,可以進行可視化的開發(fā)。在本例中,,有兩個頁面:一個登錄頁面和一個顯示商品列表的頁面,。其中登錄頁面的編輯如圖 8 所示。
圖 8. JSF 的可視化編輯頁面
本例中的業(yè)務邏輯是用戶正確登錄后會自動轉到商品列表頁面,,否則將返回到登錄頁面,。這種頁面跳轉的邏輯也可以通過可視化的方式來進行設置,如圖 9 所示,。
圖 9. 頁面跳轉邏輯編輯頁面
通過 Eclipse 中的 "EJB Project" 向導創(chuàng)建 ShopWS 工程,,同時把新創(chuàng)建的工程加入到ShopEAR 中。
通過 JAX-WS 的方式來開發(fā) Web Service 簡化了很多工作,。在本例中,,我們開發(fā)了一個通過商品編號來查詢商品價格的 Web Service,。此 Service 只需要使用一個接口和一個實現(xiàn)類,在部署時,,WAS CE 會根據(jù)接口和類中的 Annotation 來生成相應的 WSDL 文件,。
以下是此 Service 的接口,使用了 Annotation @WebService
,。
清單 7. ShopService 接口
@WebService(name="ShopServicePortType", targetNamespace = "http://shop.wasce.ibm.com") public interface ShopService { public double getPriceById( int goodsId ); } |
以下是此 Service 的實現(xiàn)類:
清單 8. ShopService 的實現(xiàn)
@WebService(serviceName = "ShopService", portName="ShopServicePort", endpointInterface = "com.ibm.wasce.shop.ws.ShopService", targetNamespace = "http://shop.wasce.ibm.com") public class ShopServiceImpl implements ShopService { public double getPriceById( int goodsId ) { ShopBean shopbean = EJBLocator.getInstance().getShopBean(); Good good = shopbean.getGoodById(goodsId); return 20; } } |
以上定義的 Web Service 需要通過 Servlet 的方式發(fā)布,,所以需要在 web.xml 中進行以下配置:
清單 9. 在 web.xml 中配置 ShopService
<servlet> <display-name>ShopService</display-name> <servlet-name>ShopService</servlet-name> <servlet-class> com.ibm.wasce.shop.ws.ShopServiceImpl </servlet-class> </servlet> <servlet-mapping> <servlet-name>ShopService</servlet-name> <url-pattern>/shopservice</url-pattern> </servlet-mapping> |
雖然類 com.ibm.wasce.shop.ws.ShopServiceImpl 不是一個 Servlet,它沒有繼承javax.servlet.http.HttpServlet,,但是在部署的時候,,WAS CE 的部署程序會對 ShopServiceImpl進行解析,并且生成一個 Servlet 來包裝 ShopServiceImpl,,這樣就可以通過地址 /shopservice來訪問到此 Web Service,。
也可以通過 JAX-WS 的方式來調用上面生成的 Web Service,代碼如下:
清單 10. 調用 ShopService
public static double getPriceById( int goodsId) throws Exception { URL url = new URL("http://localhost:8080/ShopWS/shopservice?wsdl"); QName qname = new QName("http://shop.wasce.ibm.com", "ShopService"); Service service = Service.create(url, qname); ShopService shopservice = (ShopService)service.getPort(ShopService.class); double price = shopservice.getPriceById( goodsId ); return price; } |
在 Eclipse 中開發(fā)完以上模塊后,,就可以部署此應用,。我們可以通過兩種方式來部署:通過Eclipse 部署或者從 Eclipse 中導出 EAR 后通過命令行部署。
第一種方式:通過 Eclipse 部署
- 在 Eclipse 中的 Server 視圖,,右擊 WASCE Server,,選擇Add and Remove Projects ...
- 添加 ShopEAR 到 Configured projects 列表中
- 點擊 Finish
第二種方式:通過命令行部署
- 右擊 ShopEAR 工程,選擇 Export
- 選擇“Java EE”-> EAR file
- 指定要保存的目錄和文件名,,例如 d:\temp\ShopEAR.ear
- 用以下命令部署導出的 ear 文件
%WASCE_HOME%\bin\deploy --username system --password manager deploy d:\temp\ShopEAR.ear
部署此應用后,,可以通過 http://localhost:8080/ShopWEB/
來訪問 OlliShop 的主頁,默認的用戶名/密碼為 user1/user1
對于 Web Service,,可以通過 http://localhost:8080/ShopWS/shopservice?wsdl
來訪問 shopservice的 WSDL 文件,,可以通過http://localhost:8080/ShopWS/invokeshopservice.jsp
來調用此 Web Service。
WAS CE v2.1 作為一款免費的 Java EE 5 應用服務器,,結合 Eclipse 強大的 WST 工具,,為廣大開發(fā)人員提供了快速的開發(fā)環(huán)境,也為中小型企業(yè)實踐 Java EE 5 的應用提供了一個很好的平臺,。
描述 | 名字 | 大小 | 下載方法 |
---|---|---|---|
代碼示例 | OlliShop.zip | 49 KB | HTTP |
學習
- WebSphere Application Server Community Edition V2.1 中的新增功能:本文主要講述了 WebSphere Application Server Community Edition V2.1 中的新增功能,,包括使用 Gshell 執(zhí)行 Geronimo 命令、在您自己的服務器集基礎上創(chuàng)建多個服務器組裝,,以及通過專家模式和新的 Monitoring Portlet 完全控制服務器的能力,。
- 從 Apache Tomcat Version 6.0 遷移到 WAS CE V2.1 :本文將逐步地指導您將一個應用程序部署到 Tomcat 6.0,然后遷移代碼并將其部署到 WebSphere Application Server Community Edition V2.1,。并通過該示例應用程序突出說明了這兩種實現(xiàn)之間的一些顯著差異,。
- 使用 WAS CE 開發(fā) JPA 應用程序:本教程將向您介紹如何用 JPA 開發(fā) WAS CE 目標平臺下的 Java EE 5 應用。本教程通過一個示例應用程序的開發(fā)過程,,將帶您了解如何創(chuàng)建 JPA 項目和持久生成類,,如何配置持久單元以及如何部署和運行 Web 應用程序,。
- WAS CE 產品文檔:本網站向您提供了 WAS CE 不同版本的產品幫助文檔。
- Eclipse 網站:本網站向您提供了 開源開發(fā)工具 Eclipse 最新,。
- Geronimo 專題:為您提供了 Apache Geronimo 相關的技術文章,、教程、下載等資源,。
- WAS CE 專欄:為您提供了開源應用服務器 WAS CE 相關的技術文章,、教程、下載等資源,。
獲得產品和技術