内容


通过 BE4WS 聚集 UDDI 搜索

开发者可以利用 BE4WS 极大的简化他们的 Web 服务搜索

Comments

一般情况下,Web 服务会被发布到一个公共的或私有的 UDDI 注册中心。UDDI 的设计允许简单的搜索格式,并允许交易伙伴发布关于自身及其宣传的 Web 服务的数据以自动提供分类数据。通常,UDDI 可以定位那些标识众所周知的企业;用户可以查到那些企业提供的服务,以及如何以电子方式同他们交互。目前的 UDDI 搜索机制只能集中注意力于单一搜索条件,例如,企业名称、企业位置、企业类别或按名服务类型、企业标识符或发现 URL。

从电子商务应用程序开发者的观点来看,最好是把一些顺序型或程序型搜索命令发送到 UDDI 注册中心来聚集信息。潜在的信息源可能包括多个 UDDI 注册中心和其它可搜索数据源。显然,有必要显著扩展 Web 服务目前的搜索功能,从而提高效率、改进性能。

所有现有的 UDDI 搜索引擎只支持单一的 UDDI 注册中心。例如,Microsoft 的 UDDI 搜索技术只允许用户搜索 Microsoft 的 UDDI 注册中心,而且每次搜索只能基于下列分类之一使用一条搜索查询:企业名称、企业位置、企业类别和按名、按企业标识符或发现 URL 的服务类型。已经知道的分类法类型包括 NAICS、UNSPSC、SIC 或地理代码(GEO);已经知道的标识符类型包括 D-U-N-S、托马斯注册号(Thomas Registry number)及美国税号(US Tax ID)。

本文中,我们将介绍新发布的 BE4WS 技术,该技术是基于 XML 的 UDDI 浏览引擎,并为开发者在一个或多个 UDDI 注册中心高效搜索企业和服务信息提供了标准接口。BE4WS 是用 Java 编程语言写的;它利用 UDDI 搜索标记语言(UDDI Search Markup Language,USML)文档中的信息引导 UDDI 客户程序(如 UDDI4J)执行复杂的 UDDI 搜索。您可以用 BE4WS 构建 Java 程序,或者从 servlet 调用它并创建一个 BE4WS Web 应用程序或 Web 服务。

通过 BE4WS,您可以同 UDDI 浏览机制的 XML 表示交互;这一过程取代了会涉及到直接利用 UDDI4J 或其它一些 UDDI 客户程序的通常的编程模型。通过 BE4WS,不论您的底层 UDDI 客户程序是如何实现的,您都可以使用相同的编程模型。

为了使企业应用程序能高效搜索 UDDI 注册中心,我们定义了 UDDI 搜索标记语言(USML;请参阅 参考资料以获得更多信息)。我们还提出了执行搜索过程(请参阅 参考资料)的高级 UDDI 搜索引擎框架。本文中,我们将使用样本 Java 应用程序代码、JSP 代码和 servlet 代码来说明 BE4WS 作为部署在 WebSphere Application Server(WAS)4.0 上的高级 UDDI 搜索门户的用法。但是 BE4WS 也将用于其它应用程序服务器,如 Apache Tomcat。您将看到一些屏幕截图,包括 JSP 页面和 BE4WS SOAP 服务页面。但是,我们要先分析一下 BE4WS 如何利用现有的 UDDI 客户程序,然后分析 BE4WS API。

BE4WS 和 UDDI 客户程序

象 UDDI4J 这样的 UDDI 客户程序提供搜索 UDDI 注册中心的底层 API。BE4WS 提供高级 API 来利用 UDDI4J 或其它客户程序(例如 Web Services Inspection Language(WS-Inspection)搜索工具)、定义基于脚本的搜索请求、聚集搜索结果和同时浏览多个 UDDI 注册中心。例如,BE4WS 中一个 USML 请求可以包括多个查询、不同的 UDDI 数据源和一个聚集操作符。根据搜索条件聚集从不同的 UDDI 注册中心或其它数据源返回的结果。如果您是单独使用 UDDI4J 的,那么您必须自己编写代码向不同的 UDDI 注册中心发出多个搜索查询,并设法自己聚集数据。显然,这是一个很耗时间的过程,高级 UDDI 搜索引擎可以帮助您更好的处理这样的请求。

