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

标签 java web-services wsdl cxf wsdl2java

我已经使用 apache-cxf 的 wsdl2java 命令为以下服务创建了客户端 stub 。 http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL


然后我调用 getWeatherInformation() 方法,如下所示。

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

我读到 cxf 客户端是线程安全的。但是我怀疑跨多个线程使用相同的 WeatherSoap 实例是否安全?或者我应该/可以跨多个线程使用 Weather 类的实例吗? 谢谢。

编辑:


我所做的是向公众公开一个 RESTful API,如果有人调用该 rest 服务,我将调用另一个 SOAP 服务。以上代码用于调用 SOAP 服务。我想知道的是,我应该为每个休息请求执行以上所有行,还是可以重用 WeatherWeatherSoap 的实例来服务所有 REST 请求。

最佳答案

是的,CXF 是线程安全的,您可以为 Weather 和 WeatherSoap 使用单实例/单例,您可以将 cxf 视为类似于 servlet 引擎,它为您处理所有基础设施,例如传输、数据绑定(bind)。我有类似的用例,其中我有一个前端表示层和许多网络服务器,为了在它们之间进行交互,我休息了表示和实现业务逻辑以及与服务器交互的 SOAP。因此我在休息层实现了一个肥皂客户端。我有要求是我需要拆分休息请求并调用具有 800 毫秒时间延迟的并行 soap 调用。我对整个设置进行了性能测试,没有遇到任何线程问题。

所以进入客户端实现

纯 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;
  }

}

我会修改 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

}

使用 Spring

如果您使用的是 spring,则可以使事情变得更简单,您可以使用如下所示的配置文件消除 Weather.java 类,并让 cxf 为您生成代理。

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

商务舱如下所示。

@Component
MyBusinessLogic{

  @Autowired
  private WeatherSoap weatherSoap;

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

}

关于java - 如何以线程安全的方式使用 CXF 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29079866/

相关文章:

java - 图像跟踪器库

web-services - Web 应用程序 API 的用例?

c# - IIS 应用程序池管理和最佳实践

objective-c - 注册应用程序的 SoundCloud API 和 401 错误

Java WSDL 修改或隐藏 Web View 上的某些属性

Java JSR 文档

Java的ServiceLoader和测试资源

web-services - 基于文档或 RPC 的 Web 服务

c# - 来自 .NET C# 客户端的 Java Web 服务 - 命名空间故障?

Java Android AsyncHttpClient 将 byte[]responseBody 转换为 InputStream