例子程序介绍
我们的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是如何知道从那里获得这些消息?这些我们是通过部署描述符来实现的。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器