此外,BE4WS 不仅可以合并不同的 Web 服务发现技术层(例如 UDDI for Java 技术或其它类似的 UDDI 客户程序包),而且还能合并不同的数据源(如标准 UDDI 注册中心、增强的 UDDI 注册中心或者诸如 LDAP 目录、Web 和 Web 服务检查文档(Web Service Inspection document)之类的其它数据源等)。因此,BE4WS 使您能够同 UDDI 浏览机制的 XML 表示交互,而不是直接利用 UDDI for Java 技术以及其它 UDDI 客户程序。通过 BE4WS,不论您的 Web 服务发现客户程序是如何实现的,您都可以使用相同的编程模型。BE4WS 可以作为 UDDI 注册中心以及其它数据源的高效且有效的浏览机制和通用接口标准出现。

BE4WS API

BE4WS为企业应用程序开发者提供了两类 API:常规 Java API 和 Web 服务接口。利用这些 API,任何电子商务应用程序开发者只要使用一个 Java 或 SOAP 调用就可以很容易的从不同的 UDDI 注册中心查找需要的企业实体、服务和服务类型(tModel)。这些调用唯一的输入参数就是 USML 请求串或 USML 文档的位置。返回的结果也是 USML 文档。因此,很容易就可以把 BE4WS 部署为主要的 UDDI 搜索门户。所有授权的电子商务应用程序都可以利用这一服务来浏览多个 UDDI 注册中心的企业和服务信息。

常规 Java API

Java 编程语言类( com.ibm.UDDI.BusinessExplorer.UDDISearch )提供了三个公有函数:

  • public String searchByString(String inputUSMLString) 该函数把一个包含想要的搜索条件的字符串作为输入,返回一个 USML 响应文档。参数 inputUSMLString 是一个 USML 请求串。

  • public String searchByURL(String inputUSML_URL) 该函数把一个包含想要的 USML URL 字符串作为输入,返回一个 USML 响应文档。参数 inputUSML_URL 是适当的 USML 文件的 URL。

  • public String searchByFilename(String inputUSMLFilename) 该函数把一个包含想要的搜索条件的文件作为输入并返回一个 USML 响应文档。参数 inputUSMLFilename 是包含 USML 请求的文件的文件名。

要在您自己的 Java 应用程序中使用这些函数,请按照下面这些步骤:

  1. 创建一个包含全部搜索条件的 USML 脚本。
  2. 写一个包括 BE4WS 包的 Java 应用程序。
  3. 调用适当的方法。
  4. 解析来自 BE4WS 的 USML 响应。

请注意 alphaWorks 上当前的 BE4WS 包不包括 USML 响应解析器。目前,开发者需要修改 清单 5中样本解析代码以达到自己的目的。在 alphaWork 的 Web Services Toolkit(WSTK;请参阅 参考资料)版本 3.1 中将会发布通用的 USML 响应解析器。

利用这样的 Java API,任何电子商务应用程序开发者只要使用一个搜索请求很容易就可以从不同的 UDDI 注册中心查找企业实体和服务。您可以在 BE4WS 安装包(请参阅 参考资料)中找到三个样本 Java 程序来说明上述 Java API 的用法。

Web 服务 API

一旦 BE4WS Web 服务在私有的或公共的 UDDI 注册中心中发布,任何应用程序就都可以查找这一有用的 UDDI 搜索服务并通过 WSDL 接口调用它。已安装的 BE4WS SOAP 服务可以用作 UDDI 高级搜索门户,它允许任何一个 SOAP 客户程序从多个 UDDI 注册中心方便有效的查找有关企业和服务的信息。

BE4WS SOAP 服务中有两种方法: searchByStringsearchByURL 。SOAP 服务 ID 为 urn:uddisearch-service 。提供者类为 com.ibm.UDDI.BusinessExplorer.UDDISearch

图 1展示了已安装在 WAS 4.0.1 上正在运行的 BE4WS SOAP 服务。它是用 WebSphere Application Assembly Tool(AAT)打包成企业应用程序的常规 Java 应用程序。您可以使用 WAS 管理控制台(WAS admin control console)启动或中止它。此外,如果需要的话,您还可以指定访问角色,为 BE4WS 设定某一安全性级别。BE4WS SOAP 服务提供这一 Web 服务接口是为了所有 SOAP 客户程序都很容易访问它。

