本技巧建立了一个使用统一描述、发现和集成 (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. AlphaDict 软件公布

    今天 Release 了 1.1. 主要是移植到了 window 平台, 无须安装,直接执行. 对 UI 又一次进行了设计,应该比之前好看多了. 加入了 生词本 功能,方便 学习外语. ------- ...

  2. Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应

    版权声明:本文为博主原创文章,未经博主允许不得转载.  Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应  上一篇讲过了主体界面的绘制,这里讲解调色板应用中的另外一 ...

  3. Qt 学习之路:Canvas

    在 QML 刚刚被引入到 Qt 4 的那段时间,人们往往在讨论 Qt Quick 是不是需要一个椭圆组件.由此,人们又联想到,是不是还需要其它的形状?这种没玩没了的联想导致了一个最直接的结果:除了圆角 ...

  4. iOS-设置状态栏白色以及覆盖状态栏

    iOS-设置状态栏白色以及覆盖状态栏 将状态栏设置为白色 首先, 在info.plist中添加一个标记. View controller–based status bar appearance键值设置 ...

  5. CentOS 6.7编译安装MySQL 5.6

    1.安装前准备 yum install make gcc gcc-c++ ncurses-devel perl bison-devel yum groupinstall "Developme ...

  6. 用JS实现AJAX

    用JS实现AJAX   准备工作:新建网站,建立两个页面,index.aspx和backstage.aspx, 在工程目录下新建一个文件夹命名和image,在这里添加一个loading.gif,模拟提 ...

  7. oc常用正则表达式

    常用的第三方正则库: http://regexkit.sourceforge.net/RegexKitLite/index.html 匹配中文字符的正则表达式: [\u4e00-\u9fa5]评注:匹 ...

  8. Codeforces 474F - Ant colony

    注意到每个区间生存下来的蚂蚁的长度等于区间的gcd 于是可以先预处理出区间的gcd 然后二分查找就好了 预处理gcd我这里用的是倍增法 总的时间复杂度O(NlogN) /* Cf 271F 倍增求区间 ...

  9. saiku

    1.saiku下载http://community.meteorite.bi/可以下载各个版本的源代码 2.下载到   saiku-latest.zip 3.解压运行比较简单     解压出来的目录: ...

  10. java.math.BigDecimal类

    BigDecimal类用于高精度计算.一般的float型和Double型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到java.math.BigDecima ...