本技巧建立了一个使用统一描述、发现和集成 (Universal Description, Discovery, and Integration,UDDI) 来注册应用程序级消费的 Web 服务实例。作者提供了详细的代码示例以及基于 Java 的统一描述、发现和集成 (Universal Description, Discovery,and Integration for Java,UDDI4J) API 的扩展 API,通过这些可以使您使用 UDDI 来进行您自己的开发。

0 评论:

Andrew J. Bradfield (abrad@us.ibm.com), Author, EMC

2004 年 8 月 01 日

  • 内容

引言

统一描述、发现和集成(UDDI) 正在快速成为在 Web 上存储可用业务流程的标准。虽然 UDDI 能够存储大量不同类型的数据,但就本技巧而言,我将把重点放在如何使用 UDDI 来注册 Web 服务,从而使 Web 服务可用于应用程序级的消费。

 

回页首

假设

  • 您正在使用IBM® WebSphere® Studio Application Developer V5.0 (Application Developer) 或者其它的 J2EE 兼容开发环境,例如 Eclipse IDE
  • 已经安装了DB2 ®,并且创建了示例数据库(本示例要用到 Employee 表和 Department 表。要创建示例数据库,打开“DB2 First Steps”,然后单击“Create Sample Database”链接)。
  • 已经安装并正确配置了 UDDI 注册中心。请参阅用于自动安装 UDDI 注册中心来使用 Cloudscape 数据库的 InstallUDDI 清单。从命令窗口执行installuddilibs.bat来创建必需的目录结构。
 

回页首

本技巧涵盖了哪些内容

本技巧给 Java® 开发人员提供了一种快速并且简单的方法来开发他们自己的 UDDI Java 应用程序,并使用这些应用程序来消费在注册中心注册了的 Web 服务。附带的示例代码包含一个 Payroll Web 服务(从一个实体 bean 部署而来的)和一个 UDDI 会话 bean。

 

回页首

技巧背景

本技巧主要是基于教程“使用 WSDK V5.1 发现 Web 服务:UDDI”(developerWorks, 2003 年 11 月),参考资料部分引用了该教程。我的目的是提出基础的 Java 的统一描述、发现和集成 (UDDI4J) 类的扩展,从而帮助您快速建立您自己的 Web 服务 UDDI 注册中心。完成“Discover Web services with the WSDK V5.1: UDDI”这个教程的过程中,我开发了一个提供更高级访问 UDDI4J API 的扩展 API。因为本技巧的目的是注册、发现和消费存储在 UDDI 注册中心的 Web 服务,所以只展开了 UDDI4J 功能的一小部分。有关 UDDI 以及它在存储 Web 服务上的应用的更广泛的讨论,请参阅 Tom Bellwood 的文章“理解 UDDI”(developerWorks,2002 年 7 月)。

 

回页首

Payroll Web 服务

附带的Payroll.ear文件包含一个名为PayrollEjbPrj的企业 JavaBean (EJB) 方案。在这个 EJB 方案里有两个实体 bean(Department 和 Employee)以及一个会话 bean (Payroll)。Department 和 Employee 这两个实体 bean 显示了用于示例数据库的 getter 和 setter 方法。Payroll bean 显示了 12 种方法,它使用实体 bean 的 getter 方法从示例数据库中查询各种信息片断。示例代码很容易被扩展,从 Payroll bean 内部提供 setter 函数。显示所有的示例数据库字段不在本技巧的范围之内。

 

回页首

UDDIClient 会话 EJB

UDDIClient 会话 bean 几乎全部由下一部分讨论的 UDDI 实用 API 构成。

UDDI 注册中心可以包括业务、服务以及 TModel。UDDIClient bean 为每类 UDDI 条目提供了一个 publish() 方法和两个 delete() 方法。如下面的清单 1所示,把任务移交给 UDDI 实用 API 处理时,方法签名(method signature)方法尽可能的简单。