图 1. 已安装在 WAS 4.0 上的 BE4WS SOAP 服务
已安装在 WAS 4.0 上的 BE4WS SOAP 服务
已安装在 WAS 4.0 上的 BE4WS SOAP 服务

使用 BE4WS 集成样本应用程序

让我们看一下 BE4WS 是如何用于通过一个有多个查询的 USML 请求来高效搜索多个 UDDI 注册中心的。我们的示例将把 BE4WS 部署为 Web 应用程序,且有两个 URL 作为参数:一个是 USML 文档(描述我们想要执行的搜索)的 URL,另一个是 JSP 模板(为我们提供输出格式)的 URL。我们将看一个示例 USML 文档,连同表示 JSP 代码、servlet 代码和 USML 响应解析器。我们将说明 BE4WS 如何简化跨多个 UDDI 注册中心的浏览过程。开发者不需要写任何 Java 代码就可以访问 UDDI 客户程序,例如 UDDI4J;他(或她)唯一需要做的事是构建一个简单的基于 XML 的 USML 脚本,并解析响应。事实上,在这一样本应用程序的基础之上,很容易开发一个让用户输入全部搜索条件的基于 Web 的搜索工具;后端服务器端代码生成 USML,解析响应,并以 Web 页面的形式把结果返回给用户。

下面的示例展示了 Web 应用程序如何调用 BE4WS SOAP 服务并解析响应/把响应提供给 Web 页面。 图 2 展示了使用可配置 BE4WS 聚集的示例页面。这是一个常规 HTML 页面,它包括一个指定您的 USML 脚本 URL 的表单域,另外一个表单域定义您需要的表示模板,它是以 JSP 页面实现的。这些参数( USMLFileURLReturnURL )被传给 BE4WS 调用 servlet。这个页面完整的 HTML 源文件如 清单 1所示。

图 2. 使用 BE4WS 的样本 Web 应用程序页面(调用之前)
使用 BE4WS 的样本 Web 应用程序页面(调用之前)
使用 BE4WS 的样本 Web 应用程序页面(调用之前)
清单 1. BE4WS 调用 servlet 的 HTML
<html>
<body>
<font size="5"><b><font face="Rockwell">
The Aggregation of Configurable BE4WS</font><br>
</b></font>
<form action="http://gcb9.watson.ibm.com/GEMEX/servlet/BE4WSServlet" method="POST">
<table border="1" width="50%" bordercolor="#800000">
  <tr>
    <td width="45%"><font color="#000080"><b>1. Specify the URL of Your USML 
(Search Criteria)</b><br>
      <br>
      <INPUT TYPE="text" name="USMLFileURL" 
value="http://wsbi4.watson.ibm.com/wsdl/be4ws/TwoUDDISearch.xml" 
size="60">
      </font>
      <p><font color="#000080"><b>2. Select Your Presentation Template <br>
      <br>
<input type="text" name="ReturnURL" 
value="http://gcb9.watson.ibm.com/GEMEX/Supplier/BusinessList2.jsp" 
size="60">
      </b></font></p>
      <p><font color="#000080"><b>3. Invoke Business Explorer for 
Web Services<br>
      </b></font>
      <br>
      <INPUT TYPE="Submit" Value="BE4WS">
      </p>
    </td>
    <td width="32%" bgcolor="#CCFF99"> 
    </td>
  </tr>
 </table>
</form>
</body>
</html>

清单 2 中的 USML 脚本的位置即我们作为第一个输入参数使用的 URL。从中我们可以看出用户想要搜索两个私有 UDDI 注册中心( wsbi10wsbi5 )。我们想要从 wsbi10 中得到所有名称以“UPS”开头的服务提供者,或者从 wsbi5 中得到所有名称中包含“KEPEX”的服务提供者。您只要查看一下 清单 2中的代码就应该能够明白 USML 如何工作;您可以在 参考资料部分中查找有关 USML 的 DTD 和如何编写 USML 文档的指导信息的链接。

