在JAXR客户端使用分类系统

在JAXR API中,一种分类系统是通过一个ClassificationScheme对象来表示的。

本节描述如何使用Java WSDP中的JAXR工具来完成:

·      定义自己的分类系统

·      为机构指定通信地址

定义分类系统

JAXR规范要求一个JAXR提供者能够添加由JAXR客户端使用的用户定义的分类系统。客户用来添加和管理这些分类系统的机制是针对实现的。

Java WSDP中的JAXR的实现使用了简单的基于文件的方法来为JAXR客户端提供分类系统。一旦JAXR提供着启动了,这些文件在运行期间是可读的。

Java WSDP中的分类系统的结构由JAXR预定义概念DTD定义的,在jaxrconcepts.dtd文件以XML方案的形式和jaxrconcepts.xsd文件中都有申明。文件jaxrconcepts.xml包含了用于Java WSDP中JAXR实现的分类系统。所有的这些文件都包含在<JWSDP_HOME>/common/lib/jaxr-ri.jar文件中,但可以在<JWSDP_HOME>/docs/jaxr/taxonomies目录下发现它的一个副本。该目录还包含Java WSDP中JAXR的实现在定义著名的分类系统时使用的XML文件的副本,有naics.xml,iso3166.xml,和unspsc.xml。可以将所有这些文件用作如何构建一个分类系统的XML文件的例子。

文件jaxrconcepts.xml中的数据项与下面类似:

<PredefinedConcepts>
<JAXRClassificationScheme id="schId" name="schName">
<JAXRConcept id="schId/conCode" name="conName" parent="parentId" code="conCode">
</JAXRConcept>
...
</JAXRClassificationScheme> </PredefinedConcepts>

分类系统结构是基于包含的结构。元素PredefinedConcepts是结构的根,是必须的。元素JAXRClassificationScheme是结构的双亲,而JAXRConcept元素是孩子和孙子。一个JAXRConcept元素可以有孩子,但不是必须的。

所有元素的定义中,order和case属性是非常重要的。

要增加用户定义的分类系统,按照如下步骤进行:

1.  为分类系统发布JAXRClassificationScheme元素,形成要访问的注册中心中的一个ClassificationScheme对象。例如,可以发布ClassificationScheme对象到Java WSDP注册中心服务器。为了发布一个ClassificationScheme对象,必须设置它的name。还要给定方案,已知的分类方案中的一类,例如uddi-org:types。在下面的代码段中,name是LifeCycleManager.createClassificationScheme方法调用的第一个参数。

ClassificationScheme cScheme =
    blcm.createClassificationScheme("MyScheme",
        "A Classification Scheme");
ClassificationScheme uddiOrgTypes =
    bqm.findClassificationSchemeByName(null,
        "uddi-org:types");

if (uddiOrgTypes != null) {
    Classification classification =
        blcm.createClassification(uddiOrgTypes,
            "postalAddress", "categorization" );
    postalScheme.addClassification(classification);
    ExternalLink externalLink =
        blcm.createExternalLink(
            "http://www.mycom.com/myscheme.html",
            "My Scheme");
    postalScheme.addExternalLink(externalLink);
    Collection schemes = new ArrayList();
    schemes.add(cScheme);
    BulkResponse br =
        blcm.saveClassificationSchemes(schemes);
}

由saveClassificationSchemes方法返回的BulkResponse对象包含分类方案的关键字,它是用户要查找的:

if (br.getStatus() == JAXRResponse.STATUS_SUCCESS) {
    System.out.println("Saved ClassificationScheme");
    Collection schemeKeys = br.getCollection();
    Iterator keysIter = schemeKeys.iterator();
    while (keysIter.hasNext()) {
        javax.xml.registry.infomodel.Key key =
            (javax.xml.registry.infomodel.Key)
                keysIter.next();
        System.out.println("The postalScheme key is " +
            key.getId());
        System.out.println("Use this key as the scheme" +
            " uuid in the taxonomy file");
}
}

2.  在一个XML文件中,定义一个分类系统的结构,它是遵循JAXR预定义概念DTD的。在分类系统的XML文件输入ClassificationScheme元素,指定返回的关键字ID值作为id属性的值,名字作为name属性的值。例如,对于上面的代码段,空的JAXRClassificationScheme元素标记类似于下面的例子(所有的都在一行):

