使您的应用程序调用我的应用程序,第1部分(下)

Apache Geronimo 通信基础 —— 开发、部署和测试(下)

消息驱动 bean()

既然您已经实现了 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 目录下找到。

清单 9. 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 instance of ObjectMessage) {        Serializable bean = ((ObjectMessage) msg).getObject();        poBean = (PurchaseOrderBean) bean;        addPurchaseOrder(poBean);        }     }// end onMessage

在 PurchaseOrderMDB 的 onMessage() 方法中,您调用了 PurchaseOrderEJB 的 addPurchaseOrder() 方法在数据库表中创建新采购 订单行。

Geronimo 服务器的 JNDI 属性如下:

java.naming.facTory.initial=org.openejb.client.RemoteInitialContextFacToryjava.naming.provider.url=localhost:4201(4201 是默认端口)

java.naming.security.principal=system(默认用户名)

java.naming.security.credentials=manager(默认口令)

清单 10. 查找实体 bean 并创建采购订单

private void addPurchaseOrder (PurchaseOrderBean poBean) {try {//EJB JNDI Properties for Geronimo ServerHashtable 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");// create a new InitialContextInitialContext ctx = new InitialContext(env);// Lookup Purchase Order Entity BeanObject o = ctx.lookup("PurchaseOrderEJB");RemotePurchaseOrderHome home =(RemotePurchaseOrderHome) PortableRemoteObject    .narrow(o, RemotePurchaseOrderHome.class);// Create a new Purchase OrderRemotePurchaseOrder 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)。

清单 11. 定义 MDB 的 ejb-jar.xml 代码片段

PurchaseOrderMDBexamples.po.mdb.PurchaseOrderMDBContainerjavax.jms.Topic   

在 openejb-jar.xml 中,您定义了 MDB 应侦听的主题/队列 JNDI 名(POTopic)(参见 清单 12)。您还要定义 MDB 在 ejb-ref 部 分中调用的 EJB。

清单 12. 定义 MDB 的 openejb-jar.xml 代码片段

PurchaseOrderMDBgeronimo.server:J2EEApplication=null,J2EEServer=geronimo,JCAResource=geronimo/activemq/1.0/car,j2eeType=JCAResourceAdapter,name=ActiveMQ RA         destination            POTopic            destinationType            javax.jms.Topic    ejb/PurchaseOrderEJBPurchaseOrderEJB

PurchaseOrderMDB 在 addPurchaseOrder() 方法中调用 PurchaseOrderEJB,因此 EJB 是在 部分中定义的。

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。

在 http://localhost:8080/console 处可使用 Geronimo 管理控制台,在左窗格中的 Misc > Embedded DB 菜单下单击 DB Manager。

创建 ExampleDatabase,如 图 3 所示。

图 3. 在 Geronimo 服务器中创建数据库

成功创建了 ExampleDatabase 之后,您将会看到它出现在数据库列表中,如 图 4 所示。

图 4. 数据库创建成功

现在创建表 PURCHASEORDER,方法是在 SQL Command 文本区域中输入 SQL 脚本(参见 清单 13)。务必确保首先在 Use DB 下拉列表 中选中 ExampleDatabase,然后再单击 Run SQL 按钮(参见 图 5)。

清单 13. 创建表的 SQL 脚本

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)

图 5. 在 Geronimo 服务器中创建数据库

成功创建了 PURCHASEORDER 表之后,您将看到它出现在 DB Viewer 中,如 图 6 所示。

图 6. 表创建成功

数据库池配置

现在您可以使用 http://localhost:8080/console 处的 Geronimo 管理控制台在 Geronimo 中创建数据库池 PurchaseOrderDataSource。

在左窗格中选择 Database Pools,然后选择 Using the Geronimo database pool wizard,如 图 7 所示。完成后续步骤,如 图 8 和 图 9 所示。

图 7. 创建数据库池

键入 PurchaseOrderDataSource 作为数据库池名、Derby Embedded 作为类型,如 图 8 所示。

图 8. 选择数据库类型

从 Driver JAR 下拉列表中选择 org.apache.derby/derby/10.1.1.0/jar。您可将用户名和口令字段留空。选择 ExampleDatabase 作 为数据库名(参见 图 9)。

图 9. 选择数据库驱动和数据库名

只要将未填充的字段留空,即可使用默认值,单击 Test Connection 按钮来测试连接(参见 图 10)。

图 10. 测试数据库连接池

现在,您应看到测试结果,表示您已连接到 Derby,如 图 11 所示。

图 11. 成功测试连接

选择 Deploy 按钮后,您应看到数据库池已成功创建(参见 图 12)。

图 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。

控制台部署

使用 http://localhost:8080/console 处的 Geronimo 管理控制台部署 po-ejb.jar 文件,如 图 13 所示。

图 13. 部署新应用程序

成功部署应用程序后,您将接收到如 图 14 所示的消息。

图 14. 部署成功

测试

最后,您可创建一个客户机或测试程序来测试您的应用程序。

创建客户机

您的客户机程序(参见 清单 14)将向 POTopic 发布一条带有采购请求信息的 JMS 消息。由于 PurchaseOrderMDB 侦听 POTopic,服 务器将调用 onMessage() 方法,此方法又会调用 PurchaseOrderEJB 在数据库中创建采购订单。

客户机 PurchaseOrderPublisher.java 位于 $part1.home/src/examples/po/test 目录中。

清单 14. 发布 JMS 消息的客户机程序

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 {       // JMS JNDI Properties for Apache Geronimo Server       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");       // create a new initial context with jndi properties        javax.naming.Context ctx =          new javax.naming.InitialContext(env);       // lookup the connection facTory        javax.jms.TopicConnectionFacTory facTory =          (javax.jms.TopicConnectionFacTory) ctx            .lookup("POConnectionFacTory");       // create a new TopicConnection       conn = facTory.createTopicConnection();       javax.jms.Topic mytopic =(javax.jms.Topic) ctx.lookup("POTopic");       // create a new TopicSession       session = conn.createTopicSession(false,          javax.jms.Session.AUTO_ACKNOWLEDGE);       //create a Topic Publisher to publish messages to 'POTopic'       publisher = session.createPublisher(mytopic);       // start the topic connection       conn.start();       // create a new purchase order with test data       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");       // create a jms message       javax.jms.ObjectMessage poMsg =session.createObjectMessage(poBean);       // publish the jms message to 'POTopic'       publisher.publish(poMsg);       } catch (Exception e) {          log.severe("Error Occurred: " + e);       } finally {          // release all jms resources           if (publisher != null)             publisher.close();          if (session != null)             session.close();          if (conn != null)              conn.close();       }    }// end main}// end class

运行测试

下载的 part1.zip 文件中提供了一个脚本文件(参见 下载 部分),修改 $part1.home/runtester.cmd 中的 JAVA_HOME、J2EE_JAR 和 GERONIMO_HOME(参见 图 15)。

图 15. 测试应用程序

现在您应看到 Geronimo 控制台中显示出一些日志记录,如 图 16 所示。

图 16. Geronimo 服务器日志

如果 PURCHASEORDER 数据库中添加了一条新记录,则本测试将被视为成功。

结果

现在检查数据库,看看 PURCHASEORDER 表中是否有记录项,如 图 17 所示。

图 17. 检查数据库表中是否有新记录项

太棒了!您已经完成了本系列教程第 1 部分的学习。

在第 2 部分中,您将开发一个电子邮件应用程序,此应用程序将在 Apache James 中部署。

结束语

您已成功完成了这个共分三部分的系列教程的第 1 部分。您创建了一个 MDB 和一个带有 CMP 的实体 bean。这些 bean 协同工作,向 系统中添加采购订单。

请继续关注第 2 部分,您将使用 Apache James 邮件应用程序平台来构建一个电子邮件应用程序;另外还有第 3 部分,在第 3 部分 中您要将这篇教程中创建的两个 bean 以及第 2 部分中创建的电子邮件应用程序联系在一起,完成整个应用程序。

本文配套源码

一个人的期望值越大,心理承受力就会越小,就越经受不住失败的打击,

使您的应用程序调用我的应用程序,第1部分(下)

相关文章:

你感兴趣的文章:

标签云: