CSDN博客

img qiaov

应用程序互操作性:点对点

发表于2004/9/16 14:04:00  2170人阅读

 

发布日期: 09/15/2004 | 更新日期: 09/15/2004
pponline

Microsoft Corporation

摘要: 着重介绍 XML Web 服务和 .NET 远程处理的点对点通讯方法。 主题包括二进制通讯和路由以及集成 Java 和 .NET 内容的第三方运行时桥的使用。

*
本页内容
使用 .NET 远程处理以进行连接 使用 .NET 远程处理以进行连接
实现运行时桥 实现运行时桥
连接 Web 服务 连接 Web 服务
小结 小结
参考资料 参考资料

设计一个有效的互用性解决方案需要详细地了解用来连接 Java 和 .NET Framework系统的技术。 本章介绍点对点的场景下可以使用的连接两个平台的方法,这样一个应用程序可以与另一个应用程序同步交互。

这种让 .NET Framework和 Java 在点对点的基础上交互的技术主要有两种:

.NET 远程处理

XML Web 服务

.NET 远程处理是所讲述的第一个技术,它在纯粹的 .NET Framework环境下提供了许多优点,例如:更好的性能和简单的实现方法。 然而,Java 应用程序不能直接使用 .NET 远程处理连接,它们需要使用运行时桥实现。 本章来研究两个最流行的运行时桥产品,Ja.NET 和 JNBridgePro。

只要开发人员和系统架构师开始讨论互用性,Web 服务就会越来越流行。 Web 服务到处存在并且保证不必显式描述方法,但它们不总是最好的互用性解决方案。

使用 .NET 远程处理以进行连接

在第二章,“理解企业平台”,您了解到 .NET 远程处理是供 Microsoft 基于 .NET Framework的分布式应用程序使用的通讯和数据传输机制。 虽然 .NET 远程处理主要是为 .NET Framework应用程序之间通讯而设计的,但它提供了一种可扩展的通讯框架,您可以以其为基础,对其进行自定义以支持与 Java 应用程序的连接。

为了使用 .NET 远程处理实现和 Java 应用程序的互用性,您必须实现一个运行时桥,并且在本章的稍后部分您可以看到这两种运行时桥,来自 Intrinsyc 的 Ja.NET 和来自 JNBridge, Inc. 的 JNBridgePro。 在您学习运行时桥之前,您需要对 .NET 远程处理有一个扎实的理解。

理解 .NET 远程处理

从根本上说,.NET 远程处理让相同或不同的应用程序域内的两个进程以客户端-服务器的方式进行彼此通讯。 在一般情况下,服务器组件是一个远程对象。

.NET 远程处理通过将远程对象与一个特定的客户端、服务器应用程序域或者特定的通讯机制相分离实现进程间通讯。 因此,.NET 远程处理是灵活的,且可方便地进行自定义。

通过使用以下两个主要概念,这种抽象得以实现:

通道通道在远程组件之间提供传输。 默认的通道是 TCP 和 HTTP。

格式化程序 格式化程序将对象转换(序列化)为一种其他进程(或者对于互用性场合是平台)能理解的公共格式。 默认格式化程序是二进制和 SOAP。

本章稍后章节会讨论 SOAP。

在第三章,“互用性基本原理”,您了解了二进制序列化和 XML 序列化。 二进制格式化程序对数据对象执行二进制序列化,SOPA 格式化程序对数据对象执行 XML 序列化。 然而,SOAP 格式化程序用额外的与 SOAP 相关的 XML 标记对序列化的 XML 文档进行包装。

通过指定通道和格式化程序,您可以定义如何在一个远程对象和其客户端之间建立通讯。 通道指定通讯协议。 格式化程序然后充当序列化程序,序列化和反序列化在远程对象和客户端间传输的数据对象。 自定义这些通道和格式化程序的作用是让您使用 .NET 远程处理在 .NET Framework应用程序和 Java 应用程序间实现连接。

.NET 远程处理不仅提供进程间的通讯,您还可以用它在不同的应用程序域中连接两个或更多的应用程序组件。 要这样做,只需要在单独的应用程序域间交换数据时更改 .NET 远程处理的配置。 这为构建在单独一台计算机上运行的应用程序提供了灵活性,而且可以用最小的代码调整即可将其扩展为可以在一个分布式环境中运行。

.NET 远程处理也支持两种在应用程序组件间传输数据的方法。 它们是:

按值传递 (PBV)

按引用传递 (PBR)

按值传递涉及从远程系统调用将数据返回到客户端。 按引用传递返回一个到数据的指针或引用并且远程服务器保持数据的状态。

这两个方法各有优缺点。 您选择的方法取决于您正在开发的应用程序的类型、您要传递的数据和应用程序必须在其中运行的网络环境。

当交换大数据对象时或者在网络滞后时间使按值传递通讯变慢的分布式系统中的时候,按引用传递可以提供性能方面的优势。 然而,如果您通过引用传递一个数据对象,则每次客户端访问对象上的另一字段时都对服务器上被引用的数据对象进行一次远程调用。

例如:如果您按引用将一个名为 custDataCustomerData 对象传递到客户端,每次客户端访问一个字段,例如:custData.Name 或者 custData.Address 时,都要对服务器进行一次远程调用。 这可能产生一个紧密耦合并且繁琐的应用程序。

在面向服务的应用程序中,应用程序组件间的松耦合更理想,因此您应该使用按值传递。

实现 .NET 远程处理

在两个组件直接通讯的一个典型 .NET 远程处理实现中,它由以下几项构成:

一个远程应用程序对象或者服务器组件

一个监听客户端到远程应用程序组件请求的宿主应用程序。

一个发请求到远程应用程序组件的客户端应用程序组件。

图 4.1 说明了一个在客户端和服务器之间进行 .NET 远程处理框架连接的例子。

j2ee_interop_c4_fig4-1

图 4.1: 一个典型的 .NET 远程处理实现

实现 .NET 远程处理包括以下阶段:

确定宿主应用程序或者环境。

创建服务器组件。

创建客户端。

编辑配置文件。

以下部分提供了一个实现 .NET 远程处理必需的步骤的概述。 有关 .NET 远程处理的更多信息,请参阅本章末尾的参考部分。 有关 XBike 示例应用程序中的编码示例,请参阅第 7 到 9 章。

确定宿主应用程序或者环境

.NET 远程处理服务器组件需要在一个应用程序域中宿主,以监听该对象的传入请求。 宿主一个远程处理服务器组件您有四种选择:

IIS 上的 ASP.NET

组件服务 (COM+)

一个 Windows 系统服务

一个 Windows 应用程序(基于控制台或 Windows 窗体)

您可以将 .NET 远程处理对象作为运行在 IIS 上的 ASP.NET 组件一样宿主。 这带来了许多好处,包括对安全性和易伸缩性的内置支持。 有了这些配置,您既可以用二进制也可以用 SOAP 格式化程序,但您只能用 HTTP 通道,它比 TCP 慢。

您可以将组件服务中的远程处理对象作为 Windows XP Professional SP1 或 winodws Server 2003 上的 COM+ 服务组件一样宿主。此配置提供了组件服务的企业功能,如集成的安全性、事务处理、池化和激活。

您可以在任何托管 Windows 服务中宿主远程处理对象。 在一个 Windows 服务中宿主一个远程处理对象为使用所选择的任何通道或者格式化程序配置提供了灵活性,包括 TCP 上的最高效率的二进制执行组合。 然而,.NET 远程处理并没有一个内置的安全模型。 因此,如果您要在一个 Windows 服务中宿主一个远程对象,则需要建立自己的身份验证和授权机制。

最后,您可以在一个 Windows 应用程序中宿主一个远程处理服务器组件。 然而,应用程序运行在登录用户的上下文中,因此需要用户登录后才能执行。 它们还运行在该用户的安全上下文中,这可能不适合您的环境。 在一个 Windows 服务中宿主一个远程服务器组件会更好。

当在一个 Windows 窗体应用程序中宿主一个组件时,一个 Windows 服务或者一些其他应用程序类型时,应由程序员指定端口。 对非 ASP.NET 主机来说,远程处理可以监听任何没有使用的端口。

通常,因为 IIS 提供安全和性能上的好处,您应该使用它来宿主远程处理对象。 有关在 IIS 中宿主一个远程对象的更多信息,请参阅本章末尾的参考部分。 有关在 XBikes 示例应用程序中结合使用 Ja.NET 和 .NET 远程处理的例子,请参阅第 7 章和第 8 章。

创建服务器组件

服务器组件是服务的提供者,提供客户端应用程序按引用调用的方法或者客户端按值发送和接收的数据。 为通过 .NET 远程处理通讯,服务器组件类需要从 MarshalByRefObject 类继承。 服务器组件通过值传递的任何数据必须是可序列化的。

创建客户端组件

为了在客户端上启用 .NET 远程处理,您不必实现任何额外的接口。 然而,客户端必须具有对服务器组件或者接口的引用。 客户端使用这个引用查询服务器组件公开的任何方法或者数据类型。 客户端也需要加载远程处理配置,既可以从自己的代码也可以从一个配置文件加载。

编辑配置文件

下列 .NET 远程处理项目需要配置:

对远程系统的引用

通道

格式化程序

您既可以在您的应用程序代码中存储这些设置也可以在运行时访问一个配置文件中的设置以配置所有这些项目。 建议您把您的配置设置存储在一个配置文件中,这样您可以不重新编译应用程序即可改变它们。 在成品系统中,这个方法提供更多的灵活性,让您不重新编译和部署应用程序而实现改变设置。

在 .NET 远程处理方案中,客户端组件和服务器组件都必须访问配置信息。 如果您在一个文件中存储配置设置,对于客户端和服务器端来说这些文件的内容和位置是不一样的。

.NET 远程处理配置文件是 XML 格式化的文本文件。 您可以在记事本或者您选择的文本编辑器中编辑这些配置。

服务器组件配置

在服务器端,在客户端可以访问它们之前,您必须给所有的远程对象注册 .NET 远程处理环境。 这个注册过程中,您必须给 .NET 远程处理框架提供所有的关于激活和管理这个对象的生命周期所需的全部信息。 注册所需的最重要的信息是:

对象类型

对象位置 (URL)

管理对象生命周期的激活要求

连接对象的通道

服务器远程处理配置文件的位置取决于您所使用的宿主应用程序。例如:

