zoukankan      html  css  js  c++  java
  • 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方法。

  • 相关阅读:
    (转)Android获取手机信息
    ListView中RadioButton实现单项选择
    ListView 实现分组
    解决PopupWindow遮住输入法
    Oracle多行记录合并处理
    ubuntu install express
    图片以BLOB存储在后台数据库中,Android客户端要进行读取显示
    将图片以Blob格式存入数据库,再通过Servlet显示到界面
    httpcomponents-client-4.3.6 HttpPost的简单使用
    设置Ubuntu Mysql可以远程链接
  • 原文地址:https://www.cnblogs.com/Gyoung/p/5469536.html
Copyright © 2011-2022 走看看