WebLogic Workshop集成.NET…
作者:WebLogic Workshop 小组
网络服务的宗旨是使运行于各种硬件平台上由不同厂商开发的应用,能够通过共同的一组协议和数据格式包括 SOAP、UDDI和WSDL进行相互定位和通讯。本文说明微软.NET的网络服务如何与BEA平台进行互操作。我首先描述如 何在每个平台上创建网络服务定义语言(WSDL)文件,然后讨论如何采用WSDL文件调用外部平台上的网络服务。 最后,将演示每个平台强大的、非标准的特性如何被其它平台使用。
两个简单的网络服务
在最初的例子中,我们将创建两个非常相似的网络服务,一个基于.NET,另一个基于WebLogic Workshop。两个网 络服务都有一个简单的方法getHelloMessage,返回简单的Hello消息。在示例中,将演示两个平台的网络服务之 间如何相互调用。
下面是WebLogic Workshop网络服务的代码:
public class WLWExample { /** @jws:operation */ public String getHelloMessage() { return "Hello from WebLogic Workshop!"; } }下面是.NET网络服务的代码:
using System.ComponentModel; using System.Web.Services; namespace DotNetExample { public class Service1 : WebService { public Service1() { InitializeComponent(); } private IContainer components = null; private void InitializeComponent() {} protected override void Dispose( bool disposing ) { if(disposing && components != null) components.Dispose(); base.Dispose(disposing); } [WebMethod] public string getHelloMessage() { return "Hello from Visual Studio .NET!"; } } }在编写调用这些网络服务的代码之前,需要先快速浏览一下网络服务互操作的工作原理。
网络服务互操作原理
网络服务互操作的核心是网络服务定义语言(WSDL). WSDL是一种基于XML的语言,使网络服务能够以平台中立的方 式发布其公开契约。WSDL用于描述由网络服务提供的方法,并描述这些方法能够产生和接收的消息。 WSDL是一种 通用格式,两个不同的网络服务产品能够通过WSDL描述其网络服务。
为了能够跨平台调用上述两个网络服务,必须首先为这两个网络服务生成WSDL文件。描述过程在WebLogic Workshop和Visual Studio .NET稍有差别,但都非常简单。
在WebLogic Workshop中创建WSDL
1. 在项目树(project tree)上,用右键点击您的网络服务并选择"Generate WSDL from JWS."(从JWS生成WSDL ),将从您的网络服务创建一个新WSDL文件。项目树将创建的WSDL作为网络服务的子项。
WebLogic Workshop对WSDL文件和CTRL文件将采用一种特殊的命名约定 (将在后面讨论)。假定您有一个网络服务 命名为Service.jws,那么此服务的WSDL文件将被命名为ServiceContract.wsdl,其CTRL文件将被命名为 ServiceControl.ctrl。
在Visual Studio .NET中创建WSDL
1. 按F5从菜单中选择Debug/Start在浏览器中打开网络服务;
2. 在Internet Explorer中按右键点击"Service
Description"(服务描述)连接,并选择"Save Target As"(存储目标为),并选择一个以。wsdl结束的文件名 。
即使对于简单的网络服务,其WSDL文件依然非常复杂。幸运的是,采用网络服务无需对WSDL细节进行了解。感 兴趣的读者,可以在http://www.w3.org/TR/wsdl找到WSDL完整的规范。
从WebLogic Workshop调用.NET网络服务
无论WebLogic Workshop或者是Visual Studio .NET,都有其内部机制来使用WSDL或引用被调用网络服务。在 WebLogic Workshop中,必须创建服务控制(Service Control),在Visual Studio .NET中,相应的概念是网络 引用(Web Reference)。本节将讨论如何为WSDL文件创建服务控制(Service Control),用于调用底层的网络 服务。下一节将对网络引用(Web Reference)进行讨论。
首先,需要创建一个新的WebLogic Workshop网络服务作为客户端访问.NET 网络服务。结束以后,再对此网络访 问增加服务控制。
从WSDL创建服务控制
1. 在设计视窗中点击"Add Control" (增加控制)下拉菜单并选择"Service Control."(服务控制)
2. 在第一个正文框中输入控制的变量名。这个变量名将被用于在源代码中引用此控制。
3. 选择组合框选项"Create a service control from a WSDL" (从WSDL创建服务控制),在正文框中输入WSDL 路径,也可以使用"Browse"(浏览)按钮指定WSDL位置 。
4. 按"Create"(创建)按钮。
创建服务控制将在您的网络服务中增加一行类似下列的代码:
/** @jws:control */ DotNetExampleControl dotNetExample;控制变量名应引起足够重视,因为这个名子将用于调用.NET网络服务。现在,可以添加一个方法使用服务控制 调用.NET 网络服务。这个调用看起来像下面的代码:
/** @jws:operation */ public String callDotNet() { return dotNetExample.getHelloMessage(); }之后,您应该有一个类似下面的WebLogic Workshop网络服务:
public class WLWClient { /** @jws:control */ private DotNetExampleControl dotNetExample; /** @jws:operation */ public String callDotNet() { return dotNetExample.getHelloMessage(); } }假设.NET网络服务正在运行,您应该能够运行这个网络服务,并激活callDotNet方法向.NET网络服务发送跨平台 调用。当激活这个方法时,将获得一个应答消息:.NET hello 消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <soap:Body > <getHelloMessageResponse xmlns="http://tempuri.org/" > <getHelloMessageResult > Hello from VisualStudio.NET! </getHelloMessageResult > </getHelloMessageResponse > </soap:Body > </soap:Envelope >从.NET调用WebLogic Workshop 网络服务
现在我们已经可以从WebLogic Workshop调用.NET网络服务,下一步将从.NET调用WebLogic Workshop 网络服务。 在WebLogic Workshop中,我们采用了服务控制来调用外部网络服务,在.NET中,我们将采用网络引用(Web Reference)。
从WSDL创建网络引用
1. 选择"Project"菜单,然后选择"Add Web Reference."(添加网络引用)
2. 这时将弹出一个对话框用于浏览网络服务。在地址正文输入框中,输入为WebLogic WorkshopIn网络服务创建 的WSDL文件的路径。
3. 选择"Add Reference"(添加引用) 按钮。
您选择已经为项目(project)添加了指向WebLogic Workshop 网络服务的网络引用。默认情况下,将命名为 WebReference1。采用Solution Explorer,能够看到引用已添加到项目中,在引用之下,可以看到引用相应的WSDL 。
像使用其它对象一样,您可以在C#中使用网络引用。首先,必须将引用输入(import)到源文件中, 只需在C#文 件中增加下列代码:
using DotNetClient.WebReference1;
一旦将引用输入到源文件中,就可以创建引用实例(instance),并使用它调用WebLogic Workshop 网络服务。 下列代码说明了C#服务的这个功能:
using System.ComponentModel; using System.Web.Services; using DotNetExample.WebReference1; namespace DotNetClient { public class Service1 : WebService { public Service1() { InitializeComponent(); } private IContainer components = null; private void InitializeComponent() {} protected override void Dispose( bool disposing ) { if(disposing && components != null) components.Dispose(); base.Dispose(disposing); } private WLWExample wlwExample = new WLWExample(); [WebMethod] public DataSet callWLW() { wlwExample.getHelloMessage(); } } }当您接口callWLW 方法时,将收到来自WebLogic Workshop 网络服务的hello消息。
< ?xml version="1.0" encoding="utf-8" ? > < string xmlns="http://tempuri.org/" > Hello from WebLogic Workshop! </string >从.NET调用会话式网络服务
在WebLogic Workshop中采用会话方式非常简单并且透明。但是,如果希望从.NET调用会话网络服务,必须需要额 外的工作以确保会话功能正常运行。
当网络服务客户端调用会话方法时,WebLogic Workshop采用了会话关键字确定这次调用相关的会话。会话关键字 嵌入在向网络服务发送的SOAP消息头中。对开始(start)方法,消息头格式如下:
<StartHeader > <conversationID > convID < /conversationID > <callbackLocation > callback < /callbackLocation > </StartHeader >会话ID和回调定位均为可选项。如果未提供会话ID,WebLogic Workshop将为您自动生成一个会话ID。回调定 位 (callback location) 用于指定WebLogic Workshop应向何处发送回调消息。
对于后续方法,会话头具有下列格式:
<ContinueHeader > <conversationID > convID </conversationID > </ContinueHeader >对于后续方法,必须指定会话ID,因为需要有一种方式告诉WebLogic Workshop,调用这个后续方法时,希望 加入哪个会话。回调定位不是必须的,它已经在起始方法中指定过。
为一个.NET网络服务增加SOAP头非常简单。会话网络服务的WSDL文件已经指定了起始和后续头的结构。所有.NET 已经知道如何进行格式化。当.NET创建网络引用时,它为每一个在WSDL中指定的SOAP头的引用中置入了一个字段 (域):
// A web reference to a conversational Web service. private WLWExample wlwExample; [WebMethod] public void callStartMethod() { wlwExample.StartHeaderValue = new WebReference1.StartHeader(); wlwExample.StartHeaderValue.conversationID = 齝onvID? wlwExample.StartHeaderValue.callbackLocation = 齝allbackLoc? wlwExample.startMethod(); }本例程假设已经有一个名为WebReference1 网络引用包含了一个指向名为cWLWExample网络服务的引用,与前面的 例程相似。WLWExample有一个名为startMethod方法开始一个会话。您应该用您实际需要的会话ID和回调定位替换 字符串"convID" 和"callbackLoc" 。
为了能够调用后续的方法,可以使用类似的代码(用ContinueHeaderValue替换StartHeaderValue )。在WebLogic Workshop中使用.NET DataSets
DataSet 是微软的活动数据对象(Active Data object ),用于提供数据的更通用的包装。一个DataSet 将 其数据模型化为一组表,其结构与SQL的表格非常相近,一样具有特定字段集、特定类型和次序。, DataSet对象 提供了丰富的工具装载和操作数据。但是,针对这篇文章的目的 ,我们对这些工具的兴趣远小于对数据集序列化 机制的关注。
创建DataSet样例
开始时,我们将创建一个简单的DataSet,表示电话簿并逐渐增加相应的例子数据。然后,将DataSet 从网络服务 返回。请注意DataSet如何序列化成为XML格式。
DataSet的概要非常简单。这里DataSet(数据集)中有一个表,我们称为"PhoneBook." (电话簿),表包含有三列 -一个ID列,作为主关键字,一个Name列和一个Telephone列。我们已向本DataSet中添加了一些样例数据。当调 用方法时,将返回下列XML:
<?xml version="1.0" encoding="utf-8"?> <DataSet xmlns="http://tempuri.org/"> <xs:schema id="MyDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="MyDataSet" msdata:IsDataSet="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="PhoneBook"> <xs:complexType> <xs:sequence> <xs:element name="ID" type="xs:int" /> <xs:element name="Name" type="xs:string" minOccurs="0" /> <xs:element name="Telephone" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="Constraint1" msdata:PrimaryKey="true"> <xs:selector xpath=".//PhoneBook" /> <xs:field xpath="ID" /> </xs:unique> </xs:element> </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> <MyDataSet xmlns=""> <PhoneBook diffgr:id="PhoneBook1" msdata:rowOrder="0"> <ID>1</ID> <Name>Fred</Name> <Telephone>555.2145</Telephone> </PhoneBook> <PhoneBook diffgr:id="PhoneBook2" msdata:rowOrder="1"> <ID>21</ID> <Name>Bob</Name> <Telephone>555.6246</Telephone> </PhoneBook> <PhoneBook diffgr:id="PhoneBook3" msdata:rowOrder="2"> <ID>3</ID> <Name>Howard</Name> <Telephone>555.1125</Telephone > </PhoneBook > <PhoneBook diffgr:id="PhoneBook4" msdata:rowOrder="3" > <ID>4</ID > <Name > Stanley</Name > <Telephone > 555.0932</Telephone > </PhoneBook > </MyDataSet > </diffgr:diffgram > </DataSet >DataSet有两部分XML编码。第一部分为概要,描述了XML编码的结构。第二部分DataSet的实际数据体。本文中, 我们将忽略概要部分,假定预先已知,而只集中精力于数据自身的解码。在更复杂的应用中,可能需要利用概要 提供的其它信息。
我们创建的表中数据被编码为更简单的格式,其元素按下列格式不断重复。
<PhoneBook> <ID></ID> <Name></Name> <Telephone></Telephone> </PhoneBook>给定我们所知的特定XML形式,我们能够编写一个WebLogic Workshop 网络服务使用这个数据。
利用XML Map(视图)提取数据
利用WebLogic Workshop的XML映射技术,我们能够捕获数据并将其存储为Java对象以表示电话簿中的信息项。首 先,我们需要定义一个Java类型以承载电话簿信息项。下列代码能够满足这个要求:
为了将接收到的XML进行解码,我们将采用XML视图。下列XML视图能够用来返回服务控制的视图,这些服务控 制用于调用.NET 网络服务从而返回DataSet。
/** * @jws:return-xml xml-map:: * <getDataSetResponse xmlns="http://tempuri.org/"> * <getDataSetResult> * <diffgr:diffgram * xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> * <MyDataSet xmlns=""> * <PhoneBook xm:multiple="entry in return"> * <ID>{entry.id}</ID> * <Name>{entry.name}</Name> * <Telephone>{entry.telephone}</Telephone> * </PhoneBook> * </MyDataSet> * </diffgr:diffgram> * </getDataSetResult> * </getDataSetResponse> * :: */ public PhoneBookEntry[] getDataSet();本映射应该添加到.NET网络服务的CTRL的getDataSet方法中。映射看起来有点复杂,实际上只是深入到.NET网 络服务返回的XML,并获取电话簿条目列表。然后,利用xm:multiple 属性将每个电话簿条目的数据与getDataSet 返回的数组元素绑定。
您可能已经注意到,本映射建议的XML与前面描述有所不同。不幸的是,WebLogic Workshop收到的SOAP消息与 .NET网络接口显示的XML看上去有差别。可以通过从WebLogic Workshop激活.NET网络服务方法来发现WebLogic Workshop 实际收到的XML消息,并采用测试查看.NET返回的XML消息。
结束语
在网络服务世界中,互操作具有重要的意义。WebLogic Workshop很容易与其它网络服务实现实现互操作。本文中 ,我们浏览了与.NET互操作需要的工作。但是,本文讨论的原则适用于能够生成有效WSDL的任何网络服务产品。
- · WebLogic Server 环境下先进的JMS设计模式
- · 项目推出:针对WLS 7和8.1的COMMONJ WORK MANAGER
- · JMS集群第1部分
- · WebLogic平台的Web SSO(SAML)解决方案
- · WebLogic8中的扩展JSP标签实例解析
- · 解决打开文件过多的问题
- · 使用JMS在集群应用程序中分配任务
- · WebLogic Workshop 8.1 Jav…
- · BEA Workshop8.1之Java Pag…
- · WebLogic Server8.1新功能介…
- · 总结:第一个Java控件
- · 教程:构建第一个Java控件
- · 用WebLogic Workshop开发EJB
- · 用WebLogic Workshop调试应…
- · WLS 9.1与MQ v5.3 通过JMS Bridge通信配置
- · 在Apache Xindice中保存XML文档
- · 升级到WebLogic 9的十大理由
- · 在JAVA EE环境下使用Kodo EJB
- · Weblogic Server 9新特性:J2EE Libraries 和 Optional Packages
- · WebLogic Server 9新特性:JSR-181 Web Services
- · WebLogic Server 9.0:JMS增强功能
- · WebLogic Server9.0产品重点新特性介绍
- · 在Spring中实现事务挂起
- · ALUI 界面深入客户化——替换Portal内置组件
- · ALUI在解决企业门户上的优势
- · AquaLogic User Interaction开发入门
- · 添加协作服务
- · 使用WebLogic SIP Server和WebLogic Workshop驱动Cantata媒体服务器
- · 深入Beehive标签库系列教程 - 前提条件
- · 深入Beehive标签库系列教程(1) - 基本NETUI标签
- · 深入Beehive标签库系列教程(3) - 表单标签:单选框
- · 深入Beehive标签库系列教程(5) - 表单控件:下拉框
- · 深入Beehive标签库系列教程(6) - 使用标签遍历数据
- · 赢得网络服务开发人员的三大…
- · 大规模的财政应用和面向服务…
- · BEA实现了新的Web服务标准
- · 赢得Web服务开发者青睐的“…
- · 第11步:运行Request Quote…