清单 2. 搜索两个 UDDI 注册中心的 USML 脚本
<?xml version="1.0"?>
<!DOCTYPE Search SYSTEM "UDDISearch.dtd">
<Search>
  <ProcessId>9999</ProcessId>
  <Query>
    <Source>Private UDDI</Source>
    <SourceURL>http://wsbi10/services/uddi/inquiryAPI</SourceURL>
    <Businessname>UPS</Businessname>
    <FindBy>Business</FindBy>
  </Query>
  <Query>
    <Source>Public UDDI</Source>
    <SourceURL>http://wsbi5/services/uddi/servlet/uddi</SourceURL>
    <Businessname>%KEPEX</Businessname>
    <FindBy>Business</FindBy>
  </Query>
  <AggOperator>OR</AggOperator>
</Search>

创建 USML 脚本之后,您就可以使用 清单 3 中的通用调用 servlet 来调用 BE4WS SOAP 服务,在示例中我们把这一服务部署在 WebSphere Application Server 4.0 上。请注意,可以通过使用不同的 USML 脚本来修改 BE4WS 的行为。通过给 USMLFileURL 指定不同的值,可以动态更改 USML 脚本的位置(请参阅 图 2)。

清单 3. BE4WS 调用 servlet
public class BE4WS extends javax.servlet.http.HttpServlet {
  public void performTask(
    javax.servlet.http.HttpServletRequest request,
    javax.servlet.http.HttpServletResponse response) {
    String USMLresponse = null;
    String USMLFileURL = request.getParameter("USMLFileURL");
    String ReturnURL = request.getParameter("ReturnURL");
    try {
      // Construct a URL, you need to modify it
      //USML_URL = "http://wsbi4.watson.ibm.com/wsdl/be4ws/GCBSearch.xml";
      String encodingStyleURI = Constants.NS_URI_SOAP_ENC;
      // provides your own URL of RPC Router Servlet
      URL url = new URL("http://wsbi4.watson.ibm.com/be4ws-soap/servlet/rpcrouter");
      // Construct the SOAP call.
      Call call = new Call();
      call.setTargetObjectURI("urn:uddisearch-service");
      call.setMethodname("searchByURL");
      call.setEncodingStyleURI(encodingStyleURI);
      Vector params = new Vector();
      params.addElement(new Parameter("meth1_inType1",String.class,USML_URL,null));
      call.setParams(params);
      // Invoke a SOAP service
      Response resp = call.invoke(url, "");
      // Parse the response.
      if (resp.generatedFault()) {Fault fault = resp.getFault();
    } else {
      Parameter result = resp.getReturnValue();
      USMLresponse = (String) result.getValue();
      System.out.println("The USML Response is:\n" + USMLresponse);}
      HttpSession session = request.getSession(true);
      session.setAttribute("USMLresponse", USMLresponse);
      // set the results page URL
      String url2 = null;
      if (ReturnURL != null) {url2 = ReturnURL;
      } else {
        url2 = "http://gcb9.watson.ibm.com/GEMEX/Supplier/BusinessList2.jsp";}
        response.sendRedirect(url2);
        } catch (Throwable theException) {theException.printStackTrace();}
    }
}

BE4WS 调用 servlet 是从 图 2中所示的 Web 页面调用的。当然,通过发出一个 URL 请求,在任何 Java 应用程序或 Windows 应用程序中都可以使用这一通用调用 servlet。来自 BE4WS 的响应是一个 USML 文档,其中包含了聚集后的结果,如 清单 4 中所示。您可以从这一响应中获得关于可用企业实体的基本信息。如果您想获得更多细节,可以利用 URL 标记中指定的 URL 获取内容。例如,可以用相同的方法来检索 WSDL 文档的位置。接下来您就可以根据检索到的 WSDL 构造 Web 服务调用。

清单 4. BE4WS 的 USML 响应
<?xml version="1.0"?>
<USMLResponse>
    <Business>
        <Businessname>UPS</Businessname>
        <BusinessKey>339CFD70-E84D-11D5-B61C-970107B90C83</BusinessKey>
        <Description>USA. UPS, or United Parcel Service Inc., is a 93-year-old 
            company whose history spans the bicycle to the Internet. Today the 
            largest express carrier and largest package carrier in the world, 
            UPS continues to develop the frontiers of logistics.
                  </Description>
        <URL>http://wsbi10/services/uddi/uddiget?businessKey=339CFD70-E84D-11D5-B61C-