清单 1.方法签名
public String publishBusiness(String busName)
{
return BusinessUtilities.publishBusiness(busName);
} public void deleteBusinessByName(String busName)
{
BusinessUtilities.deleteBusinessByName(busName);
}
public void deleteBusinessByKey(String busKey)
{
BusinessUtilities.deleteBusinessByKey(busKey);
}
public String publishService(String serviceName, String busName,
String tModelName, String tModelOverviewDoc,
String accessPointStr, String description)
{
return
ServiceUtilities.publishService(serviceName,busName,tModelName,
tModelOverviewDoc,accessPointStr,description);
}
public void deleteServiceByName(String serviceName)
{
ServiceUtilities.deleteServiceByName(serviceName);
}
public void deleteServiceByKey(String serviceKey)
{
ServiceUtilities.deleteServiceByKey(serviceKey);
}
public String publishTModel(String tModelName, String overviewDocString)
{
return
ModelUtilities.publishTModel(tModelName,overviewDocString);
} public void deleteTModelByName(String tModelName)
{
ModelUtilities.deleteTModelByName(tModelName);
}
public void deleteTModelByKey(String tModelKey)
{
ModelUtilities.deleteTModelByKey(tModelKey);
}

getService 和 executeService 方法

UDDIClient bean 的 getService 和 executeService 方法演示了如何重新获得我们的 Payroll Web 服务并调用其中的一些方法。executeService 方法用一个字符串表示一个存储在注册中心的服务的名称。在示例代码中,注册的服务是 Payroll Web 服务。为了达到本技巧的预期效果,我硬编码了两个方法,供注册中心内创建的 Payroll Web 服务调用,如清单 2所示。

