作者: 朱先忠编译 出处: 天极网
摘要 本文将介绍如何实现你的ASP.NET应用程序与J2EE应用程序服务器之间的交互以及怎样使得调用EJB与调用XML Web服务一样地容易。
简介
今天,许多大型组织发现他们自己正在拥有和使用由.NET技术和J2EE技术混合组成的开发团队和发布服务器。为了平衡通过J2EE应用程序服务器发送的企业质量,公司的商业逻辑经常以企业JavaBean(EJB)的形式发布于J2EE应用程序服务器上。另一方面,为了满足日益变化的商业发展的要求,多数开发者比较喜欢在具有高度生产性能的Visual Studio.NET开发环境下实现描述逻辑。当你需要把.NET描述层连接到J2EE商业逻辑层时,挑战就产生了。
让我们看一下Visual MainWin for J2EE怎么帮助你面临和克服-从Visual Studio.NET中,用C#或Visual Basic.NET来实现ASP.NET描述层然后再调用以EJB形式实现的商业逻辑层-这一挑战性开发的。请放心,你将不需要纠缠于EJB API编码就能做这到一点。借助于Visual MainWin for J2EE,两个层-ASP.NET前端和EJB后台-都能够以一个纯粹的J2EE应用程序的形式运行于你的J2EE应用程序服务器上,并进行性能优化和实现一致的基于J2EE的安全性。
为实现从Visual Studio .NET中调用EJB,你必须安装Visual MainWin for J2EE的企业版本。当然,你可以从mainsoft.com网站上下载它的评估版本进行试验性分析。
示例分析
本文的股票投资(StocksPortfolio)示例-它向你展示怎样使用一个ASP.NET Web层和一个J2EE商业层来创建应用程序-被安装和建档于Visual MainWin for J2EE中。本示例实现了一个简单的ASP.NET网页-用户使用之来管理他们的股票投资-和一个ASP.NET Web服务-它用于提供虚构的股票行情。本示例还使用了一个会话EJB-为你的J2EE应用程序服务器所用以实现买卖股票的逻辑。
图1.运行于JBoss应用程序服务器上的StocksPortfolio应用程序
把EJB添加到你的.NET环境
从Visual Studio.NET中调用一个EJB与调用一个Web服务一样简单。在你的解决方案资源管理器中,右击"References",然后选择"Add EJB Reference",即出现一新的仅可用于Visual MainWin for J2EE工程的参考类型,它很类似于标准的Visual Studio .NETIDE下的Web参考(见图2)。
图2.添加EJB参考
为添加一个EJB参考到你的Visual MainWin for J2EE工程,你仅需要一个Java档案(JAR)文件-它实现了该EJB或者包含它的本地和远程接口。Visual MainWin能够查询应用程序服务器有关所有发布在它上面的EJB的信息并在一个对话框中显示相应于你的JAR定义的EJB。你只需要选择你想要使用的特定EJB(可能多个)即可(见图3)。
图3.添加EJB参考对话框
你也可以在一个远程应用程序服务器上消费该EJB,只要它与你的工程相关的本地应用程序服务器是一样的类型。这可能是一个Windows,Linux,Unix,主框架或任何其它支持J2EE的服务器。为了消费一个发布于一个远程服务器上的EJB,请点击"Advanced"来展开该对话框(见图4)。
图4.高级模式的添加EJB参考对话框
输入JNDI URL到远程J2EE应用程序服务器中,然后点击"Fetch From Server"。Visual MainWin将列出所有的发布于远程服务器上的EJB和相应于你的JAR文件的EJB。该操作与本地EJB是一致的。
选择你想要消费的EJB(可能多个),点击OK。一个新的EJB参考文件夹即产生于你的解决方案资源管理器浏览器中,如图5所示。该文件夹包含每一个刚添加上去的EJB参考的基于服务器的参考,类似于Web参考结点。另外,还生成一个包装类来简化你的EJB调用编码。在后面部分我们将讨论该包装类。
图5.显示有EJB参考的解决方案资源管理器文件夹
从.NET中调用EJB方法
当你添加一个EJB参考到你的工程时,系统将自动产生一个.NET(C#或VB.NET)类,它描述了一个简单的到该EJB的接口。该类包括要求创建该EJB和调用它的方法的J2EE编码。这个.NET类通过它自己的公共方法暴露了该EJB远程接口的方法。为调用你的EJB的商业方法,你只需简单地创建一个该包装类的实例并调用适当的包装类方法即可。
下面是从你的.NET工程中调用一个EJB方法的代码示例:
//创建StockTrader EJB的一个实例.
localhost.StockTraderEJB trader = new localhost.StockTraderEJB();
// 购买用户在股票名称文本框中定义的股票,
//所购买的股份数相应于股份数文本框中的数字
trader.buy(tbStockName.Text, Int32.Parse(tbNumOfShares.Text));
深入分析
在上面产生的包装类的静态构造器中执行被请求的J2EE调用以创建该EJB的home对象。然后,在一个缺省的构造器中,它使用home对象来创建该EJB对象。该EJB对象是以一个包装类成员的形式存储的,通过它来调用商业EJB方法。
下面是创建该StockTrader EJB的包装类的部分代码:
private static trading.StockTraderHome home;
private trading.StockTraderEJB ejbObj;
static StockTraderEJB() {
// 创建一个Java命名(JNDI)上下文
Context context;
context = vmw.j2ee.J2EEUtils.CreateContext(null, null);
object homeObj;
//从JNDI服务器获取home对象
homeObj = context.lookup("ejb/StockTrader");
home = ((trading.StockTraderHome)(homeObj));
}
//缺省的构造器:创建一个新的EJB实例
public StockTraderEJB() {
this.ejbObj = home.create();
}
这个包装类通过它的公共方法暴露该EJB远程接口的方法。然后,每个这些方法通过EJB对象调用你的EJB的相应的商业方法。下面的代码向你展示股票商的EJB包装器中的方法:
public virtual void buy(string arg_0, int arg_1) {
this.ejbObj.buy(arg_0, arg_1);
}
public virtual void sell(string arg_0, int arg_1) {
this.ejbObj.sell(arg_0, arg_1);
}
Visual MainWin还负责在Java和.NET之间映射数据类型。例如,如果你的EJB的方法之一以参数形式收到一个java.lang.calendar对象,那么,你将使用一个.NET System.DateTime对象参数来调用这个方法并把它映射到一个java.lang.calendar对象上。随后,如果你的EJB方法返回一个java.lang.class,你将收到一个System.Type对象作为代替。
调试问题
即使Visual MainWin对开发工作进行了简化处理,你仍然可能需要调试你的多级的、混合的ASP.NET/EJB应用程序。Visual MainWin调试器允许你从Visual Studio .NET IDE内部调试你的混合应用程序。你可以穿过语言边界在你的C#或VB.NET代码中设置中断,单步调试EJB Java代码和调试你的全部应用程序。而且,因为调试需要出现于任何问题发生的地方,所以,Visual MainWin调试器能够依附到你的J2EE应用程序服务器,而不管它是运行于Linux,Unix还是其它框架之上,只要它能运行在调试模式就行。
图6.使用Visual MainWin调试器来调试EJB源代码
Visual MainWin为你创建的应用程序是一个标准的J2EE servlet应用程序-它能够通过J2EE应用程序服务器主管控制台进行发布和管理,就象任何其它J2EE servlet应用程序一样。因此,你的ASP.NET描述层和你的EJB商业逻辑层都能依靠一样的J2EE安全基础结构。你的混合的ASP.NET/EJB应用程序能依靠一个通过使用J2EE servlet认证的一致的安全模型,而你的应用程序服务器用户和角色定义也能通过平衡基于角色的授权机制来保证安全性。
总结
1. 本文讨论了远程对象和接口。通过Visual MainWin进行本地对象消费也是可能的。为了发布一个使用本地对象的应用程序,你必须创建一个企业档案(EAR)文件-它既包括你的应用程序的WAR文件又包括本地EJB的JAR文件。
2. 虽然Visual MainWin能够把大多数的.NET类型映射到Java类型,它却不能进行集合类型的映射-因为这种映射可能导致一种性能损失。因此,你可以选择从你的.NET代码中处理Java集合类型或你自己执行这样的转化。
3. Visual MainWin允许你消费会话bean和非事务性实体beans。事务性实体bean不能被透明地消费,因此你必须手工编码J2EE事务调用。然而,在大多数情况中事务性实体bean可以通过会话bean进行存取,因此你不大可能需要这样做。