JAX-WS Customization

介紹

在以前的文章中,有一篇關於HandlerChain的介紹。當時HandlerChain使用的是Java Annotation方式註冊到WebService上的。咱們也能夠使用JAX-WS提供的針對WSDL的customization,來配置HandlerChain。JAX-WS的規範中,定義了針對WSDL的customization,能夠對如下內容進行定製:java

  1. Package namenode

  2. Wrapper styletomcat

  3. Asynchronyapp

  4. Provider interfacemaven

  5. Classide

  6. Java method網站

  7. Java parameterthis

  8. Java docurl

  9. XML schemaspa

  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);
    }
}
相關文章
相關標籤/搜索