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

  • 相关阅读:
    Gridview使用CheckBox全选与单选 Version 2
    Repeater控件第前10笔记录高亮显示
    下拉式菜单(DropDownList)连动的选择
    DataList控件显示图片要的是效果
    电容屏、电阻屏基础知识
    SIM300实现GPRS上网
    qt练习7 定时爆炸小游戏
    用 STL vector 来创建二维数组
    sim300_at命令.doc
    QT练习6 label,button创建,点击按键关闭
  • 原文地址:https://www.cnblogs.com/Gyoung/p/5469536.html
Copyright © 2011-2022 走看看