对于 IIS 宿主应用程序来说,您在位于应用程序的虚拟根的 Web.config 文件中存储远程处理配置。

对于组件服务宿主应用程序来说,远程处理配置将被存储在 /System32 目录中创建的名为 Dllhost.exe.config 的文件中。 这是因为服务器组件 Dllhost.exe 作为 COM+ 进程的一部分运行。

对一个 Windows 服务来说,远程处理配置信息在 Windows 服务的应用程序配置文件中。 例如:如果 Windows 服务被命名为 Myservice.exe,远程处理配置就在文件 Myservice.exe.config 中。

客户端组件配置

客户端也必须加载像服务器一样的配置设置。您存储客户端配置设置在您创建的命名文件中,例如名为 Remoting.config 的文件。 客户端应用程序用配置文件名作为一个参数调用 加载这个文件。 Remoting.config 文件的位置取决于客户端组件所属的应用程序类型。例如:

对基于 ASP.NET 的客户端来说,Remoting.config 文件位于应用程序的虚拟根目录。 这些配置设置必须在Global.asax 文件的 Application_Start 方法中加载。

对 COM+ 服务组件客户端来说,Remoting.config 文件位于 /system32 目录中。

对任何其他的客户端来说,Remoting.config 文件应该同客户端可执行文件放在相同的目录中。

现在您理解了 .NET 远程处理的基本原理,接下来的章节将讲述如何用这种技术连接 Java 应用程序。

实现运行时桥

有部分供应商就是用 .NET 远程处理作为基本的连接协议在 .NET Framework应用程序和 Java 应用程序间实现互用性。 运行时桥在某种程度上公开 Java 对象和方法,使您可用 .NET 远程处理的方法处理它们,反之亦然。 这个范畴下的两个主要的产品是来自 Intrinsyc 的 Ja.NET 和来自 JNBridge Inc. 的 JNBridgePro。

Ja.NET 和 JNBridgePro 不同之处在于 JNBridgePro 允许从 .NET 远程处理客户端到 Java 对象和类的调用,但是 Ja.NET 允许反相操作。 这个不同点对这本书讲述的方案没有影响。

评估 Ja.NET

Ja.NET 提供 Java 的 .NET 远程处理堆栈的双向实现。 使用 Ja.NET, 您可以产生 Java 代理,它们用 .NET 远程处理协议公开或使用组件。

因为 Ja.NET 是一个双向桥,所以从 .NET 访问 Java 会产生一组 C# 代理。 同样,从 Java 访问 .NET 会产生一组 Java 代理。

如果您检查产生的代理,您应该会注意到按值传递的类包含其所有字段的方法,而按引用传递的类的远程处理只是一个定义这个类的外壳。 Ja.NET 编译定义需要这些,并且在稍后的运行时需要它们以用于 类模拟远程服务器。 如果您尝试创建一个这个类的本地副本,这会产生一个异常。 您只能拥有一个这个类的远程 实例。 这些代理不使用自定义的代码,只使用纯粹的 .NET 远程处理。

当分析一个.NET 程序集时,如果您观察产生的 Java 代理,您应该可以看到封送处理和反封送处理到 Ja.NET 运行库的调用参数的许多代码。 当从 Java 访问 .NET 时,您需要自定义初始化 Ja.NET 运行库的代码,及任何远程发送或者接收类的代码。 然而,.NET 端仍然不需要任何特殊代码,因为 Ja.NET 遵循远程对象的 .NET 规则。

Ja.NET 让 Java 组件表现得像 CLR 组件一样,并且让 CLR 组件表现得像 Java 组件一样。 此外,Ja.NET Janetor 工具通过在一个 WAR 文件内产生 Java 代理来扩展这个功能。 您然后可以在一个Web 服务器上承载这个 WAR 文件,再次用所有基于 .NET 远程处理的通讯支持从 .NET Framework 访问 EJB。

从 Java 访问一个 .NET Framework 服务器

最简单的实现是当 Ja.NET 运行库让一个 Java 客户端访问一个 .NET Framework 服务器(在这种情况下,是以 Visual Basic.NET 实现的)。 图 4.2 说明如何完成它。

j2ee_interop_c4_fig4-2

图 4.2: 连接 Ja.NET 到一个 VB.NET 服务器组件

图 4.2 说明 Java 平台如何承载 Ja.NET 运行库组件。

从 Java 访问 IIS 组件。

Java 客户端也可以使用 Ja.NET 运行库访问一个远程 CLR 组件,就好像它是一个本地 Java 组件一样。 图 4.3 图解了这个方法。

j2ee_interop_c4_fig4-3

图 4.3: 将 Ja.NET 连接到 IIS 上寄宿的 .NET 组件

图 4.3 说明了在 Java 客户端和 Ja.NET 运行库间处理通讯的 Ja.NET 代理。 在这个例子中,IIS 正承载 .NET Framework 应用程序。

从 .NET Framework 访问一个 EJB

第三个方法将包含 Ja.NET 运行库的 WAR文件部署到支持 servlet 的任何 Web 服务器。 CLR 客户端(用任何受支持的 .NET Framework 语言编写)可以访问 EJB 就好像访问本地 CLR 组件一样。 图 4.4 说明了这种使用的一个例子。

j2ee_interop_c4_fig4-4

图 4.4: 使用 Ja.NET 连接一个 .NET 客户端到一个 EJB。

此外,Ja.NET 运行库让您:

用任何 .NET 支持的语言写 EJB 的客户端。

从任何 Java 对象或者 EJB 访问 .NET Framework 组件。

用其他环境重用每个平台的组件。

因为从传输和数据格式化角度看 .NET 远程处理是一个可扩展协议,Ja.NET 支持 HTTP 和 TCP/IP 传输协议以及 SOAP 和二进制数据格式化并且可以支持未来的传输和格式化程序。

Ja.NET 工具集

Ja.NET 工具集由六个主要部分组成。 它们是:

GenServiceGenJava 和 GenNet 工具使用 GenService 提供对 .NET Framework 程序集的访问,以进行开发。 您只需要 GenService 以产生代理,所以您不必在产品的环境中安装它。

GenNet GenNet 产生 .NET Framework 代理,该代理通过 Ja.NET 运行库访问 Java 类。

GenJava GetJava 产生 Java 代理,该代理通过 Ja.NET 运行库访问 .NET Framework 程序集。

Janetor Janetor 工具让您查看和修改 Ja.NET 运行库配置设置。 您也可以用 Janetor 产生 WAR 文件,帮助将 Ja.NET 运行库部署到 Web 服务器。 Janetor 包括 Ja.NET 产品、本地共享和远程访问对象的许可证。

Ja.NET TCP server Ja.NET TCP 服务器通过 Ja.NET 运行库提供对 Java 类的独立宿主,而这些 Java 类并不寄宿在 J2EE 服务器上。 Ja.NET 运行库包括这个组件。

Ja.NET 运行库 鈥_ Ja.NET 运行库是承载这些工具的主要类集合。 Janet.jar 文件包含运行时组件。

在 .NET Framework 和 Java 之间链接类型。

当使用 Ja.NET 将 .NET Framework 链接到 Java 时,您需要理解在 .NET Framework 的数据类型和 Java 的数据类型之间的链接。 表4.1 说明了这个信息。

表 4.1: .NET Framework 到 Java 的数据类型映射。
.NET Framework 数据类型 Java 数据类型

System.Boolean

boolean

System.Char

char

System.String

java.lang.String

System.Single

float

System.Double

double

System.Int8

byte

System.Int16

short

System.Int32

int

System.Int64

long

System.Byte

byte

System.UInt16

short

System.UInt32

int

System.UInt64

Long

System.Object

java.lang.Object

System.DateTime

Java.util.Date

表 4.2 说明您如何能使用 Ja.NET 在 Java 和 .NET Framework 间映射集合。

表 4.2: Ja.NET 集合在 Java 和 .NET Framework 间的映射
Java 集合类 .NET Framework 集合类

java.util.ArrayList

System.Collections.IList

Java.util.LinkedList

System.Collections.IList

Java.util.Vector

System.Collections.IList

表 4.3 说明从 .NET Framework 到 Java 的相反映射。

表 4.3: Ja.NET 集合在 .NET Framework 和 Java 间的映射
.NET Framework 集合类 Java 集合类

System.Collections.ArrayList

j ava.util.List

有关类型和集合映射的更多信息,请参阅 Ja.NET 文档。

理解 Ja.NET 事件和异常

为彻底了解 .NET 远程处理选项您需要理解更多的概念。 它包括下列概念:

事件Ja.NET 通过在 .NET Framework 上将 java.util.EventListener 扩展到系统事件的能力提供事件支持。 这提供了一个重大的优势,因为服务器组件现在可以通过这个事件模型实现到客户端的回调。 当您要实现异步操作或者长时间运行的事务时,事件会特别有用。

异常处理Ja.NET 提供异常处理功能,在一个平台上将异常报告到另一个平台上。 Java 服务器异常映射回 .NET Framework 的 System.Runtime.Remoting.RemotingException函数而 .NET Framework 上的异常映射回 com.instrinsyc.janet.RemoteException

通常,这些派生的异常包含来自原始异常的文本。 为处理这些异常,需捕获作为结果而发生的异常,然后在嵌入的异常内搜索文本以得到更多的信息。

强命名支持Ja.NET 支持使用和创建强命名程序集。 然后您可以在全局程序集缓存中注册这些程序集,以用于服务组件 (COM+)。

易于配置 因为 Ja.NET 是一个纯粹的 .NET 远程处理协议的 Java 实现,.NET Framework 方不需要特殊的运行时库。 在 .NET Framework 方的配置和一个标准的 .NET 远程处理实现一样,只需要一个简单的包含类和接口定义的 DLL。 任何可以在 .NET Framework 上实现远程处理的(派生自 MarshallByRefObject ),也可以在 Ja.NET 上实现远程处理。您也可以通过传值发送序列化类,就像只在 .NET Framework 上的实现一样。

实现 Ja.NET 的最佳准则

当使用 Ja.NET 时,您应实现几个最佳实践。这些问题包括性能、设计和部署因素。例如:

升级到 1.5 版。

为 .NET 远程处理使用二进制协议。

在应用程序服务器上部署 WAR 包以访问 EJB 和 JMS。

理解 .NET 远程处理以促成好的设计实践。

领会按引用传递 (PBR) 和按值传递 (PBV) 的差异。

升级到 1.5 版

