在以前的文章中,有一篇關於HandlerChain的介紹。當時HandlerChain使用的是Java Annotation方式註冊到WebService上的。咱們也能夠使用JAX-WS提供的針對WSDL的customization,來配置HandlerChain。JAX-WS的規範中,定義了針對WSDL的customization,能夠對如下內容進行定製:java
Package namenode
Wrapper styletomcat
Asynchronyapp
Provider interfacemaven
Classide
Java method網站
Java parameterthis
Java docurl
XML schemaspa
Handler chain
這些customization,能夠對wsimport產生影響。wsimport會根據WSDL+Customization產生出定製化的實現類。
Customization有兩種聲明方式:
External, 即脫離WSDL文件,單獨放在一個外部文件中。
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); } }