基于J2EE的电子商务开发模型及其实现.docx
《基于J2EE的电子商务开发模型及其实现.docx》由会员分享,可在线阅读,更多相关《基于J2EE的电子商务开发模型及其实现.docx(16页珍藏版)》请在冰点文库上搜索。
基于J2EE的电子商务开发模型及其实现
基于J2EE的电子商务开发模型及其实现
学习如何使用Publish和SubscribeMDB、IBMRationalApplicationDeveloper、IBMWebSphereEnterpriseServiceBus、ApplicationServerUnitTestEngine,以及IBMWebSphereNetworkDeployment进行设计和开发随需应变的J2EE应用程序。
这篇详细的指南包括了如何创建MDB并向其他MDB发布信息,并详细说明了如何从IDE直接将应用程序部署到应用程序服务器网络基础结构中。
介绍
在这样一个不断成长的Java™世界中,期望与挑战日复一日的不断增加。
每个人都希望站在不断变化的前沿,但是技术文章常常不能为我们提供开发者所需的细节内容。
因此,本指南为您详尽展示了如何开发、部署与运行随需应变的Java2™PlatformEnterpriseEdition™(J2EE™)应用程序。
在这个过程中,您还会学到如何完成以下相关任务:
∙使用发布订阅(PubSub)消息
∙创建消息驱动Bean(MDB)向其他MDB发布信息
∙使用IBMWebSphere®EnterpriseServiceBus
∙在IDE中开发Java™MessageService(JMS)代码
∙把来自您的IDE中的IBMWebSphereApplicationServer升级到WebSphereApplicationServernetwork
∙直接从IDE中将应用程序部署到WebSphereApplicationServernetwork
∙仅用IDE(而不需要消息软件的许可证)开发、部署与测试JMS应用
场景和设计概述
我们已设计了一种基于实际生活的场景,这个场景易于理解并且易于关联到技术。
它使用随需应变的方式在不同应用程序服务器之间交换信息。
虽然有很多方法来编写软件,但是为了交换信息的目的,我们选择了发送消息的方式来加以实现,因为它本身就拥有同步与异步的优势。
在这个实践场景中,分布在不同区域的一家公司需要完成用户实际货物订单的要求。
如果某个地点不能完成一个订单,则需要其他地方代替它完成。
由于安全原因,不同地点的员工不能查看其他地点的数据库。
每一地点的应用程序运行于本地的应用服务器,且仅对本地职员开放。
本场景只包括三个地点,但是您可以把这种设计应用于任何多的地点中。
这种设计的美妙之处在于所有地点都可以通过不同项目名称使用相同代码库。
设计细节
在下面的例子中,公司的三个地点通过WebSphereApplicationServerNetworkDeploymentnetwork的通用总线架构共享数据。
图1使用不同颜色标记沿着信息路由的三个目的地,箭头表示信息流的方向。
例如,来自Region1的TransferProcessbean发送数据至DESTINATION1,它在所有地点发送对于CheckInventoryMDB的请求信息。
图1描述的设计有如下假设:
∙每一地点拥有同一代码库的不同实例。
∙每一地点拥有自己的数据库。
∙每一地点拥有唯一的RegionID,因此如果存货清单满足请求消息来自于相同的地点,则MDB不会处理此信息。
图1.消息流图
如果Region1想将一个订单传送给另一地点来执行,它需要发送JavaMessageService消息至通用总线目的地,此目的地基于WebSphereEnterpriseServiceBus技术,并运行于应用服务网络。
所有监测通用总线目的地的MDB会采用PubSub技术报警或进行触发。
在响应链中每个被触发的MDB会触发下一个MDB。
消息使用标准语言,如XML(您可以使用任何形式的语言作为标准,它取决于您的需要)。
我们为每个功能分别创建了一个topic,一个destination,以及相应的MDB:
∙一个被称为TransferProcessBean的会话bean,发送消息至DESTINATION1
∙以下为所触发的3种PubSubMDB:
1.CheckInventoryMDB监测或监听DESTINATION1并发送消息至DESTINATION2
2.CompleteRRTransferMDB(RR表示RequestingRegion)监听DESTINATION2并发送消息至DESTINATION3
3.CompleteARTransferMDB(AR表示AcceptingRegion)监听DESTINATION3
在本例中,TransferProcessBean消息使用如下格式(您的消息格式与内容可以不同,这取决于您的业务):
表1.消息格式举例
01
ALL
TRANSFER-REQUEST
….addmoretagsasperyourbusinessneeds
当然,您可以根据您的业务需求增加更多不同的标签。
一旦CheckInventoryMDB消息被发送,那么每个监听DESTINATION1的地点都会被触发响应。
如果一个地点已有足够多的存货来满足用户订单,它会自动保留必需的条目,并发送一个其有足够存货满足此订单的响应。
这些响应被发送至DESTINATION2,并且标签告知每一个地点的接受者,此消息是否为它们的地点所想要的。
消息看起来基本上类似如下:
表2.消息格式举例
02
01
TRANSFER-RESPONSE
Fillinyourinfo/datawhetheryoucanacceptornot
一旦前一个消息在DESTINATION2中被发送,那么CompleteRRTransferMDB指令就会在每个地点中被触发。
只有处于请求地点的MDB处理这个消息,因为它是基于Region标签值的。
如果有多个地点可以满足此订单,那么请求地点的MDB只选择一个,并且相应地发送一个消息至DESTINATION3。
紧接着,监听DESTINATION3的CompleteARTransferMDB被触发。
它在存货存在的新地点中,根据其订单创建逻辑完成订单的创建。
现在,订单传输完成了。
此设计的重要优势
在此设计中存在一些很关键的考虑事项:
∙单一应用程序可以通过在不同地点的最小改变进行开发与部署。
∙当您增加了一个新地点,它就成为应用服务网络中的一部分,并且可以与其他地点以零代价交换消息。
∙无论其他地点发生什么,每个地点都会独立工作。
∙每个地点不需要知道网络中存在多少个其他地点。
∙每个地点不需要知道是否其他地点正在运行。
∙如果一个地点部署了IBMWebSphere®MQ,即使它不在线,消息也会在它再次上线时传递给它。
实践训练
现在您已经理解了基本设计,您可以开始关注如何在IDE和应用服务器上使用它了。
为了证明的需要,本例子使用IBMRationalApplicationDeveloper®作为IDE,IBMWebSphere®ApplicationServerVersion6.1UnitTestEnvironment作为应用程序服务器。
在您成功测试之后,您要使用IBMWebSphere®ApplicationServerNetworkDeploymentV6.1作为应用程序服务网络。
两者之间的区别是WebSphereApplicationServerUnitTestEnvironment只能运行一个应用程序服务器,而WebSphereApplicationServerNetworkDeployment可运行支持多地点的多个应用程序服务器。
您应能够在其他IDE和支持相似技术的应用程序服务器中实现相同的结果。
WebSphereApplicationServerV6.1拥有基本消息功能。
当您完成测试准备部署到生产环境时,一般的您会使用JMS产品作为生产环境,如WebSphereMQ。
创建会话bean和MDB
开始时创建一个会话bean和三个MDB。
为创建会话bean:
1.打开RationalApplicationDeveloper。
2.创建一个J2EE1.4应用程序的2.1EnterpriseJavaBeans™(EJB)项目。
3.在EJB项目中,创建一个被称为TransferProcessBean的会话bean。
您可以用来进行此项工作的方法之一是publishMessage1。
它被编码以发送主题消息。
您可以在看到writeYourLogicInThisMethod1的地方增加您的逻辑。
表3.对会话bean的编码
publicvoidpublishMessage1()
{
TopicConnectionFactorytopicConnectionFactory=null;
TopicConnectiontopicConnection=null;
Topictopic=null;
TopicPublishertopicPublisher=null;
TopicSessiontopicSession=null;
StringconnectionFactoryName="java:
comp/env/TCF1IdeRef";
StringtopicName="java:
comp/env/Topic1IdeRef";
//Addyourtry,catchblocks
Contextctx=newInitialContext();
topicConnectionFactory=(TopicConnectionFactory)ctx
.lookup(connectionFactoryName);
topicConnection=topicConnectionFactory.createTopicConnection();
booleantransacted=false;
topicSession=topicConnection.createTopicSession(transacted,
TopicSession.AUTO_ACKNOWLEDGE);
topic=(Topic)ctx.lookup(topicName);
topicPublisher=topicSession.createPublisher(topic);
MessagemyOutgoingMessage1=null;
//AddyourlogicinwriteYourLogicInThisMethod1
StringmyOutgoingTmpMessage1=writeYourLogicInThisMethod1();
myOutgoingMessage1=topicSession.createTextMessage(myOutgoingTmpMessage1.trim());
//PublishtheTopic
topicPublisher.publish(myOutgoingMessage1);
topicPublisher.close();
topicSession.close();
topicConnection.close();
}
接着,创建三个MDB:
∙CheckInventoryMDB
∙CompleteRRTransferMDB
∙CompleteARTransferMDB
当您创建每个MDB时,选择:
∙JMStype:
javax.jms.MessageListener
∙Transactiontype:
Container
∙ActivationconfigurationofdestinationType:
javax.jms.Topic
∙ActivationconfigurationofacknowledgeMode:
Auto-acknowledge
当触发MDB时,被激活的方法是onMessage。
在writeYourLogicInThisMethod2中根据您的需要为每个MDB增加您的逻辑。
以下是onMessage方法的内容:
Listing4.TheonMessagemethod
publicvoidonMessage(javax.jms.Messagemsg)
{
StringmyIncomingMessage1;
//Addyourtry,catchblocks.
//SimilartoSessionBean,
makesuretodeclareJMSrelatedstuffsandClosethemoncedone
//ReadtheincomingMessage
myIncomingMessage1=((TextMessage)msg).getText();
//AddyourlogicinwriteYourLogicInThisMethod2
StringmyOutgoingMessage2=writeYourLogicInThisMethod2(myIncomingMessage1);
//PublishtheMessage.CodepublishMessage2similartoSessionBean
publishMessage2(myOutgoingMessage2);
}
部署JNDI引用
JavaNaming和DirectoryInterface™(JNDI)属于Java™平台的一部分。
它给基于Java技术的应用程序提供一个多重命名与目录服务的统一接口。
您需要一些JNDI来声明MDB监听器,这些是现在您需要做的。
按照如下步骤编辑您的EJBDD(配置描述符):
1.在Bean页签下,选择CheckInventoryMDB。
2.在WebSphereBindings页签下,选择JCAAdapter。
3.对于ActivationSpecJNDI,输入jms/AS1。
4.对于DestinationJNDIname,输入jms/Topic1。
5.对于CompleteRRTransferMDB,输入jms/AS2和jms/Topic2。
6.对于CompleteARTransferMDB,输入jms/AS3和jms/Topic3。
这意味着当一个消息在jms/Topic1中发送时,CheckInventoryMDB会自动运行。
相同的情况发生在jms/Topic2与CompleteRRTransferMDB、jms/Topic3与CompleteARTransferMDB中。
声明消息目的地
现在您准备为会话bean和MDB指定消息目的地。
对于会话bean:
1.在EJBDD中,进入References标签,选择会话bean。
2.按照如下步骤增加一个新的资源引用(ResourceReference):
oName:
TCF1IdeRef
oType:
javax.jms.TopicConnectionFactory
oAuth:
Application
oSharescope:
Shareable
3.还要按照以下步骤为主题消息增加一个新的资源参数:
oName:
Topic1IdeRef
oType:
javax.jms.Topic
oAuth:
Application
oSharescope:
Shareable
4.然后,选择Topic1IdeRef。
5.在WebSphereBindings下,通过键入jms/Topic1更新JNDI。
6.类似的,为TCF1IdeRef键入jms/TCF01。
对于MDB,按照以下步骤替换或修改TCF1IdeRef和Topic1IdeRef:
∙对于CheckInventoryMDB:
TCF2IdeRef和Topic2IdeRef
∙对于CompleteRRTransferMDB:
TCF3IdeRef和Topic3IdeRef
注意:
记住CompleteARTransferMDB不发送任何消息;它只是简单的监听DESTINATION3。
因此,您不需要为那个MDB增加引用。
开发前端
现在您已经建立起应用核心,您需要有一种机制引发能够触发其他MDB的会话bean。
我们有很多方式触发会话bean。
例如,通过Java类调用会话bean,诸如servlet或FacesJSP。
假设您创建了包含命令按钮的FacesJSP。
编辑FacesJSP,然后把会话bean拖到命令按钮上,这样点击按钮就可以触发会话bean。
定义应用服务器的JMS参数
在WebSphereApplicationServerUnitTestEngine的消息引擎中您需要JMS引用。
RationalApplicationDeveloper是一份免费拷贝。
下面是您必须配置的内容:
∙Serviceintegrationbus
∙Destinations
∙Busmembers
∙Connectionfactories
∙Activationspecs
注意:
需要更多资料,请访问WebSphereApplicationServerVersion6InformationCenter
启动您的WebSphereApplicationServerUnitTestEnvironment,并进入AdminConsole。
按照如下步骤键入JMS引用:
1.第一步:
创建WebSphereEnterpriseServiceBus通用总线
1.在ServiceIntegration下,进入Buses
2.创建以CommonBus1命名的新总线。
2.第二步:
创建总线目的地
1.在Buses下,进入CommonBus1/Destinations/New
2.设置Selectdestinationtype为Topicspace。
3.设置Identifier为DESTINATION1。
4.选择Busmember作为您的服务器。
5.重复第二步两次,一次为DESTINATION2一次为DESTINATION3。
3.第三步:
创建Busmembers
1.在ServiceIntegration下,进入Buses。
2.通过选择您的结点和服务器为CommonBus1增加一个新总线成员。
("例如:
"Node=pvtndserverNode01,Server=server1)
4.第四步:
创建TopicConnectionFactories、Topics和ActivationSpecs:
注意:
您将重复三遍第四步:
3TCFs、3Topics、3ActivationSpecs。
第二和第三遍的值在方括号[]内。
例如TCF1WASref[TCF2WASref,TCF3WASref]。
1.在Resources>JMSProviders>Defaultmessaging内。
2.选择您的结点和服务器。
5.4.1步:
创建TopicConnectionFactory。
1.JNDIname:
jms/TCF01[jms/TCF02,jms/TCF03]
2.Busname:
CommonBus1
3.Clientidentifiervalue:
(example)client1[client2,client3]
4.DurabilitySubscriptionHome:
键入.-(例如:
pvtndserverNode01.server1-CommonBus1)
5.Non-persistentmessagereliability:
Assuredpersistent
6.4.2步:
为Topic1WASref[Topic2WASref,Topic3WASref]创建主题。
1.JNDIname:
jms/Topic1[jms/Topic2,jms/Topic3]
2.TopicName:
Topic1IdeRef,它应与TopicName[Topic2IdeRef,Topic3IdeRef]的值相同
3.Busname:
CommonBus1
4.Topicspace:
DESTINATION1[DESTINATION2,DESTINATION3]
7.4.3步:
创建activationspec。
例如:
AS1WASref[AS1WASref,AS3WASref].
1.JNDIname:
jms/AS1[jms/AS3,jms/AS3]
2.Destinationtype:
Topic
3.DestinationJNDIname(与JMSTopic的JNDI名称相匹配):
jms/Topic1[jms/Topic2,jms/Topic3]
4.Busname:
CommonBus1
5.Subscriptiondurability:
Durable
6.Subscriptionname:
值的例子:
sn1[sn2,sn3]
7.Clientidentifier:
与您键入的TCF/clientidentifier名称一致。
例如:
client1[client2,client3]