简体   繁体   English

如何以线程安全的方式使用CXF客户端

[英]How to use CXF client in thread safe way

I have created the client stub for below service using apache-cxf 's wsdl2java command. 我使用apache-cxf的wsdl2java命令为以下服务创建了客户端存根。 http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL


Then I invoke the getWeatherInformation() method as below. 然后我调用getWeatherInformation()方法,如下所示。

Weather weatherService = new Weather();
WeatherSoap weatherSoap = weatherService.getWeatherSoap();
ArrayOfWeatherDescription result = weatherSoap.getWeatherInformation();

I have read that cxf clients are thread safe. 我已经读过cxf客户端是线程安全的。 But I have a doubt whether it is safe to use the same WeatherSoap instance accross multiple threads? 但我怀疑在多个线程中使用相同的WeatherSoap实例是否安全? Or instead should/can I use an instance of Weather class, accross multiple threads? 或者我应该/可以使用Weather类的实例,跨越多个线程吗? Thanks. 谢谢。

EDIT: 编辑:


What I do is I have exposed a RESTful API to public and if somebody calls that rest service I call another SOAP service. 我所做的是我向公众公开了RESTful API,如果有人称之为休息服务,我会调用另一个SOAP服务。 Above code is used to call the SOAP service. 上面的代码用于调用SOAP服务。 What I want to know is should I execute all the above lines for each rest request or can I reuse an instance of Weather or WeatherSoap to serve all the REST requests. 我想知道的是我应该为每个休息请求执行以上所有行,还是可以重复使用WeatherWeatherSoap的实例来处理所有REST请求。

Yes CXF is thread safe, you can use single instance/singleton for Weather and WeatherSoap, you can think of cxf as similar to servlet engine which handles all the infrastructure for you such as transport, databinding for you. 是的CXF是线程安全的,你可以使用单个实例/单独的Weather和WeatherSoap,你可以认为cxf类似于servlet引擎,它为你处理所有基础设施,如传输,数据绑定。 I had similar usecase, where I had a front end presentation layer and number of network servers, to interact between these I had a rest for presentation and SOAP which implements business logic as well as interacts with servers. 我有类似的用例,我有一个前端表示层和多个网络服务器,在这些之间进行交互我有一个休息的演示文稿和SOAP实现业务逻辑以及与服务器交互。 Hence I implemented a soap client in rest layer. 因此我在rest层中实现了一个soap客户端。 I had requirement were I needed split rest request and invoke parallel soap calls which had time delays 800ms. 我有要求,我需要拆分休息请求,并调用时间延迟800毫秒的并行肥皂调用。 I performance tested the entire setup and did not run-up into any thread issues. 我的性能测试了整个设置,没有遇到任何线程问题。

So coming into to client implementation 所以进入客户端实现

Pure Java 纯Java

public class MySoapClient{

  private static WeatherSoap weatherSoap;

  private MySoapClient(){
  }

  public static WeatherSoap getClient(){

    if(weatherSoap==null){
        Weather weatherService = new Weather();
        weatherSoap= weatherService.getWeatherSoap();
    }
    return weatherSoap;
  }

}

And I would modify the Weather class to get SOAP url from properties file. 我会修改Weather类以从属性文件中获取SOAP URL。

@WebServiceClient(name = "Weather", 
                  wsdlLocation = "classpath:weather.wsdl",
                  targetNamespace = "http://ws.cdyne.com/WeatherWS/") 
public class Weather extends Service {

    private static final Logger LOG = LoggerFactory.getLogger(Weather.class);
    public final static URL WSDL_LOCATION;
    public final static QName SERVICE = new QName("http://ws.cdyne.com/WeatherWS/", "Weather");
    public final static QName WeatherHttpPost = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherHttpPost");
    public final static QName WeatherHttpGet = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherHttpGet");
    public final static QName WeatherSoap12 = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherSoap12");
    public final static QName WeatherSoap = new QName("http://ws.cdyne.com/WeatherWS/", "WeatherSoap");
    static {
        URL url = null;
        try {
            url = new URL(MyPropertiesUtil.getProperty("app.weather.url"));
        } catch (MalformedURLException e) {
            LOG.error(e.getMessage(), e);
        }
        if (url == null) {
            LOG.error("an issue with your url");
        }       
        WSDL_LOCATION = url;   
    }

    public Weather(URL wsdlLocation) {
        super(wsdlLocation, SERVICE);
    }

    public Weather(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public Weather() {
        super(WSDL_LOCATION, SERVICE);
    }


    //All the other interface methods

}

Using Spring 使用Spring

if you are using spring you can make things even simpler, you can eliminate Weather.java class by using configuration file as shown below and let cxf generate proxy for you. 如果你使用spring你可以使事情变得更简单,你可以使用配置文件消除Weather.java类,如下所示,让cxf为你生成代理。

<jaxws:client id="weatherSoap" serviceClass="com.cdyne.ws.weatherws.WeatherSoap" address="${app.weather.url}" />

And Business Class would look like below. 商务舱看起来如下。

@Component
MyBusinessLogic{

  @Autowired
  private WeatherSoap weatherSoap;

  public ArrayOfWeatherDescription getOutput(){
    return weatherSoap.getWeatherInformation();
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM