之前我们使用了JDK的JAX-WS来开发一个WebService,现在我们使用Apach的CXF来开发一个WebService。
准备CXF的组件
到官方网站下载,最新版本的是apache-cxf-3.1.1,下载地址为:http://cxf.apache.org/download.html
使用CXF要导入的jar包比较多,我们使用maven在导入相关的jar包,maven依赖如下:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-aegis</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.0</version>
</dependency>
这里我cxf-rt-transports-http-jetty使用3.1.0版本是因为使用3.1.1版本时报错,下载不到相应的包,所以使用了3.1.0。
定义服务端WebService
定义服务端WebService的方式和之前一样,需要使用@WebService注解在WebService类的接口上进行标记。接口如下:
package com.hello.ws;
import javax.jws.WebService;
@WebService
public interface MyWS {
public String sayHello(String name);
}
对应的实现类如下:
package com.hello.ws;
import javax.jws.WebService;
@WebService
public class MyWSImpl implements MyWS {
@Override
public String sayHello(String name) {
return "I am web service, hello " + name;
}
}
发布服务端WebService
这次我们使用CXF的JaxWsServerFactoryBean来发布服务:
package com.hello.ws;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class Publisher {
public static void main(String[] args) {
String address = "http://localhost:8089/ws/MyWS";
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setAddress(address);
factory.setServiceClass(MyWS.class);
factory.setServiceBean(new MyWSImpl());
factory.create();
}
}
运行上面代码,可以看到控制台输出:
Creating Service {http://ws.hello.com/}MyWSService from class com.hello.ws.MyWS
Setting the server's publish address to be http://localhost:8089/ws/MyWS
Logging initialized @761ms
jetty-9.2.9.v20150224
No Server set for org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine$1@548a24a
Started ServerConnector@7139992f{HTTP/1.1}{localhost:8089}
Started @878ms
Started o.e.j.s.h.ContextHandler@7dfb0c0f{/ws,null,AVAILABLE}
我们可以在用浏览器访问:http://localhost:8089/ws/MyWS?wsdl ,我们可以看到:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.hello.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="MyWSService" targetNamespace="http://ws.hello.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.hello.com/" elementFormDefault="unqualified" targetNamespace="http://ws.hello.com/" version="1.0">
<xs:element name="sayHello" type="tns:sayHello"/>
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="sayHello">
<wsdl:part element="tns:sayHello" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHelloResponse">
<wsdl:part element="tns:sayHelloResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="MyWS">
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello" name="sayHello"></wsdl:input>
<wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MyWSServiceSoapBinding" type="tns:MyWS">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="sayHello">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MyWSService">
<wsdl:port binding="tns:MyWSServiceSoapBinding" name="MyWSPort">
<soap:address location="http://localhost:8089/ws/MyWS"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
生成WebService客户端代码
我们使用CXF提供的wsdl2java工具来生成客户端代码。
刚才我们已经下载了apache-cxf-3.1.1,我们打开cmd,cd到bin目录下,执行命令“wsdl2java -d D:\workspace\wsclient\src http://localhost:8089/ws/MyWS?wsdl”,就会生成客户端代码到-d后面的目录下。
在客户端调用WebService对外提供的方法
我们可以在客户端使用JaxWsProxyFactoryBean来调用WebService对外提供的方法。
package com.hello.ws;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class WSClient {
public static void main(String[] args) {
String address = "http://localhost:8089/ws/MyWS";
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(address);
factory.setServiceClass(MyWS.class);
MyWS ws = (MyWS) factory.create();
String result = ws.sayHello("wsclient");
System.out.println(result);
}
}
运行以上代码,可以看到控制台输出:
七月 26, 2015 8:28:15 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://ws.hello.com/}MyWSService from class com.hello.ws.MyWS
I am web service, hello wsclient
以上,我们就实现了使用CXF开发WebService。