例子程序介绍
我们的email应用程序将使用ptp域模型。当一个eamil被放入队列中时我们只希望一个接收者能够收到,另外email可以被多次发送。
jms 消息被放入队列的条目是jms消息。这是一个普通的消息,他拥有消息头和消息体。jms消息有如下几个类型:
类型描述
textmessage文本消息. 你可以通过msg.settext("foo")和msg.gettext方法来操作textmessageobjectmessage
这种消息存储序列化对象。你可以通过msg.setobject(object o)和msg.getobject()来操作objectmessage.mapmessage
这种消息保存键/值对信息。你可以通过msg.setstring(key,value)和msg.getstring(key)来操作mapmessage.他还有其他几种getter和setter方法对应基本java类型(比如,getboolean,getint,getobject,等等)bytesmessage这种消息是一个字节流。他可被用于封装现有的消息格式。streammessage这种消息允许你发送java的原语流。在我们的例子中将使用一个mapmessage,因为他提供了一种方法可以让我们把email的标题信息和内容信息放到消息中。ejb 2.0消息驱动bean我们已经讲述了jms的基本概念,现在我们来谈一谈ejb2.0规范中的新概念。
回顾一下前面讲的jms部分。我们有一个发送者,他把消息放到队列中,然后一个接收者将读取这个消息并使用接收到的信息来发送email。这个接收者可以是一个运行的程序,他接收“email队列”中的消息。为了实现这个动作我们需要一个接收者,这个接收者的结构允许一个消息流的并行处理,同时它还要处理事务,这将使我们能够处理商业逻辑。这就是消息bean的由来。也就是说一个消息bean是一个简单的jms消费者。一个客户端不能直接访问消息beans(像你访问状态bean那样)你只能通过发送jms消息到消息bean所侦听的目的地。为了达到重用的目的,像其他的ejb一样,许多的支持信息都在ejb部署描述符中。这意味着我们不必关心我们从那里获得消息(不管是一个queue或者是topic),我们只需要写一个onmessage(message msg)方法来处理消息就可以了。我们已经讲述了jms和mdb的知识;现在让我们开始我们的例子吧.email 应用程序的开发步骤:我们将通过下面几步来完成email应用程序:在jms服务器上安装一个“email queue”消息队列。创建一个email客户端,他负责向emial 队列发送java 消息。创建一个消息驱动bean,他将处理这些消息,然后用这些信息用email发送。为消息驱动bean写部署描述符。打包代码。
将被创建的代码是:
代码
描述
com.customware.client.emailclientemail客户端,他将把消息发送到队列中com.customware.ejb.emailmdb消息驱动bean将消耗来自客户端的jms消息,并且使用emailhelper来发送邮件。com.customware.util.emailhelper一个助手类,他有一个静态方法sendmail(map mail,这个方法将使用javamail发送邮件。
第一步:安装一个邮件消息队列
这一步将依赖于你的消息服务器(比如ibm mqseries,sonicmq,等等)。我们需要安装一个jms 队列。我给他取名为emailqueue,客户端和消息驱动bean部署描述符要用到它。
第二步:创建一个email客户端 (emailclient.java)现在我们需要创建一个客户端(jms sender)。这个客户端截获搜有关email的信息,然后把它发送出去。main()方法从命令行获得参数,创建一个hashtable(用于存储map),调用sendmail(map m)方法。sendmail方法获得信息,根据获得的信息中创建一个mapmessage,再通过sender.send(message)把消息发送到emailqueue队列中。主要的工作在构造函数之中,这些是jms工作的全部内容。
下面是构造函数的内容:
1.通过getinitialcontext()助手方法连接到jndi服务。
2.为队列查找一个连接工厂[(queueconnectionfactory) ctx.lookup(connection_factory)]
3.为我们的jms服务器创建一个队列连接[confactory.createqueueconnection()]
4.创建一个jms会话(session),这个会话用于生产和消费信息。[connection.createqueuesession(false, session.auto_acknowledge)]5.查找队列,他将发送消息[(queue) ctx.lookup(queue_name)]6.最后创建一个发送者,这个发送者将使用会话(我们前面创建的)发送消息到我们查找到的队列中。
第三步:创建一个消息bean (emailmdb.java)在写会话 bean或实体bean时,你必须创建远程接口、主接口和bean类(实体bean还有一个可选的主键类)。而消息bean只需要bean类,因为有一个“客户端”他将作为bean的接口。一个消息驱动bean必须扩展两个接口:
接口描述
messagelistener
javax.jms.messagelistener这是jms接口,他提供了一个onmessage(message msg)方法。当一个消息放入队列中时,消息驱动bean的onmessage方法将被调用,容器将传输实际的消息来被消费。messagedrivenbean
javax.ejb.messagedrivenbean这是ejb接口,他包含ejb生命周期的方法:ejbcreate(): 当ejb创建时容器会调用这个方法ejbremove(): 当容器销毁ejb时调用setmessagedrivencontext(messagedrivencontext ctx): 当对象被装载后ejbcreate()调用之前上下文环境被传输到ejb中. 上下文包含信息,容器保存这些信息并允许你查许、处理(getusertransaction(), setrollbackonly(), getrollbackonly())
security (getcallerprincipal(), iscallerinrole())
如果你看一下emailmdb.java代码你会发现开头的几个方法实现了messagedrivenbean接口。我们在这些方法中作的所有事情就是打印他们被调用的信息。setmessagedrivencontext()把上下文环境保存到实例变量中,以便我们今后能够找的到他。你要作的差不多就是这些了。最后要作的就是扩展messagelistener接口的onmessage(message msg)方法。这就是我们消费消息并处理他们的过程。开始,我们通过抛出的消息创建一个mapmessage。然后我们从map消息中查找“键/”值对,把他们的值装入标准的hashtable。注意,这些方法我们是通过mapmessage调用的:// 从map message获得键
enumeration mapnames = mapmessage.getmapnames();
// 从mapmessage中获得值
string val = mapmessage.getstring(key);
最后,调用 emailhelper.sendmail(map)方法,把消息当作邮件发送出去。是不是很简单。这就是是消息驱动bean重要的部分,我们没有写那些晦涩的jms代码。实际上消息驱动bean是如何知道从那里获得这些消息?这些我们是通过部署描述符来实现的。
闽公网安备 35060202000074号