首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

讓您的應用程式呼叫我的應用程式,第 1 部分 (下)

     編輯:Java 相關知識

Apache Geronimo 通訊基礎 — 開發、部署和測試 (下)

訊息驅動 Bean (MDB)

既然您已經實作了 PurchaseOrderEJB,接下來就可以實作 PurchaseOrderMDB 了。與 EJB 不同,MDB 是 JMS 偵聽器,偵聽 JMS 主題或佇列上的 JMS 訊息。根據 EJB 2.1 規格,MDB 不僅限於 JMS 偵聽器,而是可實作任意自訂偵聽器介面。在本系列的第 3 部分中,您將再次回顧這一點,並修改 PurchaseOrderMDB,以便使用自訂偵聽器介面,將其與 JCA 資源適配器相整合。

在本教學中,您將實作 PurchaseOrderMDB,它偵聽 JMS 主題 (POTopic) 接收到的帶有採購請求的 JMS 訊息。接收到採購請求訊息時,它將呼叫 PurchaseOrderEJB 來建立新採購訂單。

實作 PurchaseOrderMDB

不同於實體 Bean,MDB 不必實作遠端介面或主介面,而是要實作 MessageDrivenBean 和 MessageListener 介面——因而必須實作 onMessage() 方法。程式碼片段 9 給出了 PurchaseOrderMDB 的程式碼片段。

PurchaseOrderMDB 的原始檔 (.java) 可在 $part1.home/src/examples/po/mdb 目錄下找到。

public class PurchaseOrderMDB implements MessageDrivenBean, MessageListener {
 private MessageDrivenContext ctx = null;
 public void setMessageDrivenContext(MessageDrivenContext mdCtx) throws EJBException {
 ctx = mdCtx;
 }
 public void onMessage(Message msg) {
 if (msg instanceof ObjectMessage) {
 Serializable bean = ((ObjectMessage) msg).getObject();
 poBean = (PurchaseOrderBean) bean;
 addPurchaseOrder(poBean);
 }
 }
}

在 PurchaseOrderMDB 的 onMessage() 方法中,您呼叫了 PurchaseOrderEJB 的 addPurchaseOrder() 方法在資料庫表中建立新採購訂單行。

Geronimo 伺服器的 JNDI 屬性如下:

java.naming.factory.initial=org.openejb.client.RemoteInitialContextFactory
java.naming.provider.url=localhost:4201 (4201 是預設連接埠)
java.naming.security.principal=system (預設使用者名稱)
java.naming.security.credentials=manager (預設密碼)

程式碼片段 10. 查找實體 Bean 並建立採購訂單

private void addPurchaseOrder(PurchaseOrderBean poBean) {
 try {
 // Geronimo 伺服器的 EJB JNDI 屬性
 Hashtable env = new Hashtable();
 env.put("java.naming.factory.initial", "org.openejb.client.RemoteInitialContextFactory");
 env.put("java.naming.provider.url", "localhost:4201");
 env.put("java.naming.security.principal", "system");
 env.put("java.naming.security.credentials", "manager");
 // 建立新的 InitialContext
 InitialContext ctx = new InitialContext(env);
 // 查找 Purchase Order 實體 Bean
 Object o = ctx.lookup("PurchaseOrderEJB");
 RemotePurchaseOrderHome home = (RemotePurchaseOrderHome) PortableRemoteObject.narrow(o, RemotePurchaseOrderHome.class);
 // 建立新的採購訂單
 RemotePurchaseOrder po = home.create(poBean.getPurchaseOrderNum(), poBean.getItem(), poBean.getDescription(), poBean.getUnitPrice(), poBean.getQuantity(), poBean.getRequestorEmail());
 log.info("Purchase Order Number # :" + po.getPurchaseOrderNum());
 } catch (Exception e) {
 e.printStackTrace();
 log.severe("" + e);
 }
}

如程式碼片段 10 所示,為了在資料表中建立一個採購訂單行,您在 JNDI 伺服器中查找 PurchaseOrderEJB,並呼叫主介面上的 create() 方法。

定義 MDB 描述符

既然已經實作了 PurchaseOrderMDB,就該在描述符中定義 MDB 了。您不必為 MDB 定義單獨的描述符。它們是在與 EJB 相同的描述符中定義的,也就是 ejb-jar.xml (程式碼片段 11) 和 openejb-jar.xml (程式碼片段 12)。

<message-driven>
 <ejb-name>PurchaseOrderMDB</ejb-name>
 <ejb-class>examples.po.mdb.PurchaseOrderMDB</ejb-class>
 <transaction-type>Container</transaction-type>
 <message-destination-type>javax.jms.Topic</message-destination-type>
</message-driven>

在 openejb-jar.xml 中,您定義了 MDB 應偵聽的主題/佇列 JNDI 名 (POTopic) (程式碼片段 12)。您還要定義 MDB 在 ejb-ref 部分中呼叫的 EJB。

<message-driven>
 <ejb-name>PurchaseOrderMDB</ejb-name>
 <resource-adapter>
 <target-name>
 geronimo.server:J2EEApplication=null,J2EEServer=geronimo,
 JCAResource=geronimo/activemq/1.0/car,j2eeType=JCAResourceAdapter,
 name=ActiveMQ RA
 </target-name>
 </resource-adapter>
 <activation-config>
 <activation-config-property>
 <activation-config-property-name>destination</activation-config-property-name>
 <activation-config-property-value>POTopic</activation-config-property-value>
 </activation-config-property>
 <activation-config-property>
 <activation-config-property-name>destinationType</activation-config-property-name>
 <activation-config-property-value>javax.jms.Topic</activation-config-property-value>
 </activation-config-property>
 </activation-config>
 <!-- 這是對 Geronimo 伺服器中部署的 PurchaseOrderEJB CMP 的引用 -->
 <ejb-ref>
 <ref-name>ejb/PurchaseOrderEJB</ref-name>
 <ejb-link>PurchaseOrderEJB</ejb-link>
 </ejb-ref>
</message-driven>

PurchaseOrderMDB 在 addPurchaseOrder() 方法中呼叫 PurchaseOrderEJB,因此 EJB 是在 <ejb-ref> 部分中定義的。

Geronimo 伺服器配置

既然已經實作了 PurchaseOrderMDB 和 PurchaseOrderEJB,現在就可以配置 Geronimo 伺服器以便部署。首先使用 Geronimo 伺服器中的 Derby 為 PurchaseOrderEJB 配置資料庫表 PURCHASEORDER。

Geronimo 中不需要任何 JMS 配置,因為 JMS 主題/佇列是在部署期間由伺服器動態建立的。Geronimo 為 JMS 主題或佇列使用 openejb-jar.xml 描述符中的 JNDI 名。

資料庫配置

執行 $GERONIMO_HOME/bin/startup.bat 啟動您的 Geronimo 伺服器。如果您未在系統屬性中設定 JAVA_HOME,可在 $GERONIMO_HOME/bin/setjavaenv.bat 中進行設定。為 Geronimo 使用預設使用者名稱 system 和密碼 manager。

在 https://localhost:8080/console 可使用 Geronimo 管理主控台,在左窗格中的 Misc > Embedded DB 選單下點選 DB Manager。

建立 ExampleDatabase,如圖 3 所示。

在 Geronimo 伺服器中建立資料庫

成功建立 ExampleDatabase 後,您將會看到它出現在資料庫列表中,如圖 4 所示。

資料庫建立成功

現在建立表 PURCHASEORDER,方法是在 SQL Command 文字區域中輸入 SQL 腳本 (程式碼片段 13)。務必確保首先在 Use DB 下拉清單中選中 ExampleDatabase,然後再點選 Run SQL 按鈕 (圖 5)。

CREATE TABLE PURCHASEORDER (
 PURCHASEORDERNUM VARCHAR(30) PRIMARY KEY,
 ITEM VARCHAR(30) NOT NULL,
 DESCRIPTION VARCHAR(255),
 UNITPRICE INTEGER,
 QUANTITY INTEGER,
 REQUESTOREMAIL VARCHAR(30) NOT NULL
)

在 Geronimo 伺服器中建立資料表

成功建立 PURCHASEORDER 表後,您將看到它出現在 DB Viewer 中,如圖 6 所示。

資料表建立成功

資料庫池配置

現在您可以使用 https://localhost:8080/console 的 Geronimo 管理主控台在 Geronimo 中建立資料庫池 PurchaseOrderDataSource。

在左窗格中選擇 Database Pools,然後選擇 Using the Geronimo database pool wizard,如圖 7 所示。完成後續步驟,如圖 8 和 9 所示。

建立資料庫池

輸入 PurchaseOrderDataSource 作為資料庫池名、Derby Embedded 作為類型,如圖 8 所示。

選擇資料庫類型

從 Driver JAR 下拉清單中選擇 org.apache.derby/derby/10.1.1.0/jar。您可將使用者名稱和密碼欄位留空。選擇 ExampleDatabase 作為資料庫名 (圖 9)。

選擇資料庫驅動和資料庫名

只要將未填寫的欄位留空,即可使用預設值,點選 Test Connection 按鈕來測試連接 (圖 10)。

測試資料庫連接池

現在,您應看到測試結果,表示您已連接到 Derby,如圖 11 所示。

成功測試連接

選擇 Deploy 按鈕後,您應看到資料庫池已成功建立 (圖 12)。

資料庫池建立成功

部署

既然已完成資料庫配置,那麼也就準備好在 Geronimo 中部署包含 EJB 和 MDB 的應用程式了 (po-ejb.jar)。po-ejb.jar 檔案位於 $part1.home/deploy 目錄下。

您可以使用命令列,也可以使用基於主控台的部署,分別介紹如下。

