JAX-WS Customization

介绍

在之前的文章中,有一篇关于HandlerChain的介绍。当时HandlerChain使用的是Java Annotation方式注册到WebService上的。我们也可以使用JAX-WS提供的针对WSDL的customization,来配置HandlerChain。JAX-WS的规范中,定义了针对WSDL的customization,可以对以下内容进行定制:

  1. Package name

  2. Wrapper style

  3. Asynchrony

  4. Provider interface

  5. Class

  6. Java method

  7. Java parameter

  8. Java doc

  9. XML schema

  10. Handler chain

这些customization,可以对wsimport产生影响。wsimport会根据WSDL+Customization产生出定制化的实现类。

声明

Customization有两种声明方式:

  1. External, 即脱离WSDL文件,单独放在一个外部文件中。

  2. Embedded,内嵌在WSDL文件中。

Embedded方式跟External方式均必须放置在如下XML节点中:

<jaxws:bindings xmlns:jaxws="">
</jaxws:bindings>

不同的是,在外部声明方式中,需要指明wsdl的位置,也需要指明customization所针对的wsdl中的节点。embedded方式就没有这种烦恼了。

外部声明示例:

<jaxws:bindings
        wsdlLocation="http://127.0.0.1:8080/library/service?wsdl"
        jaxws:xmlns="http://java.sun.com/xml/ns/jaxws">
    <jaxws:bindings node="wsdl:definitions"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
        <jaxws:package name="external_customize.client"/>
        ...
    </jaxws:bindings>
</jaxws:bindings>

接下来,我将给出一个实例。下面的实例。

实例

说明

在JAXWS的官方网站中,提供了一个配置Provider的实例。实例对客户端接口进行了定制,修改各种名字,以表现的像本地API。我以此为例做解释。

服务端

在服务端,提供了一个加法服务。只对正数提供服务,负数会抛异常。

@WebService (serviceName = "AddNumbersService", targetNamespace = "http://duke.example.org")
public class AddNumbersImpl {
    
    /**
     * @param number1 must be > 0
     * @param number2 must be > 0
     * @return The sum
     * @throws AddNumbersException
     *             if any of the numbers to be added is negative.
     */
    public int addNumbers (int number1, int number2) throws AddNumbersException {
        if(number1 < 0 || number2 < 0){
            throw new AddNumbersException ("Negative number cant be added!", "Numbers: "+number1+", "+number2);
        }
        return number1 + number2;
    } 
}

异常

@javax.xml.ws.WebFault(name = "AddNumbersException", targetNamespace = "http://duke.example.org")
public class AddNumbersException extends Exception {
    String info;

    public AddNumbersException(String message, String detail) {
        super(message);
        this.info = detail;
    }

    public String getFaultInfo() {
        return info;
    }
}

打包部署

首先,使用wsgen命令,生成相应的WSDL文件和一系列的JAXB所需类文件。

然后创建sun-jaxws.xml

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
    <endpoint
        name='numbers'
        implementation='com.mycompany.AddNumbersImpl'
        url-pattern='/addNumbers'/>
</endpoints>

然后打包部署到tomcat中。

客户端

在使用wsimport生成客户端之前,先创建customization文件,将原SEI重命名。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="http://localhost:8080/library/addNumbers?wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <package name="external_customize.client"/>
    <!-- default settings -->
    <enableWrapperStyle>true</enableWrapperStyle>
    <enableAsyncMapping>false</enableAsyncMapping>

    <!-- wsdl:portType customization -->
    <bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']">
        <!-- change the generated SEI class -->
        <class name="MathUtil"/>
        
        <!-- you can also override the following customization settings -->
        <enableWrapperStyle>true</enableWrapperStyle>
        <enableAsyncMapping>false</enableAsyncMapping>
    </bindings>
    
    <!-- wsdl:portType operation customization -->    
    <bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']">
        <!-- change java method name from addNumbers() to add() -->
        <method name="add"/>   
                
        <!-- rename method parameters-->           
        <parameter part="wsdl:definitions/wsdl:message[@name='addNumbers']/wsdl:part[@name='parameters']" childElementName="tns:number1" name="num1"/>
        <parameter part="wsdl:definitions/wsdl:message[@name='addNumbers']/wsdl:part[@name='parameters']" childElementName="tns:number2" name="num2"/>      
         
         <!-- you can also override the following customization settings -->
        <enableWrapperStyle>true</enableWrapperStyle>
        <enableAsyncMapping>false</enableAsyncMapping>
    </bindings> 
    
    <!-- change the generated exception class name -->
    <bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']/wsdl:fault[@name='AddNumbersException']">
        <class name="MathUtilException"/>
    </bindings>
    
    <!-- wsdl:service customization -->
    <bindings node="wsdl:definitions/wsdl:service[@name='AddNumbersService']">
        <!-- change the generated service class -->
        <class name="MathUtilService"/>
    </bindings>
    
    <!-- change the port accessor method -->
    <bindings node="wsdl:definitions/wsdl:service[@name='AddNumbersService']/wsdl:port[@name='AddNumbersImplPort']">
        <method name="getMathUtil"/>
    </bindings>    
</bindings>

然后使用wsimport命令创建客户端实现类:

在maven中,命令如下:

          <execution>
            <id>wsimport-from-jdk</id>
            <goals>
              <goal>wsimport</goal>
            </goals>
            <configuration>
              <executable>${tool.wsimport}</executable>
              <wsdlUrls>
                <wsdlUrl>http://localhost:8080/library/addNumbers?wsdl</wsdlUrl>
              </wsdlUrls>
              <bindingFiles>
                <bindingFile>/pathTo/custom-client.xml</bindingFile>
              </bindingFiles>
              <verbose>true</verbose>
              <xdebug>true</xdebug>
            </configuration>
          </execution>

运行maven命令 mvn generate-sources, 可以生成所有的java文件。

引入生成的java文件,编写client,调用client端的service。

public class AddNumbersClient {
    private MathUtil port;
    
    public AddNumbersClient () {
        port = new MathUtilService().getMathUtil ();
    }
    
    public static void main (String[] args) {
        try {
            AddNumbersClient client = new AddNumbersClient ();
            
            //invoke synchronous method
            client.invoke ();
        } catch(MathUtilException e){
            System.out.println ("\tException detail: "+ e.getMessage ()+", "+e.getFaultInfo ());
        }
    }
    
    private void invoke () throws MathUtilException{
        int number1 = 10;
        int number2 = 20;
        
        System.out.printf ("Invoking addNumbers(%d, %d)\n", number1, number2);
        int result = port.add (number1, number2);
        System.out.printf ("The result of adding %d and %d is %d.\n\n", number1, number2, result);
        
        //lets make endpoint throw exception
        number1 = -10;
        System.out.printf ("Invoking addNumbers(%d, %d) and expect exception.\n", number1, number2);
        result = port.add (number1, number2);
    }
}


你可能感兴趣的:(Complex,jaxws,Customization,bindings)