使用CXF写SOAP WebService以及测试
1.服务端
@WebService(targetNamespace = "calculate")
public interface CalculateWS {
@WebMethod
Integer add(int a,int b);
@WebMethod
Integer minus(int a, int b);
}
首先创建WebService的接口,接口上需要加上@WebService注解,命名空间可以任意取,但是需要与实现类保持一致,目的是在WSDL文件中一并显示类型与消息定义,如果实现类和接口放在同一个包下,则命名空间可以忽略。
@WebService(targetNamespace = "calculate")
public class CalculateWSImple implements CalculateWS {
public Integer add(int a, int b) {
return a+b;
}
public Integer minus(int a, int b) {
return a-b;
}
}
然后写实现类,如果实现类和接口不在同一个包下,注意命名空间保持一致。
public class MainInvoke {
public static void main(String[] args){
String address = "http://localhost:9090/calculator";
Endpoint.publish(address,new CalculateWSImple());
System.out.println("publish success");
}
}
最后需要写个主函数把WebService发表出来,CXF是内置Jetty的,所以使用Eedpoint发布即可。
当看到控制台出现 publish success 字样后就可以在浏览器中打开WSDL文档查看,此处的地址为:
http://localhost:9090/calculator?wsdl
WSDL:<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="calculate" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="CalculateWSImpleService" targetNamespace="calculate">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="calculate" elementFormDefault="unqualified" targetNamespace="calculate" version="1.0">
<xs:element name="add" type="tns:add"/>
<xs:element name="addResponse" type="tns:addResponse"/>
<xs:element name="minus" type="tns:minus"/>
<xs:element name="minusResponse" type="tns:minusResponse"/>
<xs:complexType name="minus">
<xs:sequence>
<xs:element name="arg0" type="xs:int"/>
<xs:element name="arg1" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="minusResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="add">
<xs:sequence>
<xs:element name="arg0" type="xs:int"/>
<xs:element name="arg1" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="minusResponse">
<wsdl:part element="tns:minusResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="minus">
<wsdl:part element="tns:minus" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="add">
<wsdl:part element="tns:add" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="addResponse">
<wsdl:part element="tns:addResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="CalculateWS">
<wsdl:operation name="minus">
<wsdl:input message="tns:minus" name="minus"></wsdl:input>
<wsdl:output message="tns:minusResponse" name="minusResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="add">
<wsdl:input message="tns:add" name="add"></wsdl:input>
<wsdl:output message="tns:addResponse" name="addResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CalculateWSImpleServiceSoapBinding" type="tns:CalculateWS">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="minus">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="minus">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="minusResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="add">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="add">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CalculateWSImpleService">
<wsdl:port binding="tns:CalculateWSImpleServiceSoapBinding" name="CalculateWSImplePort">
<soap:address location="http://localhost:9090/calculator"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
2.客户端
同样使用CXF来测试发布的WebService,当然也可以使用WSDL2JAVA工具来测试,但是生成的客户端代码有点冗余。
此处新建一个类
public class CXFTest {
public static void main(String[] args) throws Exception{
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:9090/calculator?wsdl");
QName name = new QName("calculate","add");
Object[] ob = client.invoke(name,1,2);
System.out.println(ob[0].toString());
}
}
第一步,通过动态客户端工厂实例化一个对象;第二步,调用动态客户端的 createClient() 方法创建客户端对象,参数为WSDL地址;第三步,创建访问对象 QName ,构造方法的第一个参数是命名空间,第二个参数是操作名;第四步,调用客户端对象的invoke() 方法,第一个参数是访问对象,接下来的Object型不定对象为该操作的参数,返回是一个Object数组。