我已经使用 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 服务。我想知道的是,我应该为每个休息请求执行以上所有行,还是可以重用
Weather
或 WeatherSoap
的实例来服务所有 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/