清单 2. getService 和 executeService 方法
/**
* Execute a Service found in the UDDI registry
* @param serviceName Service name used to search for
and execute available UDDI Services
*/
public void executeService(String serviceName)
{
//Obtain all access points for services providing this
service
Map accessPoints =
ServiceUtilities.getServiceAccessPoints(serviceName); //Create a set of accespoints
Set accessSet = accessPoints.keySet();
Iterator it = accessSet.iterator(); Payroll payroll = null;
Object obj = null; while(it.hasNext())
{
try
{
//For each access point, create an
PayrollService object
String accessPoint = (String)it.next();
System.out.println("Service Access Point: " +
accessPoint);
payroll = getService(accessPoint); if(payroll != null)
{
System.out.println("Employee 000010's
bonus is " + payroll.getBonus("000010"));
System.out.println("Employee 000010's
phone number is " + payroll.getPhoneNo("000010"));
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
/**
* Create a Service object, to communicate with the
Web service defined by the URL
* @param urlString the URL of the Web service
* @return A PayrollService object.
*/
private Payroll getService(String urlString)
{
PayrollServiceLocator payrollServiceLocator =
new PayrollServiceLocator();
Payroll payroll = null; try
{
URL url = new URL(urlString);
System.out.println("Payroll URL: " + url.toString());
System.out.println("Getting Payroll object");
payroll =
payrollServiceLocator.getPayroll(url);
System.out.println("Payroll object retrieved
successfully");
}
catch (MalformedURLException e)
{
System.out.println("URL Exception: " + e.toString());
}
catch(javax.xml.rpc.ServiceException se)
{
System.out.println("Service Exception: " +
se.toString());
} return payroll;
}
 

回页首

UDDI 实用 API

UDDI 实用 API 有四个主要的类,我将在清单34以及5中详细描述其中的三个。第 4 个 (Utilities.class) 包含所有的 UDDI 注册的设置信息。 "使用 WSDK V5.1 将服务发布到 UDDI 注册中心"(developerWorks,2003 年 11 月)这个教程详细解释了其中的值和结构。

清单 3. BusinessUtilities
/**
* Display business information of a BusinessEntity
* @param businessKey The businessKey of the BusinessEntity
whose detail is to be displayed
*/
public static void showBusinessDetail(String businessKey)
/**
* Locate a Business by name
* @param busName The business name used to search for a business
* @return Vector: This method returns a Vector of Strings.
Each String represents the businessKey of a business matching the query
*/
public static Vector findBusinessByName(String busName)
/**
* Locate a Business by key
* @param businessKey The business key used to search for a business
* @return BusinessList: This function returns a BusinessList on success.
In the event that no matches were located for the specified criteria,
a BusinessList structure with zero BusinessInfo structures is returned.
*/
public static BusinessList findBusinessByKey(String businessKey)
/**
* Delete a Business by name
* @param busName Business name used to find and delete a business
*/
public static void deleteBusinessByName(String busName)
/**
* Delete a Business by key
* @param businessKey A Business key used to find and delete a business
*/
public static void deleteBusinessByKey(String businessKey)
/**
* Publish a Business
* @param busName The name of the business to be published
* @return String: This method returns a String representing the
key of the newly published Business
*/
public static String publishBusiness(String busName)
清单 4. ModelUtilities
/**
* Locate a technical Model by name
* @param tModelName the Name
* @return Vector: This method returns a Vector of
tModelKey Strings
*/
public static Vector findTModelByName(String tModelName)
/**
* Locate a technical Model by key
* @param tModelName The TModel key used to search for a TModel
* @return TModelList: This method returns a TModelList
of TModelInfos objects
*/
public static TModelList findTModelByKey(String tModelKey)
/**
* Delete a technical Model by name
* @param tModelKey TModel name used to delete a TModel
*/
public static void deleteTModelByName(String tModelName)
/**
* Delete a technical Model by key
* @param tModelKey TModel key used to delete a TModel
*/
public static void deleteTModelByKey(String tModelKey)
/**
* Publish a technical Model
* @param tModelName The TModel name
* @param overviewDocString This parameter expects a
URL-String representation of the WSDL address.
EX: http://localhost:9080/MyRouter/Test.wsdl
* @return String: This method returns a String
representing the key of the newly published TModel
*/
public static String publishTModel(String tModelName,
String overviewDocString)
清单 5. ServiceUtilities
/**
* Locate a Service by name
* @param serviceNames A vector of Name objects
* @return Map: This method returns a Map of service
and business key pairs
*/
public static Map findServiceByName(Vector serviceNames) /**
* Locate a Service by key
* @param serviceKey A key used to search for a Service
* @return ServiceList: This method returns a ServiceList of
ServiceInfos objects
*/
public static ServiceList findServiceByKey(String serviceKey)
/**
* Delete a Service by name
* @param serviceName Service name used to find
and delete a Service
*/
public static void deleteServiceByName(String serviceName)
/**
* Delete a Service by key
* @param serviceKey Service key used to find and delete
a Service
*/
public static void deleteServiceByKey(String serviceKey)
/**
* Publish a Service
* @param serviceName The name of the Service to be published
* @param businessName The Business name used to
associate the service to. If Business name does not exist
in the registry, a Business entry will be created.
* @param tModelName The TModel that the service implements.
If TModel is not found in the registry and the
TModelOverviewDoc parameter is not null, a TModel entry
will be created.
* @param tModelOverviewDoc Required only if the TModel name
provided in the tModelName parameter is not
found in the registry.
This parameter expects a URL-String representation of the
WSDL address. EX: http://localhost:9080/MyRouter/Test.wsdl
* @param accessPointStr
* @param description Optional Service description.
* @return String: This method returns a String representing
the key of the newly published Service
*/
public static String publishService(String serviceName,
String busName, String tModelName, String tModelOverviewDoc,
String accessPointStr, String description)
 

回页首

结束语

正如您所看到的,UDDI 程序设计是在使用 UDDI 注册中心的网络上共享信息的非常有效的途径。这里的示例代码,更具体地说,UDDI 实用 API 提供了一个起点,从这个起点出发您能够开发更加用户化的解决方案。

http://www.ibm.com/developerworks/cn/webservices/ws-tip-uddijava.html

【Java】Web 服务编程技巧与窍门: 在 UDDI 注册中心为 Web 服务注册开发 UDDI Java 应用程序的更多相关文章

  1. SpringCloud Alibaba实战(7:nacos注册中心管理微服务)

    源码地址:https://gitee.com/fighter3/eshop-project.git 持续更新中-- 在上一节我们已经完成了Nacos Server的本地部署,这一节我们学习如何将Nac ...

  2. Spring Cloud(Dalston.SR5)--Eureka 注册中心高可用-服务提供和消费

    由于 Eureka 注册中心只是在内存中保存服务注册实例,并且没有将服务注册实例进行同步,因此我们需要对服务提供和消费进行调整,需要指定服务提供和消费的注册.服务发现的具体Eureka 注册中心配置, ...

  3. Dubbo中多注册中心问题与服务分组

    一:注册中心 1.场景 Dubbo 支持同一服务向多注册中心同时注册, 或者不同服务分别注册到不同的注册中心上去, 甚至可以同时引用注册在不同注册中心上的同名服务. 2.多注册中心注册 中文站有些服务 ...

  4. Dubbo多注册中心和Zookeeper服务的迁移

    一.Dubbo多注册中心 1. 应用场景 例如阿里有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心. consumer.xml <?xm ...

  5. nacos注册中心配置命名服务不生效问题

    nacos作为注册中心指定命名空间,配置如下: 但是启动之后发现服务都默认注册到了public这个命名空间下面,也就是指定的命名空间不生效 这是因为注册中心使用的命名空间的配置不是nacos.conf ...

  6. 优雅写Java之一(常见编程技巧)

    一.字符串相关 推荐使用Apache Commons Lang3库 创建Empty字符串:return StringUtils.EMPTY; 或者 return ""; 创建重复的 ...

  7. SpringCloud的服务注册中心(二)注册中心服务端和两个微服务应用客户端

    一.构建EurekaServer工程 1.pom.xml 2.application.yml 3. EurekaServerApp.java 4.启动EurekaServer 二.构建部署 Eurek ...

  8. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇] 在进行基于会话信道的WCF服务调用中,由于受到并发信道数量的限制,我们需要及时的关闭信道:当遇到某些异常,我们需要强行中止(Abor ...

  9. Java入门网络编程-使用UDP通信

    程序说明: 以下代码,利用java的网络编程,使用UDP通信作为通信协议,描述了一个简易的多人聊天程序,此程序可以使用公网或者是局域网进行聊天,要求有一台服务器.程序一共分为2个包,第一个包:udp, ...

随机推荐

  1. OMCS的语音视频带宽占用

    OMCS的语音.视频.电子白板.远程桌面等功能对网络带宽的要求分别如何了? 我们先假设一种常见的场景:假设N个在线用户同时进行1对1的多媒体沟通(即分为N/2组),在不考虑P2P通道的情况下,带宽的大 ...

  2. 分布式还是混合式? 谈CDN架构对服务质量的影响

    传统分布式模型 通 常,内容分发网络(CDN)採用分布式模型.在这样的模型里, 用户的文件存放在一个源server上.而且由大量边缘server负责分发这些文件.这些边缘server的磁盘空间比較小. ...

  3. css考核点整理(十一)-响应式开发经验,响应式页面的三种核心技术是什么

    响应式开发经验,响应式页面的三种核心技术是什么

  4. 10.26 noip模拟试题

    enc[问题背景]zhx 和他的妹子聊天.[问题描述]考虑一种简单的加密算法.假定所有句子都由小写英文字母构成,对于每一个字母,我们将它唯一地映射到另一个字母.例如考虑映射规则:a->b, b- ...

  5. css 图片平铺

    背景图尺寸(数值表示方式): #background-size{ background-size:200px 100px; } 背景图尺寸(百分比表示方式): #background-size2{ b ...

  6. cocos2dx 的Hello world的简单分析

    Node之间的关系: 场景AppDelegate.cpp又要由导演去调用然后进行表演: // create a scene. it's an autorelease object auto scene ...

  7. Store update, insert, or delete statement affected an unexpected number of rows ({0}).

    问题描述 Store update, insert, or delete statement affected an unexpected number of rows ({0}). Entities ...

  8. (ternary operator)三元运算符.

    ternary operator: advantage: make a terse simple conditional assignment statement of if-then-else. d ...

  9. (转载)[FFmpeg]使用ffmpeg从各种视频文件中直接截取视频图片

    你曾想过从一个视频文件中提取图片吗?在Linux下就可以,在这个教程中我将使用ffmpeg来从视频中获取图片. 什么是ffmpeg?What is ffmpeg? ffmpeg是一个非常有用的命令行程 ...

  10. Xcode的控制台调试命令

    XCode4.0以后,编译器换成了LLVM 编译器 2.0 与以前相比,更加强大:1.LLVM 编译器是下一带开源的编译技术.完全支持C, Objective-C, 和 C++.2.LLVM 速度比 ...