<JAXRClassificationScheme
id="uuid:nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn"
name="MyScheme">

ClassificationScheme的id 必须是UUID。

3.  在分类系统的XML文件中输入每个JAXRConcept元素,指定下面的四个属性,按照这一次序:

a.                   id是JAXRClassificationScheme的id值,后面跟/分隔符,再跟上JAXRConcept元素的代码

b.                   name是JAXRConcept元素的名字

c.                   parent是直接的双亲id(或者是ClassificationScheme的id,或者是双亲JAXRConcept的id)

d.                   code是JAXRConcept元素代码的值

naics.xml文件中的第一个JAXRConcept元素如下所示(所有的都在一行):

<JAXRConcept
id="uuid:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2/11"
name="Agriculture, Forestry, Fishing and Hunting"
parent="uuid:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"
code="11"></JAXRConcept>

4.  要添加用户定义的分类系统的结构到JAXR提供者,运行客户端程序时,指定系统属性com.sun.xml.registry.userTaxonomyFilenames。命令行(都在一行)如下所示。垂直竖线(|)是文件分隔符。

java myProgram -DuserTaxonomyFilenames=
c:\myfile\xxx.xml|c:\myfile\xxx2.xml

在build.xml文件中,可以使用<sysproperty>标记来设置该属性。或者在程序中,如下设置该属性:

System.setProperty
("com.sun.xml.registry.userTaxonomyFilenames",
"c:\myfile\xxx.xml|c:\myfile\xxx2.xml");

指定通信地址

JAXR规范将通信地址定义成由属性street,city,country等构成的结构化接口。另一方面,UDDI规范将通信地址定义成自由格式的地址行的集合,每一行可以被赋予一个含义。要将JAXR的PostalAddress格式映射成一个已知的UDDI地址格式,必须将UDDI格式指定成一个ClassificationScheme对象,然后指定UDDI格式分类方案中的概念与JAXR PostalAddress分类方案中的注释间的语义等价。JAXR PostalAddress分类方案由Java WSDP中的JAXR的实现提供。

在JAXR API中,一个PostalAddress对象有成员streetNumber, street, city, state, postalCode和country。在Java WSDP中的JAXR的实现中,jaxrconcepts.xml文件里有预定义的概念,在ClassificationScheme内名为PostalAddressAttributes。

要指定JAXR通信地址格式和其他格式间的映射,需要设置两个连接属性:

·      javax.xml.registry.postalAddressScheme属性,它为连接指定了一个通信地址分类方案

·      javax.xml.registry.semanticEquivalences属性,它指定了JAXR格式和其他格式间的语义等价

例如,假设要使用已经发布到IBM注册中心的方案,已知UUID为uuid:6eaf4b50-4196-11d6-9e2b-000629dc0a2b。该方案已经在jaxrconcepts.xml文件中存在,在名字IBMDefaultPostalAddressAttributes下。

<JAXRClassificationScheme
id="uuid:6EAF4B50-4196-11D6-9E2B-000629DC0A2B"
name="IBMDefaultPostalAddressAttributes">

首先,使用JAXRClassificationScheme元素(UUID)中的id值来指定通信地址方案。情况并不重要:

props.setProperty("javax.xml.registry.postalAddressScheme",
  "uuid:6eaf4b50-4196-11d6-9e2b-000629dc0a2b");

接着,指定从默认的JAXR通信地址方案中的每个JAXRConcept元素到IBM方案中的counterpart的id的映射:

props.setProperty("javax.xml.registry.semanticEquivalences",
  "urn:uuid:PostalAddressAttributes/StreetNumber," +
  "urn:uuid:6eaf4b50-4196-11d6-9e2b-
000629dc0a2b/StreetAddressNumber|" +
  "urn:uuid:PostalAddressAttributes/Street," +
  "urn:uuid:6eaf4b50-4196-11d6-9e2b-
000629dc0a2b/StreetAddress|" +
  "urn:uuid:PostalAddressAttributes/City," +
  "urn:uuid:6eaf4b50-4196-11d6-9e2b-000629dc0a2b/City|" +
  "urn:uuid:PostalAddressAttributes/State," +
  "urn:uuid:6eaf4b50-4196-11d6-9e2b-000629dc0a2b/State|" +
  "urn:uuid:PostalAddressAttributes/PostalCode," +
  "urn:uuid:6eaf4b50-4196-11d6-9e2b-000629dc0a2b/ZipCode|" +
  "urn:uuid:PostalAddressAttributes/Country," +
  "urn:uuid:6eaf4b50-4196-11d6-9e2b-000629dc0a2b/Country");

使用这些属性生成连接后,可以生成一个通信地址并在发布机构前,将它赋值给机构的主要联系:

String streetNumber = "99";
String street = "Imaginary Ave. Suite 33";
String city = "Imaginary City";
String state = "NY"; String country = "USA";
String postalCode = "00000";
String type = "";
PostalAddress postAddr =
  blcm.createPostalAddress(streetNumber,
street, city, state,
    country, postalCode, type);
Collection postalAddresses = new ArrayList();
postalAddresses.add(postAddr);
primaryContact.setPostalAddresses(postalAddresses);

然后,如果通信地址方案和查询用的等价语义与发布指定的相同,JAXR查询可以使用PostalAddress方法来查找通信地址。当不知道发布时使用的通信地址方案时,要查找通信地址,可以用Slot对象的集合的方式进行查找。JAXRQueryPostal.java例子应用程序演示了如何实现这一个过程。

一般来说,可以为任意的使用uddi-org:types分类系统中著名分类的postalAddress tModel生成一个用户定义的通信地址分类系统,它的tModel UUID为uuid:c1acf26d-9672-4404-9d70-39b756e62ab4,有一个postalAddress的值。可以查找tModel overviewDoc,它指向方案规范中的技术细节,在那儿可以找到分类系统的结构定义。(overviewDoc与JAXR中的ExternalLink等价。)

运行客户端例子

该指南提供了简单的可以从命令行运行的客户端应用程序。可以修改它来适应你的需求。这些应用程序还允许指定IBM注册中心、Microsoft注册中心或者用于查询和更新的注册中心服务器;可以指定任意其它的UDDI版本2注册中心。

目录<JWSDP_HOME>/docs/tutorial/examples/jaxr中有如下一些客户端实例:

·      JAXRQuery.java 演示了如何查找注册中心中的某个机构

·      JAXRQueryByNAICSClassification.java 演示了如何使用通用的分类方案来查找注册中心

·      JAXRQueryByWSDLClassification.java 演示了如何查找注册中心中借助于WSDL文档描述自身的那些Web服务

·      JAXRPublish.java显示了如何将某个机构发布到注册中心

·      JAXRDelete.java显示了如何从注册中心移除一个机构

·      JAXRSaveClassificationScheme.java 显示了如何发布一个分类方案(特殊的,通信地址方案)到注册中心

·      JAXRPublishPostal.java显示了如何用主要联系用的通信地址来发布一个机构

·      JAXRQueryPostal.java显示了如何从一个机构中检索通信地址数据

·      JAXRDeleteScheme.java 显示了如何从一个注册中心删除一种分类方案

·      JAXRGetMyObjects.java列出注册中心中所拥有的全部对象

目录 <JWSDP_HOME>/docs/tutorial/examples/jaxr还包括:

·      实例的build.xml文件

·      供例子程序使用的字符串值的JAXRExamples.properties文件

·      名为postalconcepts.xml的文件,它在通信地址的例子中使用

编译例子程序前

编译例子程序前,如下编辑JAXRExamples.properties文件。(关于编辑该文件来访文注册中心服务器的详细信息,请参见“使用JAXR来访问注册中心服务器”。)

1.  在JAXRExamples.properties文件中编辑下列这几行来指定想要访问的注册中心。对于queryURL和publishURL的赋值,除了希望访问的注册中心,全部注释掉。默认的是注册中心服务器,因此如果要使用注册中心服务器,不必修改这部分。

## Uncomment one pair of query and publish URLs.
## IBM:
#query.url=http://uddi.ibm.com/testregistry/inquiryapi
#publish.url=https://uddi.ibm.com/testregistry/protect/
publishapi
## Microsoft:
#query.url=http://uddi.microsoft.com/inquire
#publish.url=https://uddi.microsoft.com/publish
## Registry Server:
query.url=http://localhost:8080/registry-server/
RegistryServerServlet
publish.url=http://localhost:8080/registry-server/
RegistryServerServlet

IBM和Microsoft注册中心都拥有相当多的数据,可以在其中执行查询。而且,如果仅仅执行查询,不必注册。

没有包含SAP注册中心的URL,可以自由的添加。

如果想要发布任意的公共注册中心,用于访问注册中心的注册处理并不难(参见:“预备:访问注册中心”)。但是,每个注册中心在同一时刻只允许注册一个机构。如果将某个机构注册到其中的某个注册中心,在发布另一个前必须删除它。由于JAXRPublish例子发布的机构是虚构的,不管怎样可以直接删除。(有提示地删除这样的机构是非常重要的,因为发布的注册中心彼此间会复制数据,虚构的机构可以出现在没有在其中发布的注册中心,因此不能从中删除。)

注册服务器使得你可以更自由的使用JAXR进行试验。可以注册所希望的多个机构。但是,该注册中心开始时数据库为空,因此执行查询前必须自己发布机构到注册中心。

2.  编辑JAXRExamples.properties文件中的下面几行来指定注册到注册中心时获得的用户名和密码。默认值是注册中心服务器默认的密码。

## Specify username and password if needed
## testuser/testuser are defaults for Registry Server
registry.username=testuser
registry.password=testuser

3.  如果将要使用公共的注册中心,编辑JAXRExamples.properties文件中的下面几行,包含空字符串的代理主机,指定自己的代理设置。代理主机是网络上,系统访问Internet时要通过的;通常在Internet浏览器中指定它的设置。可以保持空值来使用注册中心服务器。

## HTTP and HTTPS proxy host and port;
## ignored by Registry Server
http.proxyHost=
http.proxyPort=8080
https.proxyHost=
https.proxyPort=8080

代理端口值为8080,这是常用的一个;如果使用了不同的端口,修改这个字符串。

对于公共注册中心,数据项通常有如下模式:

http.proxyHost=proxyhost.mydomain
http.proxyPort=8080
https.proxyHost=proxyhost.mydomain
https.proxyPort=8080

4.  在文件的剩余部分自由的修改任意机构的数据。在发布和通信地址例子中将使用这些数据。

任何时候都可以编辑JAXRExamples.properties文件。运行客户例子时,会使用最新版的该文件。

编译例子

要编辑程序,进入<JWSDP_HOME>/docs/tutorial/examples/jaxr目录。build.xml文件允许使用下面的命令

ant build

来编译所有的例子。Ant工具生成名为build的子目录,并将class文件放置在该目录中。

注意到在build.xml文件中,classpath的设置包括几个目录的内容。所有的JAXR客户端例子都需要设置classpath。

运行例子

用于运行例子的一些build.xml目标包含注释掉的<sysproperty>标记,它是设置JAXR记录层来调试和设置其它连接属性的。提供这些标记来演示如何指定连接属性。这些标记可以自由的修改或删除。

如果正使用注册中心服务器运行例子,启动Tomcat。更多信息请参见“启动注册中心服务器”。要运行公共注册中心上的例子,不必启动Tomcat。

运行JAXRPublish例子

要运行JAXRPublish程序,使用不带命令行参数的run-publish目标:

ant run-publish

程序output显示新机构关键字的字符串值,机构名为“The Coffee Break.”

运行JAXRPublish程序后,JAXRDelete程序前,可以运行JAXRQuery来查找你发布的机构。也可以使用注册中心浏览器来查找。

运行JAXRQuery例子

要运行JAXRQuery例子,使用Ant目标run-query。在命令行指定一个查询字符串作为参数,来查找注册中心中名字包含该字符串的机构。例如,下面的命令行查找名字包含“coff”的机构(查找是不区分大小写的):

ant run-query -Dquery-string=coff

运行JAXRQueryByNAICSClassification例子

运行完JAXRPublish程序后,也可以运行JAXRQueryByNAICSClassification例子,它查找使用“Snack and Nonalcoholic Beverage Bars”分类的机构,同样用于由JAXRPublish生成的机构。要完成这一任务,使用Ant目标run-query-naics:

ant run-query-naics

运行JAXRDelete例子

要运行JAXRDelete程序,指定由JAXRPublish程序返回的关键字串作为输入给run-delete目标:

ant run-delete -Dkey-string=keyString

运行JAXRQueryByWSDLClassification例子

任何时候都可以运行JAXRQueryByWSDLClassification例子。使用Ant目标run-query-wsdl:

ant run-query-wsdl

这个例子从公共注册中心返回许多结果,可能要运行几分钟。

发布一种分类方案

为了发布带有通信地址的机构到公共注册中心,必须首先为通信地址发布一种分类方案。

要运行JAXRSaveClassificationScheme程序,使用目标run-save-scheme:

ant run-save-scheme

程序返回一个UUID字符串,在下一节将会使用该串。

如果正在使用注册中心服务器,可以不必运行该程序,因为没有使这些对象生效。

公共注册中心允许同时拥有多个分类方案(通常分类方案和概念加在一起的总数不超过10)。

运行通信地址的例子

运行通信地址的例子前,在编辑器中打开postalconcepts.xml文件。找到字符串uuid-from-save,用run-save-scheme目标返回的UUID字符串替换它。对于注册中心服务器,可以使用格式为UUID的任意字符串。

对于一个给定的注册中心,只要保存分类方案和编辑的postalconcepts.xml一次。执行完这两步后,可以多次运行JAXRPublishPostal和JAXRQueryPostal程序。

1.  运行JAXRPublishPostal程序。注意,在build.xml文件中,run-publish-postal目标包含一个<sysproperty>标记,它将userTaxonomyFilename属性设置成当前目录中postalconcepts.xml文件的位置:

<sysproperty
   key="com.sun.xml.registry.userTaxonomyFilenames"
   value="postalconcepts.xml"/>

指定在postalconcepts.xml文件中输入的字符串作为run-publish-postal目标的输入:

ant run-publish-postal -Duuid-string=uuidstring

程序output显示新机构的关键字的值串。

2.  运行JAXRQueryPostal程序。Run-query-postal目标包含与run-publish-postal目标相同的<sysproperty>标记。

在命令行指定一个query-string参数和一个uuid-string参数作为run-query-postal目标的输入,来在注册中心中查找由run-publish-postal目标发布的机构:

ant run-query-postal -Dquery-string=coffee
-Duuid-string=uuidstring

使用JAXR的PostalAddress方法将得到正确的主要联系用的通信地址。使用其它通信地址方案找到的任何通信地址将以缝隙行的形式出现。

3.  如果正使用公共注册中心,确保按照“运行JAXRDelete例子”中的指令删除了已经发布的机构。

删除分类方案

使用完后要删除发布的分类方案,使用run-delete-scheme目标来运行JAXRDeleteScheme程序:

ant run-delete-scheme -Duuid-string=uuidstring

对于UDDI注册中心来说,删除一个分类方案是逻辑上将它从注册中心移除,并没有物理上删除。不能再使用这一分类方案,但例如,如果调用QueryManager.getRegisteredObjects方法,该方案仍然是可见的。由于公共注册中心允许拥有10个这样的对象,这不是个问题。

获得注册的对象的列表

要获得在注册中心已经拥有的对象、机构和分类方案的列表,通过使用run-get-objects目标来运行JAXRGetMyObjects程序:

ant run-get-objects

其它目标

要删除build目录和class文件,使用命令:

ant clean

要获得目标的语法提示,使用命令:

ant -projecthelp

更多信息

关于JAXR、注册中心以及Web服务的更多信息,可以参考下列:

·       Java规范请求 (JSR) 93: JAXR 1.0:

http://jcp.org/jsr/detail/093.jsp

·       JAXR主页:

http://java.sun.com/xml/jaxr/index.html

·       统一描述、发现和集成(Universal Description, Discovery, and Integration,UDDI)项目:

http://www.uddi.org/

·       ebXML:

http://www.ebxml.org/

·       用于ebXML注册中心的开放源代码JAXR提供着

https://sourceforge.net/forum/forum.php?forum_id=197238

·       Java Web服务开发包(Java WSDP):

http://java.sun.com/webservices/webservicespack.html

·       Java技术和XML:

http://java.sun.com/xml/

·       Java技术和Web服务:

http://java.sun.com/webservices/index.html

 

 

常见问答

下载中心

产品简介

 

 

Solaris论坛