强烈建议您升级到 Ja.NET 1.5 版,这对早期的 Ja.NET 版本的用户来说是免费的。1.5 版包含许多重要的新功能,其中一些功能对运行本书中的示例来说是必需的。 一些新功能包括以下内容:

强命名程序集支持。

在 .NET Framework 类型和 Java 类型间改善类型映射。

重大的性能提升。

改善双方平台的按值传递类的序列化能力。

用于非企业层次通过 HTTP 远程访问的集成的 Web 服务器。

改善的 SDK。

.NET Framework 版本 1.0 和 1.1 的运行时支持。

用于 JMS 的集成的 .NET Framework 代理。

稳定性和性能的加强。

使用二进制协议进行 .NET 远程处理。

这一章描述使用 .NET 远程处理而不是 SOAP 的好处。 尽管 Ja.NET 也支持 SOAP 连接,但 .NET 远程处理提供更好的性能,用 TCP/二进制提供最快的连接。 然而,如果您需要穿越防火墙,要使用 IIS 的安全基础结构,或者轻松地在一个应用程序服务器内部部署组件,则 HTTP/二进制是首选的协议。

HTTP/二进制仍然比 HTTP/SOAP 快得多。

在应用程序服务器上部署 WAR 包以访问 EJB 和 JMS。

最快的访问 EJB 的方法是从应用程序服务器自身进行访问。 最简单的部署方案是创建一个包含 Ja.NET 运行时 JAR、EJB 客户端 JAR 和一个配置文件的 WAR 文件。 您可以使用 Ja.NET Janetor 工具来轻松地创建 WAR 文件,然后您可以立刻部署到应用程序服务器。 因为 WAR 文件驻留在应用程序所在的同一个进程空间内,访问 EJB 比从一个外部的进程用 RMI 访问它要快得多。

理解 .NET 远程处理以促成好的设计实践

因为 Ja.NET 是一个 .NET 远程处理协议的纯粹 Java 实现,所以 .NET 远程处理最佳实践的同样规则也适用于 Ja.NET。确保您读过目前的关于 .NET 远程处理的著作,这样才能理解将它和 Ja.NET 结合使用的优势。

领会 PBR 和 PBV 的不同。

在一个 PBR 类中,每个方法调用导致一个数据请求。 然而,如果您发送一个 PBV 类,这会序列化整个类,包括超类或类的字段。 如果您通过值传递一个非常大的对象,而该对象有众多包含大量数据的字段,则这可能产生一个相当大的网络流量。 这种情况下,使用 PBR 可能更好。 与此相似,如果您有一个小类,就考虑用按值传递发送一个这个类的副本,而不是为每个字段的访问做一次网络调用。 理解了 PBR 和 PBV 的差别就减小了网络流量,并且改善了性能。

评估 JNBridgePro

JNBridgePro 是一个将 Java 组件链接到 .NET Framework 的点对点桥接解决方案。 Java 代码运行在普通的 Java 虚拟机 (JVM) 或者 J2EE 应用程序服务器上,而 .NET Framework 代码则运行在标准 .NET Framework CLR 上。 JNBridgePro 随后管理双方的通讯。

代理使 Java 类和对象表现得像普通的 .NET Framework 类和对象一样。 .NET Framework 组件和那些代理交互就像标准的本地 .NET Framework 函数调用一样,但代理对象透明地将调用重定向到 Java 方。 Java 组件处理方法调用和字段访问并且将值或者数据返回给代理。 然后,代理把结果提供给 .NET Framework 组件。

一个使用 JNBridgePro 来执行 Java/.NET Framework 互用的应用程序包含 JNBridgePro 的 .NET Framework 方和 Java 方运行时组件(这些组件管理平台间通讯和对象生命周期),和一个 .NET Framework 程序集(一个 DLL),该程序集包含公开给 .NET Framework 的 Java 类的代理。 开发人员使用 JNBridgePro 工具包产生代理。

图 4.5 显示了 JNBridgePro 的体系结构。

j2ee_interop_c4_fig4-5

图 4.5: JNBridgePro 运行时桥的内部体系结构

图 4.5 显示了 .NET Framework 方的运行时组件和代理。 请将其与图 4.3 比较。

.NET 远程处理集成 JNBridgePro。

JNBridgePro 使用 .NET 远程处理来实现 .NET Framework 方和 Java 方之间的通讯。 因为 .NET 远程处理是一个可扩展的体系结构,您可以按需要改变通讯通道。 JNBridgePro 使用这个可扩展体系结构来支持 SOAP 和二进制通讯。

.NET 远程处理也包括与传统的“本地”面向对象开发不同的概念,如租用、已知对象、及客户端激活的对象和服务器激活的对象。 JNBridgePro 可以封装这些概念并且对用户隐藏它们。 因此 Java 和 .NET Framework 代码之间的 JNBridgePro 互用在开发人员看来就像本地开发一样。

JNBridgePro 在 .NET 远程处理基础上创建了额外的功能。 例如,基本的 .NET 远程处理可以访问实际对象的成员,但如果类的静态成员不是类的实际实例成员,则基本的 .NET 远程处理无法访问它。 JNBridgePro 提供访问那些静态类成员的能力。

理解 JNBridgePro 功能

JNBridgePro 允许通过调用对应的 JNBridgePro 代理访问 Java 类和对象。 JNBridgePro 除支持对字段的访问请求和方法调用外,还支持访问静态和实例成员。 您可以通过使用 .NET Framework 代码调用 Java 类和对象的 .NET Framework 代理来从 .NET Framework 显式调用 Java,并且您可以通过使用 .NET Framework代码注册一个回调对象并且让 Java 代码通过它实现的侦听器接口访问回调对象来从 Java 隐式调用 .NET Framework。

Java 方组件可以驻留在一个独立 JVM 或者一个 J2EE 应用程序服务器中。 在 .NET Framework 和 Java 方之间的通讯可以使用 SOAP 或者更快的二进制协议。

JNBridgePro 支持事务处理,允许您从 .NET Framework 到 Java 在同一事务内作出一系列调用。 如果事务失败,则整个序列将回滚到开始点。 这可防止应用程序调用在 .NET Framework 和 Java 方之间挂起。 JNBridgePro 也可以为在执行时动态产生的 Java 类创建 .NET Framework 代理。 这样动态产生的类经常出现在 J2EE 应用程序中,尤其当链接到 JNDI 和 EJB 组件时。

JNBridgePro 也支持下面的情况:

在 .NET Framework 和 Java 基元之间映射。

字符串。

集合。

支持按值传递 (PBV) 和按引用传递 (PBR)。

连接到基于 Java 的消息处理服务器。

选择 JNBridgePro

如果您的应用程序需要在 .NET Framework 和 Java 对象间的同步、点对点的通讯并且需满足以下要求中的一个或者多个,那么请为 J2EE 和 .NET Framework 互用选择 JNBridgePro:

高性能 您的应用程序需要一个低开销、高性能的互用性机制,而 Java 平台和 .NET Framework 位于同一局域网或 intranet 中,或者在同一机器上。

向 .NET Framework 接口公开一个丰富的面向对象的 Java API 您的应用程序需要 Java 向 .NET Framework 应用程序公开大量的 Java 类 API,或者 Java API 返回自定义 Java 对象或者需要自定义 Java 对象作为参数。

“频繁”交互 您的应用程序在 Java 和 .NET Framework 之间执行频繁的细粒度调用。 Web 服务使用不频繁和更粗粒度的“简短结实”的交互会工作得更好。

期望保持“本地”、面向对象的开发模型 您的应用程序架构师决定不实现公开少量类的 API 作为服务、面向服务的模型。 相反,他们希望 .NET Framework 代码用新的运算符构造新的 Java 对象,使用跨平台垃圾回收技术,并且提供一个传统的“本地”面向对象模型。

实现 JNBridgePro 最佳实践

这里有一些不管互用性场景如何您都应该用 JNBridgePro 实现的一些最佳实践。 性能相关的最佳实践包括提高通讯通道速度,或者减少平台间往返行程的数量,因此明显改善了应用程序的执行速度。

升级到 1.3 版

如果您使用 JNBridgePro 1.2 版或者更早的版本,您应该考虑升级到 1.3 版,尤其是如果您的 .NET Framework 和 Java 组件驻留在不同的计算机上。 当在网络上使用二进制通讯连接时,1.3 版或更新的版本提供了重大的性能改进。 一些实现证明访问 EJB 的时间从 200 毫秒降低到 2.3 毫秒。

除了网络通讯性能的改进之外,1.3 版还支持值对象和直接映射集合,这两者都可以改善性能。

为了利用这些改进,下载和安装 1.3 版并且使用 1.3 版代理产生工具重新产生您的代理。 在您的应用程序中用 1.3 版文件替换老版本的 Jnbshare.dll 和 Jnbcore.jar。

使用二进制通讯协议

二进制/TCP 通讯比 SOAP/HTTP 快一个数量级以上。 只有用 Internet 链接 .NET Framework 和 Java 方并且通讯路径穿越防火墙时使用 SOAP/HTTP。

为使用二进制/TCP 通讯通道,确保在 Jnbproxy.config 远程处理配置文件中的设置使用 JTCP: 协议而不是 HTTP:协议。 而且将 Java 方配置文件 Jnbcore.properties 的 servertype 属性设置为 TCP,而不是 HTTP。

把 Java 方组件放在 J2EE 应用程序服务器内。

如果您使用 JNBridgePro 访问运行在一个 J2EE 应用程序服务器内的 EJB,则在应用程序服务器内部署 JNBridgePro Java 方。 这些组件由包含 Jnbcore.jar 的 WAR 文件、包含 EJB 存根的 JAR 文件及相关的配置文件组成。 图 4.6 适当地说明了这种情况。

j2ee_interop_c4_fig4-6

图 4.6: J2EE 应用程序服务器中的 Java 方组件

这样的安排确保执行 EJB 调用的 Jnbcore.jar 绕过 RMI 并且直接调用 EJB。

在同一计算机上放置 Java 方和 .NET Framework 方组件。

如果一个单个的 .NET Framework 客户端访问 Java 类,如果可能的话,在 .NET Framework 方组件所在的同一计算机上放置包括 Java 类的 Java 方组件。 这最小化了通讯的开销。 图 4.7 说明了这样的操作过程。

j2ee_interop_c4_fig4-7

图 4.7: 运行 .NET Framework 组件的计算机上的 Java 方组件