970107B90C83</URL>
        <Operator>wsbi10/services/uddi</Operator>
    </Business>
    <Business>
        <Businessname>KEPEX Fulfillment Center</Businessname>
        <BusinessKey>8EF91680-EDDA-11D5-ADF1-850C07A41C41</BusinessKey>
        <Description>KEPEX</Description>
        <URL>http://wsbi5:80uddiget?businessKey=8EF91680-EDDA-11D5-ADF1-850C07A41C41
</URL>
        <Operator>wsbi5:80/services/uddi</Operator>
    </Business>
</USMLResponse>

为了解析这个 USML 文档,请使用 清单 5中的解析代码。这里,我们使用 IBM XML parser for Java 代码,但是很容易把代码修改成使用其它解析器。您可以把这段代码改写成您自己的应用程序。

清单 5. 解析 USML 响应的代码
String USMLresponse = (String) session.getAttribute("USMLresponse");
Vector nameVec = new Vector();
Vector keyVec = new Vector();
Vector descriptionVec = new Vector();
Vector urlVec = new Vector();
Vector operatorVec = new Vector();
try {
  byte[] USMLresByteArray = USMLresponse.getBytes();
  String stest = new String(USMLresByteArray);
  ByteArrayInputStream bstream = new ByteArrayInputStream(USMLresByteArray);
  InputSource is = new InputSource((InputStream) bstream);
  NonValidatingTXDOMParser nvparser = new NonValidatingTXDOMParser();
  nvparser.parse(is);
  Document doc = nvparser.getDocument();
  NodeList storylist = doc.getElementsByTagname("USMLResponse");
  for(int at =0; at < storylist.getLength(); at++) {
    TXElement entryEle = (TXElement) storylist.item(at);
    NodeList contEle = entryEle.getElementsByTagname("Business");
    for(int i=0; i<contEle.getLength(); i++) {
      TXElement AttrEle = (TXElement) contEle.item(i);
      NodeList nameEle = AttrEle.getElementsByTagname("Businessname");
      for(int j=0; j<nameEle.getLength(); j++) {
        TXElement AttrnameEle = (TXElement)nameEle.item(j);
        String sContent = AttrnameEle.getText();
        nameVec.addElement(sContent);
      }
      NodeList keyEle = AttrEle.getElementsByTagname("BusinessKey");
      for(int j=0; j<keyEle.getLength(); j++) {
        TXElement AttrKeyEle = (TXElement)keyEle.item(j);
        String sContent = AttrKeyEle.getText();
        keyVec.addElement(sContent);                
      }
      NodeList descriptionEle = AttrEle.getElementsByTagname("Description");
      for(int j=0; j<descriptionEle.getLength(); j++){
        TXElement AttrDesEle = (TXElement)descriptionEle.item(j);
        String sContent = AttrDesEle.getText();
        descriptionVec.addElement(sContent);                
      }
      NodeList urlEle = AttrEle.getElementsByTagname("URL");
      for(int j=0; j<urlEle.getLength(); j++){
        TXElement AttrURLEle = (TXElement)urlEle.item(j);
        String sContent = AttrURLEle.getText();
        urlVec.addElement(sContent);                
      }
      NodeList operatorEle = AttrEle.getElementsByTagname("Operator");
      for(int j=0; j<operatorEle.getLength(); j++) {
        TXElement AttrOperatorEle = (TXElement)operatorEle.item(j);            
        String sContent = AttrOperatorEle.getText();
        operatorVec.addElement(sContent);                
      }
    }
  }
}catch (Exception e) {
  System.out.println("Exception in parser : " + e.getMessage());
  e.printStackTrace();}

清单 6中的 JSP 代码将依据 BE4WS 的 USML 响应创建一个人类可阅读的企业实体列表。调用 servlet( 清单 3)的 USML 响应( 清单 4)被传至该 JSP,然后它调用 清单 5中的解析代码来解析 USML 响应并以结构化方式显示最终结果。请记住,我们通过在上面 图 2中输入它的 URL(作为第二个参数)来指定这个 JSP。 图 3展示了 JSP 代码的输出结果。

