在 Weblogic Server 10 中使用 JAX-WS 和 JAXB:JAX-WS 自定义绑定

作者:Mike Wooten
10/30/2007

本文将提供一系列关于JAX-WS自定义绑定的教程——这些教程是JAX-WS规范的一部分,主要涵盖WSDL到Java映射。其中多处提到了JAXB自定义绑定。

教程列表

介绍 JAX-WS 自定义绑定之后,本文将通过以下教程介绍如何执行各种自定义任务:

然后,我将在示例代码中演示如何使用JAX-WS和JAXB自定义绑定的结果。自定义绑定适用于服务使用者和服务提供者,因此示例代码中将反映以下内容:

JAX-WS 自定义绑定简介

JAX-WS自定义绑定是JAX-WS规范的一部分,主要涵盖WSDL到Java映射。JAXB规范中有一个类似的部分涵盖了XSD到Java映射。

这已经足够好了,可是为什么还要控制WSDL到Java(或XSD到Java)映射呢?我将使用您最近可能遇到的一些场景来解答这个问题。

  1. 假设有一个WSDL使用 parameters 值作为每个 <message><part> 元素的 name 属性。您的JAX-WS工具将抱怨它们无法通过此WSDL生成JAX-WS工件,原因是 name 属性的值不是惟一的。可以通过将 ?WSDL 链接到服务端点来获取WSDL,托管服务端点的一方已经声明自己不能控制WSDL,因为WSDL将“自动”生成。

    通过自定义绑定可以保证 name 属性的惟一性,从而解决此问题。

  2. 某个项目需要使用JAX-WS Web服务的Java方法名和参数匹配由公司体系结构团队生成UML工件。要实现这一点,需要修改发给合作伙伴的WSDL,而您无法完成这一操作。

    通过自定义绑定,您可以将JAX-WS Web服务中的方法签名(比如说,方法名和输入参数)与UML工件中的内容相匹配。

  3. 您的团队的这样一个策略:通过XML模式生成的所有类 必须在完全限定名中包含以下内容,以便于指定:

    • 英文单词“schemas”
    • 表示版本的4位数年份,以小写字母x开头(比如说,x2007)
    • 表示版本的2位数月份,以小写字母x开头(比如说,x09)
    • XML模式的.xsd文件名称

    通过自定义绑定,您可以指示JAXB工具满足这一需求(当它们生成JAXB类时)。

以上只是可以(需要)使用自定义绑定的场景中的一部分。我将在本文中讨论如何完成这些操作,因此我将从最基本的定义开始。

通常,人们更愿意将自定义绑定称作 绑定声明,因此本文其余部分将使用后面这个术语。从本质上说,绑定声明就是使用XML表示的一组“指令”,这些指令既可以嵌入WSDL或XML模式文件,也可存放在外部XML文件中。对于后者,将使用XPath表达式选择WSDL或XML模式文件中的目标内容。基于XML文件的方法是SOA架构师和开发人员的首选,因为它可以提供灵活性同时又不会牺牲可维护性或治理能力。

绑定声明是一组XML元素,由Sun的 wsimport Ant任务进行处理。在第一篇文章中,我已经指出BEA的Ant任务(即 jwscwsdlcclientgen)将从内部调用 wsimport 任务。在与本文相关的代码中,我将在使用BEA的 wsdlc Ant任务。因此我将wsdlc包含在 run-wsdlc Ant目标中:

<target name="run-wsdlc" depends="clean">

   <taskdef name="wsdlc" classname="weblogic.wsee.tools.anttasks.WsdlcTask" classpathref="compile.classpath" />

   <mkdir dir="${src.dir}"/>
    
                        
<property name="binding.declaration.files" value="server-jaxws.xbd,shared-jaxb.xbd"/>
<wsdlc
type="JAXWS"
srcWsdl="etc/${wsdl.file.name}.wsdl" destJwsDir="WebContent/WEB-INF/lib" destImplDir="${src.dir}" explode="false" verbose="${verbose}" debug="${debug}" failonerror="true" >
<binding dir="etc" includes="${binding.declaration.files}"/>
<classpath> <path refid="compile.classpath"/> </classpath> </wsdlc> </target>

此处,我们需求讨论一下 type="JAXWS" 属性和 <binding>子元素。绑定声明位于 <binding> 元素的 includes 属性所指定的文件中。我使用.xbd(表示XML绑定声明)作为文件扩展名。 type="JAXWS"属性通知 wsdlc Ant任务将文件传递给 wsimport Ant任务。

<property> 元素用于保存所使用的两个绑定自定义文件的名称。第一个文件(名称为 etc/server-jaxws.xbd)用于服务提供者端的JAX-WS绑定声明。第二个文件(名称为 etc/shared-jaxb.xbd)与JAXB相关,并且同时用于服务提供者端和服务使用者端。

使用JAX-WS绑定声明可以完成的任务

使用JAX-WS可以指定WSDL中的信息如何映射到为JAX-WS Web服务和JAX-WS Web服务使用者生成的Java代码。这种Java代码包括:

  • SEI提供者接口类

  • 实现SEI提供者接口类的框架类(框架类)

  • 框架类中所使用的方法和参数的名称

  • 用于报错的异常类

  • 在Web服务的方法签名中使用 java.util.Vector,而不是 java.util.List*

  • 为Java对象生成的子类、超类和超接口,作为某个Web服务的返回值和输入参数*

  • 生成的 enum 类和指派给其成员的值*

*使用JAXB绑定自定义文件完成

本文下一部分将介绍如何通过JAX-WS 绑定声明完成上述非星号项目。

JAX-WS绑定声明的使用

现在,我将介绍JAX-WS绑定声明的一些使用方法。

使用JAX-WS绑定声明指定Java包名

这种绑定声明与JAXB结合可能比与JAX-WS结合具有很大的价值,但是我们不能因此而否认它的重要性。

我在第一篇文章中介绍过通过JAXB实现这种绑定声明。本文将继续介绍通过JAX-WS实现这种绑定声明。使用目的仍然相同: 即控制生成类的Java包名。下面是 shared-jaxb.xbd 绑定声明文件的内容(用于指定通过XML模式文件生成的类的Java包名):

<jxb:bindings

  version="1.0"

  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"

>

    <jxb:bindings

       xmlns:xs="http://www.w3.org/2001/XMLSchema"
        
                        
schemaLocation="datastaging_exceptions.xsd"
node="/xs:schema" > <jxb:schemaBindings>
<jxb:package name="services.datastaging.exceptions"/>
</jxb:schemaBindings> </jxb:bindings> </jxb:bindings>

使用这个 shared-jaxb.xbd 文件将导致通过 datastaging_exceptions.xsd 文件生成的所有JAXB类的Java包名都使用 services.datastaging.exceptions。如果没有指定绑定声明文件,则类的Java包名将以 datastaging_exceptions.xsd 文件中的( <schemas> 元素的) targetNamespace 属性为基础。

注意:不要在 wsdlcjwscclientgen Ant任务上使用 package 属性。此操作将覆盖绑定声明文件中的 <package>绑定声明。

如果您的XML模式文件使用了 <xs:include><xs:import> 元素,那么事情将更具挑战。如果含有 <xs:schema> 的 WSDL 使用了 <xs:import> 元素也同样如此。不管哪种情况,您都希望使用JAXB绑定声明文件指定Java包名。以下是的JAXB绑定声明文件的摘录,它演示了如何使用OASIS WS-Notification规范中的 XML 模式实现这一目的。

<jxb:bindings

  version="1.0"

  xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 

>

  <jxb:bindings

    xmlns:xs="http://www.w3.org/2001/XMLSchema"

     
                        
schemaLocation="schemas/oasis-wsn13.xsd"

node="/xs:schema"
> <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
node="//xs:schema/xs:import[@namespace='http://docs.oasis-open.org/wsn/b-2']"
> <jxb:schemaBindings> <jxb:package name="org.oasis_open.docs.wsn.b_2"/> </jxb:schemaBindings> </jxb:bindings> <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
node="//xs:schema/xs:import[@namespace='http://docs.oasis-open.org/wsn/br-2']"
> <jxb:schemaBindings> <jxb:package name="org.oasis_open.docs.wsn.br_2"/> </jxb:schemaBindings> </jxb:bindings> <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
node="//xs:schema/xs:import[@namespace='http://docs.oasis-open.org/wsn/t-1']"
> <jxb:schemaBindings> <jxb:package name="org.oasis_open.docs.wsn.t_1"/> </jxb:schemaBindings> </jxb:bindings> ... </jxb:bindings> </jxb:bindings>

请注意黑体部分, node 属性中的XPath表达式使内容具有可单击特性。第一个嵌套的 <jxb:bindings> 元素包含 schemaLocation 属性,该属性设置使用XML模式文件。其他嵌套 <jxb:bindings> 元素的 node 属性用于处理XML模式文件中的各种 <xs:import> 元素。

一个绑定声明文件中可以嵌入多个含有 schemaLocation 属性的 <jxb:bindings> 元素。如果对于模块性和易重用性的要求比较高,则不适合使用此方法。为每个XML模式都使用一个单独的绑定声明可提高易用性等方面。此外,还可以更容易地将它们组织到可重用的软件资产中,以实现治理目的。

页面: 1, 2, 3

下一页 »