使用现有的 http 客户端进行 SOAP 调用

use existing http client for SOAP call

我有一个工作 Dropwizard project, which has several ways of getting data it needs. One of those ways is the JAX-RS client that Dropwizard provides, the JerseyClient。此客户端已配置为适合我的需要(使用适当的代理、超时等...)

现在我的项目有一个新需求,我需要对其进行 SOAP 调用。我已经使用以下代码在功能上正常工作:

// not the actual structure, edited to make a minimal example
// SERVICE_QNAME and PORT_QNAME are hardcoded strings, config.url comes
// from the configuration
import javax.xml.ws.*;
import javax.xml.ws.soap.*;
import javax.xml.namespace.QName;

Service service = Service.create(SERVICE_QNAME);
service.addPort(PORT_QNAME, SOAPBinding.SOAP11HTTP_BINDING, config.url);
Dispatch dispatch = service.createDispatch(PORT_QNAME, SOAPMessage.class, Service.Mode.MESSAGE);
dispatch.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, config.url);


Message message = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL).createMessage();
// do stuff to fill the message
response = dispatch.invoke(message);

这都是开箱即用的行为,这里发生的任何事情都是由 java (8) 或 Dropwizard 提供的。

然而,此代码使用它自己的 http 连接器,绕过我在 JAX-RS 客户端中设置的任何内容。我想以一种非复制粘贴的方式在 JAX-WS 客户端中重新使用 JerseyClient 的 http 功能。

有什么方法可以设置 Dispatch 以便它使用现有的 http 连接器?或者其他一些 SOAP 客户端来实现相同的?

感谢@zloster 的研究和建议。然而,我决定走另一条路。

我找到了 SAAJ 标准并正在使用它。我为 javax.xml.soap.SOAPConnection 创建了一个子 class 并基于 com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection。那部分并没有那么难,给我留下了相对较小的 class.

现在在我的代码中,我将上面的代码替换为以下内容:

SOAPConnection soapConnection = new JerseySOAPConnection(httpClient, soapProtocol);
Message message = MessageFactory.newInstance(soapProtocol).createMessage();
// do stuff to fill the message
response = soapConnection.call(message, config.url);

由于我的实现不是那么便携,但我真的不需要它。再次感谢那些帮助我做到这一点的人!