清单 6. 创建企业列表的 JSP 代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<%@ page language="java" import="java.util.Vector" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page import="java.lang.*" %>
<%@ page import="org.xml.sax.*" %>
<%@ page import="org.w3c.dom.*" %>
<%@ page import="com.ibm.xml.dom.*" %>
<%@ page import="com.ibm.xml.parser.*" %>
<%@ page import="com.ibm.xml.parsers.*" %>
<html><head>
<META name="GENERATOR" content="IBM WebSphere Page Designer">
<META http-equiv="Content-Style-Type" content="text/css">
<title>BE4WS Aggregation Result</title></head>
<body bgcolor="#FFFFFF" text="#000000" link="#000099" 
  vlink="#000099" alink="#CC0000">
<%
// See Listing 5
%>
<B><FONT face="Verdana, Arial, Helvetica, sans-serif" 
  color="#000099" size="3">
BE4WS Aggregation Result-> Business List<p></FONT></B><p>
<TABLE border="1" cellspacing="1" cellpadding="1">
<TR>
<TD bgcolor="#FFCC00"><b>Business:</b>     </TD>  
<TD bgcolor="#FFCC00"><b>Description:</b>     </TD>  
<TD bgcolor="#FFCC00"><b>Key:</b>     </TD>  
<TD bgcolor="#FFCC00"><b>Operator:</b>     </TD>  
</TR>
<%
System.out.println("size" + keyVec.size());
for(int i=0; i<keyVec.size(); i++)
{
  String sname = (String)nameVec.elementAt(i);
  String sKey = (String)keyVec.elementAt(i);
  String sDescription = (String)descriptionVec.elementAt(i);
  String sURL = (String)urlVec.elementAt(i);
  String sOperator = (String)operatorVec.elementAt(i);
%>
<TR>
<TD> <%=sname%></TD>
<TD> <%=sDescription%></TD>
<TD><a href="<%=sURL%>"> <%=sKey%></a> </TD>
<TD> <%=sOperator%></TD>
</TR>
<% } // for loop %>
</TABLE><p></FONT></body></html>
图 3. 使用 BE4WS 的样本 Web 应用程序页面(调用之后)
使用 BE4WS 的样本 Web 应用程序页面(调用之后)
使用 BE4WS 的样本 Web 应用程序页面(调用之后)

结束语

随着发布在 UDDI 注册中心的可互操作 Web 服务的出现,那些能够在全球环境中向潜在的交易伙伴描述其服务的企业应该有办法相互发现和交互。用户必须能够以比目前的需要省力的方式查找适当的 Web 服务。UDDI 搜索标记语言考虑了想要在单个或多个企业注册中心进行的搜索中有多个查询,这将会帮助实现高效搜索。为了统一 UDDI 搜索查询的格式和极大的减少一次搜索中的请求次数,我们提出这一基于 XML 的语言。基于 USML 的搜索请求合并了多个搜索查询、UDDI 数据源和聚集操作符。我们希望 USML 和 BE4WS 能使 Web 服务更易于使用并使开发者可以自由的挖掘 Web 服务技术的潜力。

大家对于本文有任何建议以及想到的其他可能的问题,都欢迎到我们的 论坛来提出意见或给出评论。


相关主题

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文.
  • 请单击文章顶部或底部的 讨论参与关于本文的 讨论论坛。(英文)
  • 请下载 alphaWorks 上的 BE4WS 分发包并试一下这些较简单的样本。从而您可以亲身实践示例 BE4WS 所支持的不同搜索条件的示例,以及它优于 UDDI4J 以及其它 UDDI 客户程序的地方。
  • BE4WS 包中包括编写 USML的指导;您还可以在 XML Cover Pages 站点找到该信息。
  • Web Services Toolkit的将来的版本将包括 USML 解析器,为了获得更新版本,请浏览这一站点。
  • 请看一下 UDDI4J,它提供 UDDI 规范版本 2 的全面支持。
  • 请更多的了解 Web Services Inspection Language,它提供了以 XML 格式表示的可用于协助检查站点的服务,以及一组与检查有关的消费信息定义规则。
  • IBM 托管 UDDI 版本 2 注册中心,它有一个图形用户界面而且遵循公用 API。
  • IBM WebSphere UDDI Registry使开发者能够探索在企业之间或内部构建 Web 服务注册中心的可能性。
  • 请更多的了解 SOAP 规范

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=SOA and web services
ArticleID=21598
ArticleTitle=通过 BE4WS 聚集 UDDI 搜索
publish-date=03012002