cxf WebService设置wsdl中soapAction的值

用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方法。

 

posted @ 2016-05-07 23:42  Gyoung  阅读(21481)  评论(0编辑  收藏  举报