命令列部署

下載檔案 part1.zip 的 $part1.home 目錄中有用於部署 (deploy.cmd) 和取消部署 (undeploy.cmd) 的腳本。務必在使用前修改命令檔案中的 JAVA_HOME 和 GERONIMO_HOME。

主控台部署

使用 https://localhost:8080/console 的 Geronimo 管理主控台部署 po-ejb.jar 檔案,如圖 13 所示。

部署新應用程式

成功部署應用程式後,您將接收到如圖 14 所示的訊息。

部署成功

測試

最後,您可建立一個客戶端或測試程式來測試您的應用程式。

建立客戶端

您的客戶端程式 (程式碼片段 14) 將向 POTopic 發布一條帶有採購請求資訊的 JMS 訊息。由於 PurchaseOrderMDB 偵聽 POTopic,伺服器將呼叫 onMessage() 方法,此方法又會呼叫 PurchaseOrderEJB 在資料庫中建立採購訂單。

客戶端 PurchaseOrderPublisher.java 位於 $part1.home/src/examples/po/test 目錄中。

public class PurchaseOrderPublisher {
 public static void main(String a[]) throws Exception {
 Logger log = Logger.getLogger("PurchaseOrderPublisher");
 javax.jms.TopicConnection conn = null;
 javax.jms.TopicPublisher publisher = null;
 javax.jms.TopicSession session = null;
 try {
 // Apache Geronimo 伺服器的 JMS JNDI 屬性
 java.util.Hashtable env = new java.util.Hashtable();
 env.put("java.naming.factory.initial", "org.activemq.jndi.ActiveMQInitialContextFactory");
 env.put("java.naming.provider.url", "tcp://localhost:61616");
 env.put("topic.POTopic", "POTopic");
 env.put("connectionFactoryNames", "POConnectionFactory");
 // 使用 jndi 屬性建立新的 initial context
 javax.naming.Context ctx = new javax.naming.InitialContext(env);
 // 查找連接工廠
 javax.jms.TopicConnectionFactory factory = (javax.jms.TopicConnectionFactory) ctx.lookup("POConnectionFactory");
 // 建立新的 TopicConnection
 conn = factory.createTopicConnection();
 javax.jms.Topic mytopic = (javax.jms.Topic) ctx.lookup("POTopic");
 // 建立新的 TopicSession
 session = conn.createTopicSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
 // 建立 Topic Publisher 發布訊息到 'POTopic'
 publisher = session.createPublisher(mytopic);
 // 啟動主題連接
 conn.start();
 // 建立帶有測試資料的新採購訂單
 PurchaseOrderBean poBean = new PurchaseOrderBean();
 Random random = new Random();
 String poNum = "PO" + random.nextInt();
 poBean.setPurchaseOrderNum(poNum);
 poBean.setItem("Pens");
 poBean.setDescription("Need pens for Marketing dept.");
 poBean.setUnitPrice(new Integer(2));
 poBean.setQuantity(new Integer(100));
 poBean.setRequestorEmail("user1@localhost.com");
 // 建立 JMS 訊息
 javax.jms.ObjectMessage poMsg = session.createObjectMessage(poBean);
 // 發布 JMS 訊息到 'POTopic'
 publisher.publish(poMsg);
 } catch (Exception e) {
 log.severe("Error Occurred: " + e);
 } finally {
 // 釋放所有 JMS 資源
 if (publisher != null) publisher.close();
 if (session != null) session.close();
 if (conn != null) conn.close();
 }
 }
}

執行測試

下載的 part1.zip 檔案中提供了一個腳本檔案 (請參閱下載部分),修改 $part1.home/runtester.cmd 中的 JAVA_HOME、J2EE_JAR 和 GERONIMO_HOME (圖 15)。

測試應用程式

現在您應看到 Geronimo 主控台中顯示出一些日誌記錄,如圖 16 所示。

Geronimo 伺服器日誌

如果 PURCHASEORDER 資料庫中新增了一條新記錄,則本測試將被視為成功。

結果

現在檢查資料庫,看看 PURCHASEORDER 表中是否有記錄項,如圖 17 所示。

檢查資料庫表中是否有新記錄項

太棒了!您已經完成了本系列教學第 1 部分的學習。

在第 2 部分中,您將開發一個電子郵件應用程式,此應用程式將在 Apache James 中部署。

結語

您已成功完成了這個共分三部分的系列教學的第 1 部分。您建立了一個 MDB 和一個帶有 CMP 的實體 Bean。這些 Bean 協同工作,向系統中新增採購訂單。

請繼續關注第 2 部分,您將使用 Apache James 郵件應用程式平台來建構一個電子郵件應用程式;另外還有第 3 部分,在第 3 部分中您要將這篇教學中建立的兩個 Bean 以及第 2 部分中建立的電子郵件應用程式串聯在一起,完成整個應用程式。

本文配套原始碼

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved