跳到导航
dev2dev.bea.com.cn
首页 资源中心 dev2dev学堂 在线技术论坛 专家Blog User Group CodeShare
dev2dev 首页 > 资源中心 > 技术文章
在Weblogic Server 10中使用JAX-WS和JAXB:JAX-WS自定义绑定

时间:2008-03-12
作者:Mike Wooten
浏览次数:
本文关键字:jax-ws jaxb web services WebLogic Server Web Services XML WebLogic Server Web服务
文章工具
推荐给朋友 推荐给朋友
打印文章 打印文章

摘要

  在WebLogic Server 10中使用JAX-WS和JAXB 这篇文章介绍了BEA WebLogic Server 10中可用的JAX-WS Web服务栈和JAXB Java/XML绑定技术。这些实现基于Glassfish JAX-WS 2.0Glassfish JAXB 2.0 项目中的JAR文件。

  本文将提供一系列关于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)映射呢?我将使用您最近可能遇到的一些场景来解答这个问题。

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

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

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

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

  • 您的团队的这样一个策略:通过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任务(即jwsc、wsdlc和clientgen)将从内部调用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.exception。如果没有指定绑定声明文件,则类的Java包名将以datastaging_exceptions.xsd文件中的(<schemas>元素的)targetNamespace属性为基础。

  注意:不要在wsdlc、jwsc或clientgen 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模式都使用一个单独的绑定声明可提高易用性等方面。此外,还可以更容易地将它们组织到可重用的软件资产中,以实现治理目的。

  使用JAX-WS绑定声明指定SEI提供者接口类名

  类绑定声明用于为SEI(Service Endpoint Implementation,服务端点实现)指定提供者接口类。以下内容摘录自etc/server-jaxws.xbd文件,它展示了如何使用类绑定声明实现此目的。

<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"

...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:portType[@name = 'DataStaging']"
>
<jxb:javadoc>
          <![CDATA[Name of Provider interface class for JAX-WS DataStagingService.]]>
        </jxb:javadoc>
<class name="DataStagingService2"/>
</bindings>
... </bindings>

  此处,我向wsimport Ant任务指定生成的SEI接口类的名称为DataStagingService2。wsdlLocation属性指定了要处理的WSDL文件的位置。此位置与绑定声明文件的位置有关,因此前面没有任何路径。XPath表达式选择WSDL中的portType元素,生成的接口类的名称就是由此而来(默认情况)。

  您将在WebContent/WEB-INF/lib/DataStagingService2_wsdl.jar文件中发现最终的services.datastaging.DataStaging2.java文件。

  使用JAX-WS绑定声明指定框架SEI类名

  还可以使用类绑定声明控制框架Java源文件(由wsimport Ant任务生成)的名称(执行wsdlc Ant任务时发生)。所使用类绑定声明与用于其他目的的类绑定声明是一样的,因此不必感到迷惑。

  我通过类绑定声明指定etc/server-jaxws.xbd文件中的框架Java源文件的名称。以下是绑定声明文件的摘录:

 <bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"

...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:service[@name = 'DataStagingService']"
>
<jxb:javadoc>
<![CDATA[Name of skeleton SEI class for JAX-WS DataStagingService.]]>
</jxb:javadoc>
<class name="DataStagingPortTypeImpl"/>
</bindings>
...
</bindings>
黑体字表示重点内容。它们告诉wsimport Ant任务您希望框架类的名称为DataStagingPortTypeImpl。如果没有定义此绑定声明,则所生成框架类的名称将以WSDL中的<service>元素的name属性的值为准。

  遗憾的是,通过以上操作并不能生成预期的输出。原因如下:

  1. 所生成的DataStagingPortTypeImpl类的Java包名最终为com.acmeworld.irad.services.datastaging,而不是services.datastaging。我尝试使用<package>services.datastaging</package>绑定声明,又通过node="wsdl:definitions"属性绑定<jaxws:bindings>元素。两种方法均不奏效。
  2. 扩展了javax.xml.ws.Service的JAX-WS类的名称也是DataStagingPortTypeImpl。该类由服务使用者使用,因此我“没有管它”(因为我在提供者端)。
  3. 如果指定一个方法绑定声明修改Web服务操作的名称,这些修改并不会传递给第1条中所生成的DataStagingPortTypeImpl类。似乎通过参数绑定声明进行的修改也不具有传递性。

我认为所有这些异常都是由wsdlc或wsimport Ant任务所使用的一个类中的bug造成的。这些异常并不会带来什么副作用,因此我选择使用Ant <replace>任务操作生成的框架SEI Java源来解决此问题。

  注意:BEA技术支持部门已经记录上述问题,此bug将在WebLogic Server 10补丁或未来的服务包中得到“永久解决”。

  使用JAX-WS绑定声明指定方法名

  我们可以通过方法绑定声明控制生成代码中的方法名称。生成的Java源代码中的代理类(扩展了javax.xml.ws.Service)的getter方法便是可以修改的方法之一。以下是etc/client-jaxws.xbd文件中与之相关的内容。该内容同样出现于etc/server-jaxws.xbd文件中:

  <bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"

...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:service[@name = 'DataStagingService']/wsdl:port[@name = 'DataStagingServicePort']"
>
<jxb:javadoc>
<![CDATA[Returns proxy object used as the Dynamic Proxy client API when invoking Web service operations on the DataStagingServiceWeb service.]]>
</jxb:javadoc>
<method name="getDataStagingPort"/>
</bindings>
... </bindings>

  上述代码将getter方法名称从getDataStagingServicePort(默认名称)修改为getDataStagingPort。您将在test.consumers.datastaging.standalone.jaxws.DataStagingService.java文件中找到结果,该文件位于lib/UC-01Client.jar文件中。

  还可以修改Web服务操作所使用的方法名:

 <bindings

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

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

  wsdlLocation="DataStagingService2.wsdl"

  > 

  ...

  <bindings

  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

  node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']"

  >

  <jxb:javadoc>

  <![CDATA[Sends URIs of resources to be staged]]>

  </jxb:javadoc>

  <method name="sendInputURIs"/>

  </bindings>

  ...

  </bindings>

  

在上述代码中,我使用方法绑定声明将dataStaging Web服务操作的名称修改为sendInputURIs。您将在test.consumers.datastaging.standalone.jaxws.DataStaging.java文件中找到结果,该文件位于lib/UC-01Client.jar文件中。

  使用JAX-WS绑定声明指定方法参数名

  我们可以通过参数绑定声明控制框架SEI类的访问所使用的参数名称。它使用:

  • 含有XPath表达式的part属性查找要修改的参数名称。
  • element属性在WSDL中选择<part>元素。
  • name属性指定参数的新名称。

以下是etc/server-jaxws.xbd文件中的相关内容:

  <bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"

...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://services.irad.acmeworld.com/datastaging"
node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']"
>
<jxb:javadoc>
<![CDATA[Input parameter for the dataStagingmethod.]]>
</jxb:javadoc>
<parameter
          part="wsdl:definitions/wsdl:message[@name='dataStaging']/wsdl:part[@name='parameters']"
          element="tns:dataStaging"
          name="inputURIs"
       />
</bindings>
...
</bindings>

  之前,我使用类绑定声明将方法名从dataStaging修改为sendInputURIs。此处,我尝试使用参数绑定声明将参数名从parameters修改为inputURIs。可是并没有生效,其原因似乎与下面这个重大发现有关:.

  如果文件中还有一个<enableWrapperStyle>true</enableWrapperStyle>绑定声明,则参数绑定声明不会起作用。

  原来<enableWrapperStyle>true< enableWrapperStyle>绑定声明会“自动”导致参数名称被修改为inputURIs。我决定在服务使用者端使用<enableWrapperStyle>false</enableWrapperStyle>取代它。这样,我至少还可以演示parameters绑定声明的使用。

  使用JAX-WS绑定声明指定异常类名

  我们还可以通过类绑定声明控制框架SEI类中的方法所使用的异常类的名称。 以下是etc/server-jaxws.xbd文件中与之相关的内容:

  <bindings

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

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

  wsdlLocation="DataStagingService2.wsdl"

  > 

  ...

  <bindings

  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

  node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']/wsdl:fault[@name='JAXWSArticleException']"

  >

  <jxb:javadoc>

  <![CDATA[General purpose exception for JAX-WS DataStagingService.]]>

  </jxb:javadoc>

  <class name="DataStagingServiceException"/>

  </bindings>

  ...

  </bindings>

  这样将导致生成一个DataStagingServiceException类。它将存放在WebContent/WEB-INF/lib/DataStagingService2_wsdl.jar文件的services.datastaging目录中。

使用JAX-WS绑定声明指定异步

  JAX-WS规范定义了两个范例,用于编写异步客户机:

  • 探询(Polling)   此范例将使用探询判断响应是否可用。来自operationAsync方法调用的返回类型为javax.xml.ws.Response对象的实例。此javax.xml.ws.Response对象中的方法具有以下功能:
    1. 取消调用。
    2. 无限期阻塞,等待服务器响应。
    3. 阻塞一段时间,等待服务器响应。
    4. 确定调用是否取消。
    5. 确定调用是否完成,以便随后获得响应。
  • 回调(Callback)   在此范例中,客户机将提供一个回调处理程序用于接收和处理传入响应对象。此回调处理程序需求实现javax.xml.ws.AsyncHandler接口,其中含有一个void handleResponse(Response)回调方法。javax.xml.ws.AsyncHandler扩展了javax.xml.ws.Response,但是您只需要使用get()方法。

当请求在服务提供者端进行处理时,两个范例都允许JAX-WS客户机继续执行工作。以下内容摘录自etc/client-jaxws.xbd文件,它展示了如何指定<enableAsyncMapping>绑定声明:

  <bindings

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

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

  wsdlLocation="DataStagingService2.wsdl"

  > 

  ...

  <bindings

  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

  node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']"

  >

  <enableAsyncMapping>true</enableAsyncMapping>

  </bindings>

  ...

  </bindings>

  

  这样只会生成一个异步版本的dataStaging方法。如果希望所有方法都有异步版本,需要将<enableAsyncMapping>true</enableAsyncMapping>移到到最初的位置。异步方法将位于test.consumers.datastaging.standalone.jaxws.DataStaging.java文件中,该文件作为JAR文件打包在lib/UC-01Client.jar文件中。

使用JAX-WS绑定声明指定处理程序链

  我们可以通过<javaee:handler-chains>绑定声明指定生成的JSR-181 (Web Services Metadata for the Java Platform) 工件。它可以:

  1. 生成处理程序链XML配置文件
  2. 在生成的代码中插入javax.jws.HandlerChain注释。

  以下内容摘录自我在服务提供者端使用的<javaee:handler-chains>绑定声明:

<bindings
   xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
   xmlns="http://java.sun.com/xml/ns/jaxws"
   wsdlLocation="DataStagingService2.wsdl"
> 
    ...
    <bindings
       xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
       node="wsdl:definitions"
    >
       <javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee">
          <javaee:handler-chain>
             <javaee:handler>
                <javaee:handler-name>VendorSOAPHandler</javaee:handler-name>
                <javaee:handler-class>services.datastaging.VendorSOAPHandler</javaee:handler-class>
             </javaee:handler>
          </javaee:handler-chain>
       </javaee:handler-chains> 
    </bindings>
    ... 
</bindings> 

  编写JAX-WS处理程序是一个相当棘手的过程,因此本文将略过这一点。大家只需注意VendorSOAPHandler类将处理SOAP报头,该报头由服务使用者端的JAX-WS处理程序生成。有关如何编写JAX-WS处理程序的深入信息,请阅读Young Yang的 "Get a handle on the JAX-WS API's handler framework" 这篇文章。

使用绑定声明示例JAX-WS代码

  至此,我已经介绍了绑定声明文件的作用。下面,我将介绍有关服务使用者和服务提供者的一些示例代码:

  • 运行BEA wsdlc Ant任务时生成的代码
  • 使用运行BEA wsdlc Ant任务时生成的JAX-WS工件的代码

示例JAX-WS代码——在服务提供者中使用绑定声明

  本文与第一篇文章中所使用服务提供者代码完成不同了。关键的区别包括:

  • 从“从Java开始”编程模型转换到“从WSDL开始”编程模型。
  • 我添加了一个绑定声明,将Web服务操作的名称从dataStaging修改为sendInputURIs。
  • 我添加了一个绑定声明,使包装器样式类型在生成的框架SEI类中使用。
  • 我添加了一个绑定声明,将生成的SEI接口类的名称修改为DataStagingService2。
  • 我添加了一个绑定声明,以控制所添加的Exception类的新名称(DataStagingServiceException)。
  • 我添加了一个AX-WS SOAP处理程序,以处理服务使用者端JAX-WS SOAP处理程序添加的Vendor SOAP Header。

  BEA wsdlc Ant任务生成的框架SEI类比较小,因此我决定完整地列出它的内容:

package services.datastaging;  

import javax.jws.WebService; 
import javax.xml.ws.BindingType; 
import javax.jws.HandlerChain;  

/**  
* services.datastaging.DataStagingServiceImpl class implements web service endpoint interface services.datastaging.DataStagingService2 
*/  

@WebService(
   portName="DataStagingServicePort",
   serviceName="DataStagingService",
   targetNamespace="http://services.irad.acmeworld.com/datastaging",
   endpointInterface="services.datastaging.DataStagingService2",
   wsdlLocation="/wsdls/DataStagingService2.wsdl"
) 
@BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http") 
@HandlerChain(
   file="jar:file:WebContent/WEB-INF/lib/DataStagingService2_wsdl.jar!/services/datastaging/DataStagingService2_handler.xml"
) 
public class DataStagingServiceImpl implements services.datastaging.DataStagingService2 
{
    public DataStagingServiceImpl() 
    {   
    }

    public com.acmeworld.irad.services.datastaging.DataStagingResponse.OutputURIs sendInputURIs(com.acmeworld.irad.services.datastaging.DataStaging.InputURIs inputURIs)
      throws services.datastaging.DataStagingServiceException 
    {
        //replace with your impl here
        return null;
    }
} 

  每次运行BEA wsdlc Ant任务时,这个框架SEI类都会被重写。因此,我们需要防止意外运行所造成的代码损失。最安全的方法是定期备份该文件。另一种方法是将build.xml文件中出现的所有depdends属性的run-wsdlc Ant目标删除。

示例JAX-WS代码——在服务使用者中使用绑定声明

  在第一篇文章中,我在JAX-WS客户机代码中使用了Dispatch client API 方法。在本文中,我选择使用Dynamic Proxy client API 方法。Dynamic Proxy client API涉及使用BEA clientgen Ant所生成的服务代理类。Ant任务将从内部调用Sun wsimport Ant任务。

  项目的etc/client-jaxws.jbd文件中包含服务使用者端使用的绑定声明。这些绑定声明的作用是:

  1. 在服务代理类中生成异步方法。我在示例JAX-WS客户机中使用这些方法异步地调用SEI方法。
  2. 修改服务代理接口类中所使用的方法的名称。
  3. 修改服务代理接口类中所使用的参数的名称。
  4. 为使用者端JAX-WS处理程序链生成JSR-181工件。

  以下是执行异步方法调用的代码:

         ... 
         DataStagingService service = new DataStagingService();

         service.setExecutor(Executors.newSingleThreadExecutor()); 

         DataStaging port = service.getDataStagingServicePort();        
               ... 

  这段代码演示了如何使用一个单线程的线程模型调用void类型的handleResponse(Response) 回调方法。客户机的java.xml.ws.Service实例中的setExecutor() 方法用于指定该方法。下面是实现javax.xml.ws.AsyncHandler接口的代码片断:

... 
private class ClientCallback implements AsyncHandler 
{
     public void handleResponse(Response response)
     {
         try
         {
           log("handleResponse(Response)", (new StringBuffer()).append("Callback method was invoked.").toString());

           printDataStagingResponse(response.get());
         }
         catch (Exception e)
         {
             e.printStackTrace();
         }
     }
}
... 

  通过阅读这些教程,我们已经了解使用绑定声明可以实现许多操作。教程还提供了关于如何在WebLogic Server 10中使用它们的详细步骤。提供这些信息的原因有以下两个:

  • 我发现一些用户在BEA NewsWeb新闻组网站上发表了一些问题,但是都没有得到回复。如果在WebLogic Server 10中使用JAX-WS和JAXB遇到了任何问题,用户可通过该站点寻求帮助。我使用本文回答了其中的部分问题,同时传播了一些关于使用WebLogic Server 10进行JAX-WS开发的知识。
  • 我希望提供一些资料作为Sun提供文档的“补充参考”(关于此主题)。

  当您在WebLogic Server 10中使用JAX-WS实现遇到问题时,这些内容足以解决大多数问题,从而减少Google搜索的使用数量。

  Using the Table of Tutorials is the recommended way to go directly to the use case you need to implement.

下载

  • 本文的 示例代码。Zip文件中有一个README文档,其中介绍了安装和配置示例代码的详细步骤。

结束语

  JAX-WS绑定声明为您提供了一种强大的机制,用于影响和改变由Sun wscompile和wsimport Ant任务生成的工件。这些绑定声明可以嵌入到WSDL中,或者存放含有XML文档(符合XML模式,名称空间为http://java.sun.com/xml/ns/jaxws)的文件中。推荐使用存放在文件中的方法。

  WebLogic Server 10 Web服务栈所提供的BEA Ant任务(即clientgen、wsdlc和jwsc)可从内部调用上面提到的Sun Ant任务。您可以使用它们所提供的<binding子元素指定要使用的JAX-WS(和/或JAXB)绑定声明。

  拥有这种控制很好,但是它确实带来了成本的复杂性问题。Java EE开发曾被认为是“过度复杂的”,而JAX-WS绑定声明也并未有所改变。在文本编辑器中“手动编写”JAX-WS绑定声明文件并不是大多Java开发人员所乐意的,并且还需要较好的IDE支持。

展望未来

  本系列的最后一篇文章将介绍 Glassfish JAX-WS Commons 项目中的一些高级功能。我的研究表明该项目中的JAR文件可以与Glassfish JAX-WS 2.0中的JAR文件一起使用,前提是Glassfish JAX-WS 2.0中的JAR文件可以在WebLogic Server 10使用。我将主要介绍以下内容:

  • 使用Spring beans作为服务实现。
  • 使用Spring配置框架创建可同时支持多种绑定类型的JAX-WS服务。javax.xml.ws.BindingType注释只允许您使用其中之一。
  • 在WebLogic Server 10上创建、托管和调用REST服务。它们并不是“真正”的REST服务,并不是使用HTTP GET方法和长查询字符串的HTTP端点。
  • 在WebLogic Server 10上创建、托管和调用JSON (Java-Script Object Notation) 服务。
  • 创建调用JSON服务的JSON服务使用者。

  敬请期待。

参考资料

  有关本文所讨论主题的其他信息,请阅读以下文章:

原文出处:http://dev2dev.bea.com/pub/a/2007/10/jax-ws-jaxb-customization.html

 作者简介
Mike Wooten 是BEA享有声望的技术解决方案小组(Technical Solutions Group,TSG)的一名高级首席解决方案工程师。他的工作时间都在帮助将BEA客户的抽象技术概念转变为能创造价值的解决方案。这些解决方案所提供的功能往往令其竞争者们望尘莫及。
dot dot dot

dot
  作者其它文章
您对本文的评价
您对这篇文章的看法如何?
太棒了!5分 不错啊 4分 一般般 3分 有待提高 2分 不好 1分

   
相关产品
相关技术