增加任何往返行程时间和通讯链接的滞后时间都会影响平台接口的整体响应性。

减少往返行程

改善 JNBridgePro 性能的最好方法之一是通过减少对代理的调用次数以减少 .NET Framework 方和 Java 方之间的往返行程数。 如何做到这点的一个示例是这样的:为获得信息,何时一些代理调用是必需的,而这一时间取决于根据计算得出的另一个值。 为了减少代理调用数量,创建一个 Java 外观类以执行调用、做计算和返回值。 然后为这个类创建代理。 这个值现在可以通过一次代理调用得到。

实现返回数组

JNBridgePro 对 Java API 提供完全的访问,因此使用全部 API 功能是个巨大的诱惑。 例如,如果您有一个 Java 方的 Vector 对象,您应该从这个向量中提取一个数组并且通过值返回那个数组。 .NET Framework 然后在本地表示那个数组,这就省去了利用迭代来进一步从原始 Vector 对象中提取值的过程。

某些 Java API 支持 stateful 对象,您可能希望重复调用此对象以获得额外的信息。 例如 JDBC 类 ResultSet 表示查询结果并且可以包含多个行,需要滚动来查看这些行。 此外,这可能导致对 ResultSet 的多次往返调用。

为改善性能,创建 Java 包装类以便返回一个对象数组,其中的每个对象包含一行结果。 如果结果数组可能非常大,并且返回它的全部内容将耗费很长时间,可以修改这个包装类以便每次返回有限数量的结果(例如,不超过 50 个)。

使用值对象

默认情况下从 .NET Framework 到 Java 的对象调用设置是通过引用传递 (PBR) 结果。 被调用的对象在 Java 方保存,并且只有该对象的引用返回给 .NET Framework。 引用比真实对象小得多,有助于提升性能,但它们提取任何有用的信息都要回到 Java 方。 甚至得到一个字段值都需要一次往返调用以获得数据。 如果为获取数据对对象的字段执行多次查询或者用访问器方法以在一个 EJB 上查询数据,您最好把那个类的对象指定为值对象

一个值对象是来自 Java 方的对象的快照然后复制回 .NET Framework 方。 取决于值对象的种类,既复制它的公共字段的值,也在 Java Bean 值对象的情况下复制它的 accessor (get) 方法的值。 此过程并不复制 Java Bean 值对象的除 get方法之外的对象方法,因为自动地将 Java 方法的含义转换为 .NET Framework 存在问题。

当对象实际上只是一大堆要用许多不同的方法访问的数据时,请考虑使用值对象。 例如,一个描绘客户银行帐户的对象可能有客户帐户号、名字、姓、地址、当前余额、历次余额和帐户所有人的开户日期这些字段。

默认的设置是通过引用传递的帐户对象 userAcct ,以致访问 userAcct 的每个字段都导致产生一个往返行程。 然而,如果您将 Account 设置为通过值传递,则将从 Java 方向 .NET 方复制 userAcct 的数据并且随后的每次字段访问都是本地调用。

通过值或者引用传递一个对象是否可取取决于对象的大小和您要访问的数据的多少。 例如,在银行帐户例子中,如果在帐户中您要访问的唯一数据是当前余额,则可能通过值传递这个对象是不值得的。 在这种情况下,花在复制所有数据到 .NET Framework 方的时间超过使所有字段访问都在 .NET Framework 本地进行所节约的时间。

不管对象通过值传递还是引用传递,代码是一样的,唯一不同点是这个对象的类被指定为值对象还是引用对象。 理想情况下,按值还是按引用传递对象取决于在试验环境下的观测度量值,而不是开发人员的判断。

单独的对象不能被指定为按值或者按引用传递,给定类的所有对象都需要指定。

有关 JNBridgePro 中关于值对象和引用对象的更多信息,请参阅 JNBridgePro 用户指南。

使用直接映射集合

直接映射集合从 Java 方返回某些对象的集合,并且自动将它们转换为 Java 方的本机 .NET Framework 集合。 在转换之后,您随即可以快速访问这些元素而无需往返调用。

JNBridgePro 支持多种直接映射集合。 Java Vector、数组列表、链接列表和哈希集合直接映射为 .NET Framework 数组列表。 Java 哈希表和哈希映射映射为 .NET Framework 哈希表。 您也可以使用直接映射集合从 .NET Framework 到 Java 传递参数。 有关更多信息,请参阅 JNBridge 用户指南。

像值对象一样,直接映射集合在 Java 和 .NET Framework 之间传递花的时间比引用对象长,但您随后可以更快地访问它们的元素。 确定是否使用一个直接映射集合取决于被传输的集合的大小、访问的次数和频率及试验环境中的测试。

每个公开的类产生一个同名的代理。 产生的代理成员(包括构造函数、方法和字段)对应于作为代理基础的 Java 类的成员。

产生所有支持的代理

当产生代理时,为每个特别请求的代理类产生所有的支持代理。 经常可能省略产生支持代理(如所有参数、返回值、抛出的异常、实现的接口和超类的类的代理),然而,产生这些支持类决不会有害而不产生却可能有害。 此外,为支持类创建代理确保您可以调用那些需要额外类代理的方法和访问它们的字段,而无需重新产生代理程序集。

不产生所有的支持代理的一个额外问题是在一些情况下,如果您不那样做应用程序抛出一个异常。

取决于原始的种子代理集合一方,产生所有支持代理为原始集合增加大约 200 到 300 个额外代理类。 通常产生额外代理所花费的时间不超过五分钟。

注意有可能在许多情况下避免产生支持类。 然而,产生这样的类绝没有害处,并且这样做在将来可以避免由于缺少支持类所带来的各种问题(尽管缺少支持类现在没有产生问题)。

连接 Web 服务

在前面的部分中,您了解了如何用 .NET 远程处理,通过运行时桥连接 Java 平台和 .NET Framework。 然而,.NET 远程处理和 .NET Framework 紧密相关并且您可能需要一个与平台无关的互用性解决方案。

目前在计算机业界 Web 服务得到广泛关注,并且 Web 服务对互用性解决方案的一部分提供了其他选择。 Web 服务是什么和它们提供了什么还是值得关注的。

Web 服务的高级别定义是一个可通过标准的 Internet 协议访问的可编程应用程序组件。 还存在许多更详细的 Web 服务的定义,并且在描述中看来它们都包含下列元素:

Web 服务通过标准的 Internet 协议提供有用的功能。 大多数情况下,这个协议是 HTTP 上的 SOAP。

Web 服务极其详细地描述了它们的接口以便用户构建一个客户端应用程序并与它们对话。 一个名为 Web 服务描述语言 (WSDL) 文档的 XML 文档包含这些描述。

用户可以以某种形式的注册表数据库搜索可用的 Web 服务。 通用描述、发现和集成 (UDDI) 是实现它的最常见的方法。

因为 Web 服务是基于标准和平台无关的,所以用它来使不同平台上的应用程序互相交互是再合适不过了。 这部分解释了为何这么多的供应商如此迅速地承认了 Web 服务标准。 从这本书的角度看,Web 服务可以为连接 .NET Framework和 J2EE 提供有用的机制。 Web 服务专门解决了三个主要的互用性问题:

协议标准 HTTP 和 HTTPS 是最常见的实现,但 Web 服务可灵活地使用任何传输协议。

类型定义 Web 服务总是公开强类型数据,因此如果一个 Web 服务公开一个类型,那么另一个 Web 服务可以理解和使用那个数据类型而不管底层的语言或者平台是什么。

多层支持 在任何平台用任何语言实现 Web 服务和使用任意供应商的工具包的能力,因此一个使用者不需要清楚一个特定的服务运行的平台。

.NET Framework 和 Java 提供 Web 服务的实现,这是通过在不同层次与底层平台进行集成实现的。 事实上,.NET Framework 的一个核心原则是和 Web 服务的高度集成。 Web 服务非常适合在 Internet 上提供各种各样的服务,并且它们对企业应用程序集成来说是一种前途光明的技术。

然而,虽然 Web 服务提供了一种非常强大的技术,但是它们并不适用于所有应用程序和互用性场合。 因为 SOAP 是基于文本的,Web 服务调用对需要频繁、快速和细粒度通讯的应用程序来说可能太慢了。

像 Web 服务这样的面向服务的接口也不适合传统的面向对象的模型。 尽管您可能认为一个服务就是一个永久的服务器激活对象、客户端激活对象(如 new 运算符所构造的对象),然而对静态方法的访问请求通常并不支持。 类似的,如果您的应用程序需要访问各种各样的对象和类,用一个 Web 服务通常是不合适的。 此外,如果您需要从 .NET Framework 链接到 Java API 的丰富的面向对象的集合,则 Web 服务可能不是合适的解决方案。

除了前面说的问题之外,Web 服务与本地面向对象体系结构支持回调的方式不同。 最后,通过一个 Web 服务将丰富的自定义 Java 对象返回到 .NET Framework 可能产生问题。 这种情况下,考虑 Web 服务的替代方案,如 JNBridgePro 和 Ja.NET。

理解 Web 服务

在一个典型的 Web 服务场景中,一个客户端应用程序可以通过查询这个服务的 WSDL 文件了解一个 Web 服务提供什么功能及了解如何调用它的功能。 接下来,客户端使用 HTTP 之上的 SOAP 协议给给定的 URL 上的服务发送一个请求。 服务器接收请求,处理它,并且返回一个响应。 请求和响应使用 SOAP 协议进行了 XML 格式化。

支持 Web 服务的协议和规范(或“stack”)是值得进行一番考察的。 “Web services stack”由 5 层构成,如图 4.8 所示:

j2ee_interop_c4_fig4-8

图 4.8: “Web services stack”的五层模型

这些层由以下元素构成:

传输 (HTTP)

编码 (XML)

标准结构 (SOAP)

说明 (萨WSDL)

发现 (UDDI)

接下来的章节描述每种元素。

传输 (HTTP)

