用cxf開發一個WebService很簡單,只需要下面幾步:
1.定義接口
public interface HelloService {
String hello();
}
2.實現
public class HelloServiceImpl implements HelloService {
@Override
public String hello() {
return "hi,my name is gyoung ";
}
}
3.用ServerFactoryBean生成服務
public static void main(String[] args) {
HelloServiceImpl helloworldImpl = new HelloServiceImpl();
//cxf發布服務的工廠bean
ServerFactoryBean svrFactory = new ServerFactoryBean();
//設置服務類
svrFactory.setServiceClass(HelloService.class);
//設置服務地址
svrFactory.setAddress("http://localhost:9001/Hello");
//設置服務bean
svrFactory.setServiceBean(helloworldImpl);
svrFactory.create();
}
這樣,一個簡單的HelloWorld服務便生成成功了。
但是,這樣生成的服務有一個問題,wsdl中的soapAction屬性是空的
<wsdl:binding name="HelloServiceSoapBinding" type="tns:HelloServicePortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="hello"> <soap:operation soapAction="" style="document"/> <wsdl:input name="hello"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="helloResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding>
這一段<soap:operation soapAction="" style="document"/>,如果是.net生成的服務,soapAction是有值的
<wsdl:binding name="WebService1Soap" type="tns:WebService1Soap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="HelloWorld"> <soap:operation soapAction="http://tempuri.org/HelloWorld" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding>
查看了很久的源碼,才發現,設置cxf設置soapAction是在org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean類中

它會去循環遍歷serviceConfigurations,調用其getAction方法來獲取action的值。但初始的serviceConfigurations只有DefaultServiceConfiguration和SoapBindingServiceConfiguration,這兩個類都沒有實現其基類AbstractServiceConfiguration中的getAction方法。所以getAction返回值是空,所以wsdl中的soapAction值也會是空。找到問題就好辦了,我們在serviceConfigurations中增加一個config,在AbstractServiceConfiguration的眾多子類中,我發現MethodNameSoapActionServiceConfiguration有繼承getAction方法,所以我們只需要在生成服務的時候,增加一個MethodNameSoapActionServiceConfiguration
配置就行了。
public static void main(String[] args) {
HelloServiceImpl helloworldImpl = new HelloServiceImpl();
//cxf發布服務的工廠bean
ServerFactoryBean svrFactory = new ServerFactoryBean();
svrFactory.getServiceFactory().getConfigurations().add(new MethodNameSoapActionServiceConfiguration());
//設置服務類
svrFactory.setServiceClass(HelloService.class);
//設置服務地址
svrFactory.setAddress("http://localhost:9001/Hello");
//設置服務bean
svrFactory.setServiceBean(helloworldImpl);
svrFactory.create();
}
最張生成的wsdl
<wsdl:binding name="HelloServiceSoapBinding" type="tns:HelloServicePortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="hello"> <soap:operation soapAction="hello" style="document"/> <wsdl:input name="hello"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="helloResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding>
當然,我們也可以自己繼承AbstractServiceConfiguration來實現getAction方法。
轉自:https://www.cnblogs.com/Gyoung/p/5469536.html

