首页 > 代码库 > 【Java】Web 服务编程技巧与窍门: 在 UDDI 注册中心为 Web 服务注册开发 UDDI Java 应用程序

【Java】Web 服务编程技巧与窍门: 在 UDDI 注册中心为 Web 服务注册开发 UDDI Java 应用程序

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

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 anPayrollService 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 theWeb 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 有四个主要的类,我将在清单3、4以及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