鲁春利的工作笔记,好记性不如烂笔头
WebService只是向客户端暴露WSDL,客户端需要将WSDL转换为相应编程语言书写的代码。JAX-WS的各种实现都提供相应的工具进行WSDL与JAVA之间的相互转换,在CXF的bin目录下提供了多种转换的支持。
E:\mvtech\apache-cxf-3.1.4\bin>ls -l|grep bat -rwxrwxrwx 1 user group 1815 Oct 31 04:06 idl2wsdl.bat -rwxrwxrwx 1 user group 1815 Oct 31 04:06 java2js.bat -rwxrwxrwx 1 user group 1819 Oct 31 04:06 java2ws.bat -rwxrwxrwx 1 user group 1789 Oct 31 04:06 mc.bat -rwxrwxrwx 1 user group 1836 Oct 31 04:06 wadl2java.bat -rwxrwxrwx 1 user group 1826 Oct 31 04:06 wsdl2corba.bat -rwxrwxrwx 1 user group 1836 Oct 31 04:06 wsdl2java.bat -rwxrwxrwx 1 user group 1786 Oct 31 04:06 wsdl2js.bat -rwxrwxrwx 1 user group 1987 Oct 31 04:06 wsdl2service.bat -rwxrwxrwx 1 user group 1823 Oct 31 04:06 wsdl2soap.bat -rwxrwxrwx 1 user group 1823 Oct 31 04:06 wsdl2xml.bat -rwxrwxrwx 1 user group 1821 Oct 31 04:06 wsdlvalidator.bat -rwxrwxrwx 1 user group 1821 Oct 31 04:06 xsd2wsdl.bat # 通过-h参数可以查看帮助 E:\mvtech\apache-cxf-3.1.4\bin>wsdl2java.bat -h
其中wsdl2java.bat可以通过使用URL?wsdl,将WSDL转换为Java类。
常用参数为:
-encoding utf-8 指定生成的文件编码格式 -d path 指定生成的java文件存储路径 -p com.lucl.... 指定生成的java文件包名 wsdlurl 指定WSDL的文件路径,如 -client 生成客户端测试web service的代码; -server 生成服务器启动web service的代码; -impl 生成web service的实现代码; -ant 生成build.xml文件; -all 生成所有开始端点代码; 示例: E:\mvtech\apache-cxf-3.1.4\bin>wsdl2java.bat -d F:\\ftpfile\\src -p package -V wsdlurl Loading FrontEnd jaxws ... Loading DataBinding jaxb ... wsdl2java -d F:\\ftpfile\\src -p 包全限定名 -V http://localhost:9000/helloWorld?wsdl wsdl2java - Apache CXF 3.1.4 E:\mvtech\apache-cxf-3.1.4\bin> # 或者通过jdk自带的wsimport命令 wsimport -d F:/ftpfile/src -p com.lucl.apps.web.webservice.cxf.client file:/F:/ftpfile/src/GBAService.wsdl
将生成的java类拷贝到eclipse中
HelloWorld.java class,对应WebService标注serviceNmae属性指定的HelloWorldImpl,继承自Service HelloWorldPortType.java interface,对应WebService标注name属性指定的HelloWorld ObjectFactory.java JAXB需要的文件 package-info.java JAXB需要的文件 SayHi.java 对应接口方法sayHi SayHiResponse.java 接口方法sayHi响应数据的封装
1、package-info.java
@javax.xml.bind.annotation.XmlSchema(namespace = "http://server.cxf.webservice.web.apps.lucl.com/") package com.lucl.apps.web.webservice.cxf.client;
看junit的包的时候发现每个包也都有这么一个java文件,具体用途留待后续分析。
2、ObjectFactory.java
提供了获取类实例的工程方法。
package com.lucl.apps.web.webservice.cxf.client; import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.XmlElementDecl; import javax.xml.bind.annotation.XmlRegistry; import javax.xml.namespace.QName; @XmlRegistry public class ObjectFactory { // QName 表示 XML 规范中定义的限定名称 private final static QName _SayHi_QNAME = new QName("http://server.cxf.webservice.web.apps.lucl.com/", "sayHi"); private final static QName _SayHiResponse_QNAME = new QName("http://server.cxf.webservice.web.apps.lucl.com/", "sayHiResponse"); public ObjectFactory() { // ...... } /** * Create an instance of {@link SayHi } * 对应的实际是sayHi方法 */ public SayHi createSayHi() { return new SayHi(); } /** * Create an instance of {@link SayHiResponse } * 对应的实际为sayHiResponse方法 */ public SayHiResponse createSayHiResponse() { return new SayHiResponse(); } /** * Create an instance of {@link JAXBElement }{@code <}{@link SayHi }{@code >}} * */ @XmlElementDecl(namespace = "http://server.cxf.webservice.web.apps.lucl.com/", name = "sayHi") public JAXBElement<SayHi> createSayHi(SayHi value) { return new JAXBElement<SayHi>(_SayHi_QNAME, SayHi.class, null, value); } /** * Create an instance of {@link JAXBElement }{@code <}{@link SayHiResponse }{@code >}} * */ @XmlElementDecl(namespace = "http://server.cxf.webservice.web.apps.lucl.com/", name = "sayHiResponse") public JAXBElement<SayHiResponse> createSayHiResponse(SayHiResponse value) { return new JAXBElement<SayHiResponse>(_SayHiResponse_QNAME, SayHiResponse.class, null, value); } }
3、HelloWorld.java
实际上对应的是WebService的serviceName标记的类(HelloWorldImpl)。
package com.lucl.apps.web.webservice.cxf.client; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.WebEndpoint; import javax.xml.ws.WebServiceClient; import javax.xml.ws.WebServiceFeature; import javax.xml.ws.Service; /** * This class was generated by Apache CXF 3.1.4 * 2015-12-16T18:03:45.079+08:00 * Generated source version: 3.1.4 * */ @WebServiceClient(name = "HelloWorld", wsdlLocation = "http://localhost:9000/helloWorld?wsdl", targetNamespace = "http://server.cxf.webservice.web.apps.lucl.com/") public class HelloWorld extends Service { public final static URL WSDL_LOCATION; public final static QName SERVICE = new QName("http://server.cxf.webservice.web.apps.lucl.com/", "HelloWorld"); public final static QName HelloWorldPort = new QName("http://server.cxf.webservice.web.apps.lucl.com/", "HelloWorldPort"); static { URL url = null; try { url = new URL("http://localhost:9000/helloWorld?wsdl"); } catch (MalformedURLException e) { java.util.logging.Logger.getLogger(HelloWorld.class.getName()) .log(java.util.logging.Level.INFO, "Can not initialize the default wsdl from {0}", "http://localhost:9000/helloWorld?wsdl"); } WSDL_LOCATION = url; } public HelloWorld(URL wsdlLocation) { super(wsdlLocation, SERVICE); } public HelloWorld(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public HelloWorld() { super(WSDL_LOCATION, SERVICE); } public HelloWorld(WebServiceFeature ... features) { super(WSDL_LOCATION, SERVICE, features); } public HelloWorld(URL wsdlLocation, WebServiceFeature ... features) { super(wsdlLocation, SERVICE, features); } public HelloWorld(URL wsdlLocation, QName serviceName, WebServiceFeature ... features) { super(wsdlLocation, serviceName, features); } /** * * @return * returns HelloWorldPortType */ @WebEndpoint(name = "HelloWorldPort") public HelloWorldPortType getHelloWorldPort() { return super.getPort(HelloWorldPort, HelloWorldPortType.class); } /** * * @param features * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values. * @return * returns HelloWorldPortType */ @WebEndpoint(name = "HelloWorldPort") public HelloWorldPortType getHelloWorldPort(WebServiceFeature... features) { return super.getPort(HelloWorldPort, HelloWorldPortType.class, features); } }
4、HelloWorldPortType.java
对应的是Server端的接口HelloWorld。
package com.lucl.apps.web.webservice.cxf.client; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; /** * This class was generated by Apache CXF 3.1.4 * 2015-12-16T18:03:44.816+08:00 * Generated source version: 3.1.4 * */ @WebService(targetNamespace = "http://server.cxf.webservice.web.apps.lucl.com/", name = "HelloWorldPortType") @XmlSeeAlso({ObjectFactory.class}) public interface HelloWorldPortType { @WebResult(name = "return", targetNamespace = "") @RequestWrapper(localName = "sayHi", targetNamespace = "http://server.cxf.webservice.web.apps.lucl.com/", className = "com.lucl.apps.web.webservice.cxf.client.SayHi") @WebMethod @ResponseWrapper(localName = "sayHiResponse", targetNamespace = "http://server.cxf.webservice.web.apps.lucl.com/", className = "com.lucl.apps.web.webservice.cxf.client.SayHiResponse") public java.lang.String sayHi( @WebParam(name = "arg0", targetNamespace = "") java.lang.String arg0 ); }
5、sayHi.java
对应server端HelloWorld接口的方法sayHi。
package com.lucl.apps.web.webservice.cxf.client; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sayHi", propOrder = { "arg0" }) public class SayHi { protected String arg0; /** * 获取arg0属性的值。 * * @return * possible object is * {@link String } * */ public String getArg0() { return arg0; } /** * 设置arg0属性的值。 * * @param value * allowed object is * {@link String } * */ public void setArg0(String value) { this.arg0 = value; } }
6、sayHiResponse.java
工具根据wsdl生成的HelloWorld接口的sayHi方法的响应。
package com.lucl.apps.web.webservice.cxf.client; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sayHiResponse", propOrder = { "_return" }) public class SayHiResponse { @XmlElement(name = "return") protected String _return; /** * 获取return属性的值。 * * @return * possible object is * {@link String } * */ public String getReturn() { return _return; } /** * 设置return属性的值。 * * @param value * allowed object is * {@link String } * */ public void setReturn(String value) { this._return = value; } }
注意:如果server端的HelloWorld接口中sayHi方法有异常被throw出来,那么在通过wsdl2java工具生成java代码时,会生成异常对应的JavaBean和实现了Exception的java类。