在最底层,分布式体系结构的两个组件必须遵从公共的传输机制。 因为 80 端口以很小的风险通过防火墙几乎被所有人接受,所以 HTTP 成为传输层的标准。 然而,Web 服务实现可以运行在其他传输协议上(如 FTP 和 SMTP),或者甚至可以是其他的网络堆栈(如顺序数据包交换 (SPX) 或者非路由协议(如 NetBEUI)。 在目前规范之内改变对 HTTP 或 HTTPS 的依赖性(用于加密连接)是可能的。

编码 (XML)

在传输层上达成一致之后,组件必须传递正确的 XML 格式文档的消息。 XML 依赖性确保了传输的成功,因为供求双方都知道分析和解释 XML 标准。

标准结构 (SOAP)

虽然 XML 定义了消息编码,但是它并没有涉及文档本身的结构和格式。 为了保证互用性,供求双方都必须知道发送什么和期望得到什么。 SOAP 是轻量级的,建立在 XML(XSD 版本 2)和标准 Internet 协议(如 HTTP 和 SMTP)上的基于消息的协议。 SOAP 协议规范为消息(SOAP 信封)、数据类型定义和实现远程过程调用的一套约定及返回数据的任何格式(SOAP 正文)定义了一个 XML 结构。

说明 (WSDL)

说明层提供了一种机制以通知有关各方 Web 服务提供的各种特殊服务。 Web 服务描述语言 (WSDL) 提供了这个协定,阐明了每个公开的组件:

组件名

数据类型

方法

参数

WDSL 描述允许远程组件的开发人员查询 Web 服务、找出这个服务可以做什么及如何让它这样做。 WSDL 文件是一种基于 XSD 的 XML 文档,它定义了 Web 服务的细节。 它还存储您的 Web 服务协定。 WSDL 文件通常是连接您的 Web 服务的任何客户端的第一个入口点,以便客户端知道如何用它。

发现 (UDDI)

发现尝试回答“在哪里”的问题。 如果您要在某个 Internet 位置上连接一个 Web 服务(例如,www.nwtraders.msft/services/WeatherService.aspx),您可以手动输入 URL。 然而,URL 有些难以操作并且对用户来说不十分友好,因此如果只请求 NWTraders 气象 Web 服务就更好了。 为了这样做,NWTraders 可以在一个通用描述、发现和集成服务 (UDDI) 服务器上发布其气象服务。 找到气象服务现在只要通过使用一种已经获准的消息格式连接到 UDDI 服务器、以定位服务的 URL 就可以了。

图 4.9 说明了一个典型的 Web 服务的基本架构元素如何在一起协作。

j2ee_interop_c4_fig4-9

图 4.9: 来自一个 Web 服务的典型架构元素

现在您理解了 Web 服务的各个部分,作一个更精确的定义就更容易了。 因此,一个 Web 服务是一个执行以下任务的应用程序组件:

使用开放协议通讯(如 HTTP 和 SMTP)。

处理用 SOAP 组帧的 XML 消息。

通过 XML 架构描述它的消息。

使用 WSDL 提供一个服务描述。

通过 UDDI 支持发现。

Web 服务互用性组织。

Web 服务依赖的协议是平台无关的。 这意味着不同应用程序平台间的 Web 服务的互用性应该是自动的。 不幸的是,不一定是这样。

尽管大多数协议是公认的规范,还是有许多 Web 服务草案标准尚未被任何公共的 Web 标准组织(如 WWW 联合会 (W3C) 或结构化信息标准促进组织 (OASIS)}完全认可。 所以许多供应商有它们自己的规范实现一点不奇怪。 所产生的后果是不同供应商之间的 Web 服务的互用性无法保证。

因为许多供应商对 Web 服务如此热心,成立一个独立的组织专注于提供方向和维护标准变得非常紧迫。 没有这样的组织,确保 Web 服务实现真正互用是不可能的。 这个需要催生了 Web 服务互用性组织 (WS-I)。 初始的成员是 170 个,有供应商、企业客户、系统集成商和独立人士一起工作以定义 Web 服务的实现。

任何希望投身于支持和推动 Web 服务互用性事业的组织或个人都可以加入 WS-I。WS-I 面向开发人员,并在以下方面提供一个框架和指导方针:

配置文件 鈥_ 这些 是定义技术标准的规范。

例子 这些例子突出了互用性概念并且说明了配置文件的功能。

实现准则这些实现准则 说明了设计要求与 Web 服务实现互用性的解决方案的最佳实践方法。

工具这些工具包括一个探测器和分析器以监视和记录 Web 服务的交互,包括识别不满足配置文件准则的实现的错误和警告。

有关 WS-I 的更多信息,请参考 Web 服务互用性组织 Web 站点 (http://www.ws-i.org/)。

实现 Web 服务的 Basic Profile

迄今为止最重要的来自 WS-I 的出版物是 Basic Profile1.0。 这个 profile 提供了一组命名的 Web 服务规范,及实现每个标准的一系列建议。 Basic Profile 1.0 涉及四个领域:

消息处理 (HTTP, XML 1.0, XSD 1.0, SOAP 1.1)

说明 (WSDL 1.1)

发现 (UDDI 2.0)

安全性 (HTTPS)

WS-I 并不管理 Basic Profile 1.0 内的各规范,因此它只是作为用于 Web 服务的统一的中间规范。 XBikes 示例应用程序并不完全支持 WS-I Basic Profile 1.0。

实现 Web 服务

在 .NET Framework 上实现 Web 服务和在 J2EE 平台上实现 Web 服务是不同的过程,这是由于各自提供的支持层次不同。 因为 .NET Framework 包括对 Web 服务的内置支持,您不需要任何额外的组件。 Visual Studio .NET 允许从一个项目模板创建 Web 服务实现。 使用 J2EE,您目前需要添加一个第三方 Web 服务实现。

无论您在 .NET Framework 或 Java 上实现 Web 服务,都存在一些公共架构元素,如图 4.9 所示。

实现 Web 服务的两个主要步骤为:

创建 Web 服务。

创建 Web 服务客户端。

下两节将介绍在两个平台上如何执行这两个任务。

在 .NET Framework 上创建 Web 服务

Web 服务紧密地和 .NET Framework 集成在一起。 这使得用 Visual Studio.NET IDE 在 .NET Framework 中设计和创建一个 Web 服务非常容易。 .NET Web 服务实现使用与 ASP.NET 同样的页面框架,由以下部分构成:

一个可寻址的 Web 服务入口点(.asmx 文件)。

实现 Web 服务功能的代码(通常保存在一个 .asmx 代码隐藏文件中)。

为使用 Visual Studio.NET 创建 Web 服务,您的开发人员工作站需要访问配置用于 ASP.NET 应用程序的 Web 服务器。 如果您的服务器运行 Windows Server 2003 的某个版本,您必须从“应用程序服务器”选项安装 IIS 并且包括对 ASP.NET 应用程序的支持。

Windows Server 2003 系列的默认安装不包含 IIS。 这不同于 Windows 2000。

Visual Studio .NET 允许您用 Web 服务项目模板以任何受支持的 Visual Studio 语言创建 ASP.NET Web 服务项目。 您在 Visual Studio 中创建 Web 服务项目之后,组件设计器出现了。 组件设计器是 Web 服务的设计界面。 您可以使用设计视图向 Web 服务添加组件,并且用代码视图查看和编辑相关的代码。

当您在 Visual Studio 上创建一个 ASP.NET Web 服务项目时,它在一个 Web 服务器上构建一个 Web 应用程序项目结构并且在本地计算机上创建一个 Visual Studio 解决方案文件。 解决方案文件 (.sln) 包含配置和编译设置,并保留和项目相关的文件列表。 此外,Visual Studio 自动创建支持 Web 服务的必需的文件和引用。 当完成后,VisualStudo 在设计视图中显示 .asmx 文件。

默认情况下,使用某一种 ASP.NET Web 服务项目模板创建 Web 服务时,Visual Studio 使用代码隐藏文件,如 Service1.asmx.vb(对于 Visual Basic)或 Service1.asmx.cs(对于 C#)。 代码隐藏文件包含实现 Web 服务功能的代码。 在这个文件中,您实现了希望 Web 服务提供的方法。

默认情况下,解决方案资源管理器隐藏了代码隐藏文件。 当您在代码视图中查看 .asmx 文件时,您看到了此代码隐藏文件的内容。 .asmx 文件本身包含处理指令 WebService,它指示在哪里找到 XML Web 服务的实现。

您实现 Web 服务的功能的方式和您在 .NET Framework 中用任何其他类实现 Web 服务的功能的方式一样。 为使一个方法在 Web 服务中可用,您在该方法的 public 声明之前用 [WebMethod] 属性标记该方法。 Private 方法无法充当 Web 服务的入口点,尽管这些方法可以在同一个类中且 Web 服务代码可调用这些方法。

当您构建一个 Web 服务时,ASP.NET 自动提供基础结构并控制 Web 服务请求和响应的处理,包括 SOAP 消息的分析和创建。 编译后的输出是一个 .dll 文件,它位于项目的 Bin 文件夹中。

本书的第 7 章和第 8 章展示了如何在 .NET Framework 中将 Web 服务作为 XBikes 示例应用程序的一部分实现的详细示例。 有关 Web 服务的额外阅读材料,请参阅本章末尾的“参考”部分。

将一个现有的类公开为一个 Web 服务

一个常见的场景是您要将一个现有的 .NET Framework 类的功能公开为一个 Web 服务以便其他应用程序(如 Java 应用程序)可以访问它。 为了这样做,您可以创建一个新的 Web 服务,该服务充当现有类的服务接口。 新的 Web 服务应实现与现有类的接口相同的接口,这样该服务的每个方法只是调用现有类的方法即可。 该解决方案被称为服务接口 模式。

有关服务接口模式的更多信息,请参阅本章末尾的“参考”部分。

Windows Server 2003 的组件服务可以使用内置的 SOAP 激活功能通过一个 SOAP 终结点公开 ServicedComponent,然后您可以通过一个 WSDL 文档访问 ServicedComponent。 SOAP 激活包括通过 IIS 自动产生和承载一个 SOAP 终结点。 这个 SOAP 终结点然后可以通过 HTTP 接受 SOAP 请求。

因为您可通过 WSDL 文档访问此 SOAP 终结点,有人会说此文档是一个 Web 服务。 遗憾的是,情况可能不会始终如此,因为尽管您使用 SOAP、HTTP 和 WSDL 生成终结点,但从 SOAP 激活生成的 WSDL 文档不是 XSD 兼容的,该文档包含特定于 .NET 远程处理的数据类型。

只有理解 .NET 远程处理的客户端可访问 SOAP 激活的 ServicedComponents。 所以,默认情况下,非 .NET Framework Web 服务的客户端无法进行连接。 为了克服这一点,您可以做以下的事情:

使用安装了运行时桥的 Java 客户端使用任何从 ServicedComponent's SOAP 终结点公开的方法。 它能工作的原因是运行时桥理解 .NET 远程处理。

创建一个新的 Web 服务以接受传入 Web 服务请求并且将它们传递到 ServicedComponent,就像本章前面所描述的服务接口模式那样。

无论您选择了哪种技术,您现在应具有一个可以使用的 Web 服务,然后就可以考虑创建客户端应用程序了。

创建Web 服务客户端

在您创建了您的 Web 服务之后,您需要有客户端应用程序以访问它。 这有几种方法去做,取决于您的 Web 服务支持的协议。

如果您的 Web 服务支持 HTTP-GET 协议,则您可以从一个 Web 浏览器来访问它。 默认情况下,用 ASP.NET Web 服务项目模板在 Visual Studio 中创建的 Web 服务支持 HTTP-GETHTTP-POSTHTTP-SOAP 命令。

WS-I Basic Profile 1.0 不支持 HTTP-GETHTTP-POST 协议。 建议您禁用 HTTP-GETHTTP-POST 以使 Web 服务与 WS-I?Basic Profile 1.0 兼容。

当您不知道如何生成一个 Web 服务时,.NET Framework 可提供两种帮助技术。 直接从浏览器不带参数调用 Web 服务的 .asmx 文件将生成一个帮助页面,如下例所示。http://localhost/WebService1/Service1.asmx其他发现关于 Web 服务的信息的方法是查询其 WSDL 属性。 您可以用“WSDL”作为附加的参数通过从浏览器直接调用 Web 服务的 .asmx 文件来进行查询。http://localhost/WebService1/Service1.asmx?WSDL这些内置的帮助系统可以在创建 Web 服务客户端的设计和调试阶段帮助您。

实现 .NET Framework Web 服务客户端

Web 服务客户端是使用和引用 Web 服务的任何组件或者应用程序。 Web 服务客户端不必是一个基于客户端的应用程序,在许多情况下,Web 服务客户端可能是其他的 Web 应用程序,如 Web 窗体或甚至是其他的 Web 服务。

当用托管代码访问 Web 服务时,一个代理类和 .NET Framework 处理所有的基础结构编码。 代理类实现接口 Web 服务的接口并且处理所有 Web 服务客户端和 Web 服务间的通讯。 图 4.10 说明了代理类、Web 服务客户端和 Web 服务本身的关系。

j2ee_interop_c4_fig4-10

图 4.10: Web 服务客户端用一个代理类和 Web 服务通讯

您可以手动创建和管理代理类,或者您可以让 Visual Studio .NET 通过自动化的 Web 引用功能为您管理它们。 建议采用 Web 引用的方法。

从 Visual Studio .NET 的托管代码中访问 Web 服务

1.

为您要访问的 Web 服务向项目添加一个 Web 引用。 Web 引用用充当 Web 服务的各个公开的方法的代理的方法创建代理类。

2.

为 Web 引用添加命名空间。

3.

创建一个代理类的实例,然后就像访问任何其他类的方法一样访问那个类的方法。

在您建立了这个项目之后,然后您应该能够访问引用的 Web 服务。

定位一个 XML Web 服务并且添加一个 Web 引用

有时候您可能既是 Web 服务的提供者也是使用者。 在这种情况下,您可能知道 Web 服务的位置和功能。 在其他时候,您可能访问别人提供的 Web 服务。 当这种情况发生时,您可能甚至不知道适合您使用的 Web 服务是否实际存在。

为了简化编码模型,以托管代码编写的应用程序用 Web 引用在本地表示每个 Web 服务。 您用 Add Web Reference 对话框将一个 Web 引用添加到您的项目中。 要访问 Add Web Reference 对话框,右键单击 Visual Studio .NET 的解决方案资源管理器中的 Web References 文件夹,然后单击 Add Web Reference。 这个对话框使您可以浏览本地服务器、Microsoft UDDI 目录和 Internet 以查找 Web 服务。

Add Web Reference 对话框使用 Web 服务发现处理来查找您在对话框中导航到的 Web 站点上适当的 Web 服务。 对一个特定的地址来说,它通过使用一个专用于查找 Web 服务发现 (DISCO) 文档、最后查找符合 Web 服务描述语言 (WSDL) 语法的 Web 服务描述文档的算法来查询 Web 站点。

产生一个代理类

在您使用 Add Web Reference 对话框定位 Web 服务以便您的应用程序进行访问之后,单击按钮 Add Reference 指示 Visual Studio 将一个服务描述的副本下载到本地计算机,然后产生一个代理类访问选中的 Web 服务。 代理类包含同步和异步调用每个公开的 Web 服务方法的方法。

这种技术只在运行 Visual Studio 的计算机具有对 Web 服务的访问权限时才能使用。

Visual Studio 在添加一个 Web 引用时使用 Web 服务描述语言工具 (WSDL.exe) 创建代理类,您可以用同样的工具手动产生代理类。 当您不能从安装了 Visual Studio 的计算机上访问 Web 服务时这是必要的,例如当 Web 服务位于网络上而客户端直到运行时才能访问此 Web 服务。 为了手动生成一个代理文件,在命令行提示符下运行 WSDL.exe 并以目标 Web 服务的 WSDL 文件的 URL 作为参数。 然后您可以手动添加工具为您的应用程序项目产生的文件。

使用代理类

产生的代理类有与其相关的自己的命名空间,并且您在可创建一个代理类的实例之前必须将这个命名空间添加到您的客户端应用程序中。 和其他任何类一样,在您能调用它的任何方法之前您必须首先创建它的一个实例。 这个过程和创建任何其他类的实例是相同的。

当使用 Visual Studio 直接从 Web 服务的服务描述中产生的代理类时,以托管代码访问 Web 服务是相对容易的过程。 为了访问一个 Web 服务方法,您的客户端应用程序可调用代理对象相对应的同步方法或异步方法。 这些方法执行必要的工作以远程调用期望的 Web 服务的方法。 默认情况下,代理类使用 SOAP 访问 Web 服务方法,因为 SOAP 支持三种受支持的协议(HTTP-GETHTTP-POSTHTTP-SOAP)的最丰富的数据类型集合。

Add Web Reference 过程产生的代理类从 System.Web.Service.Protocols.SoapHttpClientProtocol 类派生,System.Web.Service.Protocols.SoapHttpClientProtocol 类包含若干属性,您可使用这些属性来控制或自定义此类访问 Web 服务的行为。 有关 SoapHttpClientProtocol 类中可用属性的更多信息,请参阅 .NET Framework SDK。

当您升级 Web 引用时,Visual Studio .NET 自动产生一个新的代理文件。 新文件覆盖老文件,并删除您可能已经添加到原始代理文件的任何自定义部分。 保留一份任何自定义代理文件的备份副本以应对这种可能性。 如果您用 WSDL.exe 工具手动产生一个代理文件这种情况不会发生。

用动态和静态 URL 引用

Web 引用既可以用静态 URL 也可以用动态 URL。 Web Reference URL 属性指定了 Web 服务的位置。 默认情况下,这个属性是您选择的 Web 服务的 URL,这是一个静态 URL。

如果您保留 URL Behavior 属性设置的默认值 Static,则当您创建该类的实例时,硬编码的 URL 设置代理类的 URL 属性。 如果您将 Web 引用的 URL Behavior 属性设置为 Dynamic,则此应用程序在运行时从应用程序配置文件的 节获得 URL。

<appSettings> 
<add key="myApplication.myServer.Service1" value="http://myServer/myXmlWebService/Service1.asmx"/>
 </appSettings> 

当您创建一个代理对象的实例时,您也可以在您的应用程序中编程设置对象的 URL 属性。 不管代理使用哪个 URL,它一定是用于符合 WSDL 的 Web 服务,该服务与添加 Web 引用时所使用的服务相匹配。 否则,您早先生成的代理类将无法使用它。

调用 Web 服务方法

将一个 Web 引用添加到 Web 服务之后,您可以调用 Web 服务公开的方法并且就像您用组件的任何其他方法一样访问结果。

有关如何在 XBikes 示例应用程序中实现这些技术的示例,请参阅第 7 章和第 8 章。

在 J2EE 中创建 Web 服务

在 Java 中实现 Web 服务目前不像在 Microsoft 的 .NET Framework 中实现那么简单。 写本文的时候,最新发布的 J2EE 规范版本是 1.3 版,而 1.4 版目前正在测试中。 在版本 1.3 中,没有 Web 服务的本机实现。 例如,没有 java.webservices 包以便您能用 Java 语法导入和使用。

然而,在 Java 团体内定义和实现 Web 服务有相当大的动力。 Java Community Process 定义以下包含 Web 服务的 Java 规范请求 (JSR):

JSR 109 实现企业 Web 服务

JSR 93 Java API for XML Registries 1.0 (JAXR)

JSR 67用于 XML 消息处理的 Java API

JSR 101用于基于 XML 的 RPC 的 Java API

JSR 109 为 J2EE 体系结构定义 Web 服务。 它使用 J2EE 组件体系结构提供一种熟悉的、可移植的、可伸缩及可互操作的客户端和服务器编程模型。 JSR 109 在 JSR 67、JSR 93 和 JSR 101 基础上构建。

如果一个 Java 供应商的 Web 服务实现是与 JSR-109 兼容的,其他与 JSR-109 兼容的实现应能和该实现互操作。

JSR 93 定义了 Java 应用程序连接 XML 注册表的方法,如 JNDI、ebXML 和 UDDI。 此 JSR 提供机制以便 Web 服务可以公布它们的接口并且客户端应用程序然后可以发现这些接口。

JSR 101 集中处理 XML RPC 和 Java 语言。 这包括以下内容:

描绘 Java 中的基于 XML 的接口定义。

用基于 XML 的接口定义语言(如 SOAP)定义接口。

实现封送处理。

JSR 67 为 XML 消息处理提供了相似的定义。

Java Web Services Stack

目前,Java 平台上的 Web 服务支持需要 Web Services Stack,可从中选择 Web 服务。 最常用的实现是以下这些实现:

Apache Axis 是来自 Apache Software Foundation 的开放源码的 Web 服务实现。

IBM 有几个 Web services stack 可以使用,如 WebSphere Application Server、Web Services Developer Kit (WSDK) 和 Emerging Technologies Toolkit (ETTK)。 IBM 还提供 UDDI 注册表和服务器产品。

来自 Systinet 的 WASP 同时为 C/C++ 和 Java 环境提供 Web services stack。 Systinet 还提供独立的 UDDI 服务器。

来自 Mind Electric 的 GLUE 是一个流行的 Web services stack。 Mind Electric(最近被 webMethods, Inc. 并购)也提供 UDDI 服务器。

来自 BEA 的 WebLogic 应用程序服务器也有一个 Web services stack。

究竟选择哪个 Web stack 的决策可能反映了组织的喜好及技术要求。

在 Java 中创建 Web 服务

在 Java 上创建 Web 服务取决于您选择的 Web services stack,并且在某种程度上,还取决于您使用的 Java IDE。 所有供应商在他们的文档上都提供了有关如何建立 Web 服务的教程。 然而,建立 Web 服务的主要步骤是一致的。

首先,您需要确定您要公开哪个功能。 有了这个信息,您需要创建一个新类公开这个功能或标识已经可以做这项工作的现有的类。 许多 Web services stack 允许您将现有的类或者 EJB 公开为 Web 服务。 从架构的观点看,您应该创建一个新类,即使它只是调用一个现有的类。 这对防止应用程序被修改提供了某种保护。

在您确定您要公开的类之后,您必须配置您的 Web services stack 来公开这个类。 大多数 Java Web 服务实现作为 servlet 运行在应用程序服务器内部。

某些 stack,如 GLUF 和 WASP,如果一个应用程序服务器不可用它们可提供自己的容器。

您可用各种配置文件配置这些 servlet。 为了部署一个 Web 服务,您只需修改这些配置文件。 许多供应商也使用 API 提供动态公开 Web 服务的方法,但这种硬编码应该被避免。

例如,GLUE 要求您为 Web 服务创建一个 XML 配置文件。 为了公开这个 Web 服务,您只要将您的类添加到这个配置文件中。 当 GLUE servlet 基于类加载和创建适当的 WSDL 和架构文档时,GLUE servlet 分析这个文件。

有关如何使用 GLUE 创建 Web 服务的更多信息,请参阅 GLUE?文档。 第 7 章“在表示层集成 .NET”中的 XBikes 示例应用程序提供了实现用于互用性的 Web 服务的一个例子。

在 Java 中使用 Web 服务

尽管有许多不同的 Java Web 服务供应商,但在几乎所有的供应商实现中使用 Web 服务是一个相当简单的任务。 您可以使用一个名为 WSDL2Java 的工具处理本地或远程 WSDL 文档,这随后创建了一个 Java 代理实现。 这是一个和 .NET Framework 使用 Web 服务相似的方法,除了 Java 工具只是创建一个接口而不是一个实际的类。 WSDL2Java 通常创建一个帮助器类,它创建一个基于 URL 终结点的对象。 这个对象实现 WSDL2Java 创建的接口,您随后可以在您的客户端应用程序中使用它。

第 7 章和第 8 章提供在 Java 平台使用 Web 服务的例子。

保护 Web 服务

在产品环境中运行的应用程序通常需要某种形式的身份验证和授权。 这可以跟踪服务的多个用户并使每个用户的数据独立于其他用户。

实现身份验证最简单的方法是使用 HTTP 内置的基础结构,以向 Web 服务提供用户名、密码和域。 从 .NET Framework 发布的 Web 服务可以使用 HTTP 身份验证。 尽管这标识了一个用户,它并不安全,这是因为 HTTP 包无法避免侦听。 使用明文发送用户名和密码的这种基本的身份验证,让电子监听者识别用户名和密码成为可能。

更高级的身份验证方法如 Kerberos、NTLM 或者 Digest 提供加密的身份验证方法,但这些方法只为身份验证过程本身提供加密。 您的 Web 服务实现可能需要将加密应用于所有的客户端到服务器的事务的完全安全的处理。 要这样做,您可以从这些方法中选择一个:

传输层安全。

应用程序层安全。

Web 服务安全 (WS-Security)。

传输层安全如 HTTPS 上的安全套接字层 (SSL) 加密工作在协议层,并且在单个 Web 服务调用的开始点和结束点之间加密所有的包。 这从客户端(例如,一个表示层的 ASP.NET 应用程序)到业务层的 Web 服务都工作得很好。 在包到达业务层(SSL 的终点)之后,业务层 Web 服务对这些包进行解密。

您要让这些包直到它们到达存储用户名和密码的数据库层一直保持加密状态,存在着一个问题。 因为 SSL 是一个点对点的加密方法,所以它不适用于让您的数据在多层环境内越过多次 Web 服务调用而一直保持数据加密。

应用程序层安全包括开发某种自定义安全实现。 虽然这种技术可以通过提供端对端加密避免使用 SSL 产生的点对点问题,但是它需要进行只适用于实现该自定义安全实现的客户端的编码工作。 在 Web 服务中,这与提高可访问性的思想背道而驰。

第三种选择 WS-Security 使用发布的规范提供应用程序层安全。 只要客户端理解 WS-Security,它们就可以安全地连接到 Web 服务。

WS-Security 为安全令牌定义了 XML 结构,客户端使用这些安全令牌作为身份识别的证据。 WS-Security 令牌通常包括一个用户名、二进制数字和安全令牌引用。 WS-Security 使用标准组件,如 X.509 证书,来认可客户端的身份。 WS-Security 也提供加密,可包括对 SOAP 消息正文、消息头的加密,或对两者同时加密。

您通过策略文件控制 WS-Security 设置,这个策略文件是一个扩展文件名为 .wsse 的 XML 文件。 实现 WS-Security 包括创建策略文件和将此文件与 Web 服务相关联。 然后 Web 服务对照这个策略检查传入和传出消息以确保它们符合有效的设置。

为了访问一个安全的 Web 服务,您创建一个安全策略文件并且将此文件与 Web 服务控件相关联。 客户端策略设置必须和服务器端的策略设置匹配。

虽然 WS-Security 标准没有完全被批准,但是一些供应商已经产生了他们自己的实现,包括以下产品:

WSE Microsoft 的 Web Services Enhancements。

IBM 的 IBM Web Services Toolkit。

BEA Systems 的 Weblogic Workshop。

有关实现 WS-Security 和 WSE 的更多信息,请参阅本章末尾的“参考”部分。

使用通用描述、发现和集成

UDDI 是一个发布和定位 Web 服务的标准规范。 为了实现 UDDI,安装一个 UDDI 服务器,然后向服务注册 Web 服务 URL 和描述。 您可以把 UDDI 想像成类似 Internet Locator Services (ILS),但处理的对象是 Web 服务而不是人。 像 ILS 一样,UDDI 服务器可以作为公共的(一个 UDDI 业务注册表或者 UBR)、私有的(基于 intranet 的)或者半私有的,在商业合作伙伴之间使用。 您也可以把 UBR 服务器比喻成电话号码簿,白页按名称列出公司,黄页按照功能对公司分组,绿页描述它们提供的服务。

UDDI 克服了一个简单的 URL 缺乏启发意义这一问题。 例如,它没有告诉您关于所提供的服务的详细信息。 而且,URL 有一个变成其他 URL 的特性,这阻止了客户端进行连接。 UDDI 使用一个发布和订阅模型以支持连接 Web 服务的一致性,使之与 URL 字符串的变化无关。

UDDI 目录数据库存储 URL 或者访问点,使它们与所提供的服务和涉及的业务相关联。 业务信息可以包括联系人详细信息和业务经营所涉及的市场部分,支持灵活和高效的搜索。

主要的 IT 供应商如 Microsoft、IBM、SAP、Veritas和 NTT UDDI 参加了 UDDI 倡议,现在的版本是 3.0。 这五个供应商还维护公共 UBR 注册表。 有关 UDDI 的更多信息,包括白皮书和最佳实践的详细信息,请参阅 UDDI Web 站点 (http://www.uddi.org/)。

使用 UDDI 的互用性的好处

UDDI 为涉及 Web 服务的互用性项目提供了极大好处。 任何需要动态查找所提供服务的 Java 或者 .NET Framework 客户端可以充分利用 UDDI。 其他好处包括如下几个:

公共 Web 服务发行UDDI 提供平台无关的 Web 服务视图。

动态配置 任何客户端应用程序可以用 UDDI 动态配置 Web 服务代理,消除了硬编码 URL 的需要。 此外,动态重新绑定为一个 Web 服务提供多个 URL 实例。 和循环 DNS 相似,如果一个链接没有响应,应用程序可以通过 UDDI 从同一个提供者请求另一个服务实例。

Web 服务重用 大型组织可能有多个部门从事开发项目,经常导致重复提供 Web 服务。 UDDI 允许开发团队浏览整个已经发布的 Web 服务列表,防止各部门将时间和金钱浪费在提供已经存在的服务上。

特定于位置的 Web 服务 通过为一个 Web 服务分配一个位置,使客户端绑定在最近的服务实例上,可以改善性能和减少网络流量。

UDDI 注册表

UDDI 的核心组件是注册表,它允许组织在可用的服务上发布位置信息。 然而,您并没有产品 Web 服务供公共使用,以从 UDDI 中受益。

Microsoft、IBM 和 SAP 主持测试公共注册表,以便允许开发人员测试注册和发布过程。

几个供应商在其最新的操作系统上已经实现了 UDDI 服务:

Microsoft 在 Windows 2003 中包含 UDDI 作为其核心服务

IBM 已经将 UDDI 注册表添加到 WebSphere

Mind Electric 将 UDDI 服务器与 GLUE 打包在一起

如果内部实现 UDDI,检查确保其支持 3.0 标准。

UDDI 将来有希望成为一个主要的增长点并且在实现 Web 服务时可提供极大的好处。 下一部分考虑一些最佳实践的建议以帮助使用 Web 服务和互用性。

实现 Web 服务互用性最佳实践

Web 服务仍然是一种新兴的技术。 Web 服务基于的协议规范是还没有正式批准的标准,因此不同的供应商的实现可能不能彼此互用。 WS-I Basic Profile 将在将来帮助改善 Web 服务互用性。 然而,当您在 .NET Framework 和 Java 之间互用时,为了使您具有实现 Web 服务的最大可能性,请遵照这些最佳实践准则:

首先定义数据类型 如果您计划在 Web 服务上用复杂数据类型,使用第 3 章“互用性基本原理”概述的某些策略从公共 XML 架构设计您的数据类型。

测试您的数据类型在您开始编写您的主要应用程序之前,使用测试应用程序在概念试验的测试中只是来回地传递您的数据类型以证明您的互用性解决方案有效。

尽可能使用简单数据类型 只要您可以实现较简单的数据类型,就要这样做。 只因为合理的业务原因实现复杂数据类型,而不是因为您喜欢这样的挑战。

以 XSD 数据类型为所有数据类型的基础 如果您实现复杂数据类型这点尤其重要。 像在第 3 章“互用性基本原理”中描述的,这确保复杂数据对象中的数据类型映射为 .NET Framework 和 Java 中的数据类型。

在中央存储所有数据类型 当 .NET 和 Java 程序集需要一个单一的 XML 命名空间用于所有的数据类型时,从代理文件中分离数据类型并且把它们存储在独立的位置尤其有用。

符合 WS-I Basic Profile 1.0 如果要使您的服务可公用,则是否符合 WS-I Basic Profile 1.0 是一个最重要的因素。 确保您始终使用 WS-I profile 的新版本和最新修订。

标准化文档/文字的风格,而不是使用包括 SOAP 或 RPC 编码的组合 鈥_ 实现 SOAP 编码将阻止对架构进行验证,而 RPC 编码往往与服务紧密耦合并且是界面驱动的。

WS-I Basic Profile 1.0 积极推广文档/文字风格。

使用最新的 Java Web 服务发行版Java 发行版和相关的工具的领域发展得非常迅速,使用最新的发行版允许您用最新的规范工作,可以提高可靠性及提供一致的互用性。

使用 UDDI 发现 Web 服务 UDDI 是一个强大而有效的方法,它能够发现在一个组织内或作为向公共提供的服务的一部分的 Web 服务。

通过互用性适配器/服务接口模式应用抽象 这使您在不修改调用方逻辑的情况下,为一个 Web 服务调用添加功能。 抽象层可以在业务逻辑和进行调用的 ASP.NET 表示层之间。 实现一个互用性适配器/服务接口模式使 ASP.NET 代码免除额外开销,如从 UDDI 注册表计算 URL。 有关互用性适配器/服务接口模式及实现示例的更多信息,请参阅第 6 章“实现互用性设计元素”。

就像所有最佳实践建议一样,有时您需要实现一个不同的解决方案。 然而,遵照这些准则将有助于使您的多个应用程序在尽可能不相互干扰的情况下一起工作。

比较 .NET 远程处理和 Web 服务

带有运行时桥的 .NET 远程处理和 Web 服务为应用程序平台互用性提供不同的方法,它们可提供指定应用程序组件之间通讯方法的灵活性。 虽然它们有一些相似性,.NET 远程处理和 Web 服务有一些细节上的不同。 表 4.4 概括了它们的异同点。

表 4.4: .NET 远程处理和 Web 服务之间的功能比较
功能 .NET 远程处理 Web 服务

HTTP 通道

checkmark checkmark

HTTP 上的 SOAP

checkmark checkmark

TCP 通道

checkmark x_mark

XML 格式化程序

checkmark checkmark

二进制格式化程序

checkmark x_mark

按值传递

checkmark checkmark

按引用传递

checkmark

难于实现

存储会话状态

容易

更复杂

调用无状态对象上的单个方法

checkmark checkmark

调用状态对象上的多个方法

checkmark x_mark

所有客户端可调用同一服务器端对象上的方法

checkmark x_mark

穿越防火墙

checkmark checkmark

使用 IIS 作为宿主

checkmark checkmark

使用自定义宿主

checkmark x_mark

获取复杂对象的完整副本

checkmark x_mark

因为目前在 Web 服务背后具有相当大的业界动力,自然您可能倾向于实现 Web 服务。 然而,表 4.4 说明 .NET 远程处理在几个方面显示出显著的优点。

因为 .NET 远程处理加入了一个 TCP 通道,所以不再需要 HTML 头。 将其与一个二进制格式化程序相结合通常可在大通讯量下显著地改善性能。

实现按值传递或者按引用传递对两种方法来说都是可以使用的,但是在 Web 服务中实现它们显然更困难。 而且,在 .NET 远程处理中的会话状态管理没有 Web 服务复杂。

.NET 远程处理与 Web 服务相比的其他优势包括如下方面:

互用性受到保证。

支持远程对象的客户端激活和生存期控制(类似于 DCOM)。

支持回调和事件。

支持特定于 .NET Framework 的额外上下文信息。 将来,上述信息将支持额外的功能,如分布式事务和额外安全级别。

支持类型系统的保真,这意味着在类和类型层次结构之间存在一对一映射。 Web 服务和 SOAP 不支持如此的面向对象机制访问远程对象。

在一个紧密耦合的 intranet 环境内、希望高事务处理量和控制通讯的双方时实现 .NET 远程处理。 对具有更松耦合性的系统使用 Web 服务,尤其是那些跨越 Internet 连接时或者您无法控制对话双方的时候。

Web 服务高于 .NET 远程处理的优越性,主要在下列方面:

平台无关性 Web 服务使用开放和常见的标准如 XML、SOAP、HTTP 和 WSDL。 因此,Web 服务提供真正的平台无关性,您可以从任何客户端平台调用 Web 服务,而不管服务器平台或者 Web 服务的实现技术。

安全 IIS 是为 ASP.NET 组件精选的标准宿主,所以使用 ASP.NET 创建的 Web 服务应用程序可以自动利用 IIS 中的安全功能,如支持 Windows 身份验证、安全套接字层 (SSL) 加密和日志记录。 您可以使用 IIS 宿主 .NET 远程处理组件,这样它们可以利用相同的安全机制。 然而,如果您不在 IIS 中宿主您的 .NET 远程处理组件,您必须自己实现身份验证、授权和隐私机制。

缓存 在 IIS 中宿主 ASP.NET 组件还为 Web 服务添加了 IIS 缓存支持。 高效的缓存可以明显地提高 .NET 远程处理的性能优势,这取决于您要缓存的数据类型。 缓存对于重复请求的公共数据最有效,当缓存私有数据或者动态数据时有效性将降低。 .NET?远程处理没有对缓存的内置支持,即使当 IIS 宿主远程处理组件时也是如此。 因此,像安全性那样,您必须手动建立缓存支持。

易于创建 Visual Studio .NET 使创建和使用 Web 服务变得很容易。 要创建一个 Web 服务,需创建一个 ASP.NET Web 服务项目,并实现带有 [WebMethod] 属性的方法。 为了使用 Web 服务,在 Visual Studio .NET 中创建任何类型的项目并且添加一个到您选择的 Web 服务的 Web 引用,Visual Studio .NET 产生一个客户端代理,以简化对 Web 服务的访问。

如果这些因素对您很重要,Web 服务可能是实现点对点互用性的比 .NET 远程处理更好的选择。

小结

本章描述了可提供 .NET Framework 和 Java 间的点对点互用性的方法。 它包括了 .NET 远程处理和您如何能使用运行时桥(如 JNBridgePro 和 Ja.NET)链接 .NET Framework 和 Java。 然后它研究了 Web 服务这一快速发展的领域并且描述新兴的标准(如 UDDI 和XML)如何可简化链接 Java 和 .NET Framework 组件的过程。 在下一章,您将基于消息队列考察互用性技术。

参考资料

有关 XML Web 服务的更多信息,请参阅:

Simon Guest 的 Microsoft .NET and J2EE Interoperability Toolkit, Microsoft Press,ISBN 0-7356-1922-0 一书的第 5、6 章

Scott Short 的 Building XML Web 服务 for the Microsoft .NET Platform, Microsoft Press, ISBN 0-7356-1406-7 一书

有关 JNBridge 的 JNBridgePro 的更多信息,请参阅 http://www.jnbridge.com

有关 JSR 规范的更多信息,请参阅 Java Community Process Web 站点 http://www.jcp.org/en/jsr/all

有关 Apache Axis 的更多信息,请参阅 http://ws.apache.org/axis/

有关 IBM 的 Web 服务实现的信息,请参阅 developerWorks Web 站点 http://www-106.ibm.com/developerworks/webservices/

有关 Systinet 的 Web 服务实现的更多信息,请参阅 http://www.systinet.com/products/wasp_jserver/overview

有关 Mind Electric 的 GLUE 的更多信息,请参阅 http://www.themindelectric.com/

有关 .NET Framework 上的 Web 服务的更多信息,请参阅 http://msdn.microsoft.com/webservices/

有关如何在 .NET Framework 上实现 Web 服务的更多信息,请参阅“Creating XML Web 服务 in Managed Code”http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbconWebServicePublishing.asp

有关 .NET 远程处理的更多信息,请参阅“Microsoft .NET Remoting: A Technical Overview”http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/hawkremoting.asp

有关 .NET 远程处理配置文件的更多信息,请参阅“Format for .NET Remoting Configuration Files”http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/remotingconfig.asp

有关在 IIS 中承载远程对象的更多信息,请参阅“Hosting Remote Objects in Internet Information Services (IIS)”http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconhostingremoteobjectsininternetinformationservicesiis.asp

有关 Web 服务安全性的更多信息,请参阅 Web Services Developer Center 中的“Security”http://msdn.microsoft.com/webservices/building/security/default.aspx

有关实现服务接口的更多信息,请参阅“Enterprise Solution Patterns: Implementing Service Interface in .NET”http://msdn.microsoft.com/practices/type/patterns/enterprise/impserviceinterfaceinnetwasp/

有关实现 WSE 的更多信息,请参阅 MSDN 中的下列文章: “Web Service Enhancements 1.0 and Java Interoperability, Part 1”http://msdn.microsoft.com/webservices/building/wse/default.aspx?pull=/library/en-us/dnwebsrv/html/wsejavainterop.asp

- 和 -

“Web Service Enhancements 1.0 and Java Interoperability, Part 2”http://msdn.microsoft.com/webservices/building/wse/default.aspx?pull=/library/en-us/dnwebsrv/html/wsejavainterop2.asp

有关 IBM 平台上的 UDDI 服务的更多信息,请参阅 IBM Web 站点上的“Understanding UDDI”http://www-106.ibm.com/developerworks/webservices/library/ws-featuddi/#What%20is%20UDDI?

有关 GLUE 的对应信息,请参阅 GLUE UDDI Web 站点 http://www.themindelectric.com/docs/glue/guide/uddi/index.html要在 Windows Server 2003 上安装 UDDI,请参阅 Windows Server 2003 Family Help 中的“Using UDDI Services”主题。

转到原英文页面

0 0

相关博文

我的热门文章

img
取 消
img