0

虽然没有官方支持,但通过对 WSDL 进行一些小的修改,我能够成功地为 WSDL 生成 CXF 对象并让 Camel CXF 与 RPC/Encoded WSDL 端点对话。代码非常简单,除了尝试发送元素列表的更新之外,大多数请求/响应都可以正常工作。这是服务的期望:

<elements arrayType="UpdateElement">

VS 这里是发送的内容:

<elements>

我需要将 arrayType 添加到传出消息中。我研究了多种方法:

1)在 SOAP 消息由 CXF 发送之前的拦截器,然后使用 XPath 添加元素,但我不清楚如何使用 Apache Camel + Camel CXF 完成此操作。如何从 Camel 上下文中检索 CXF 客户端?

MyService client = ???

2) 通过 WSDL 修复它?是否可以将此元素添加到 WSDL,使其作为 CXF 对象的一部分生成?目前是这样定义的:

<message name="wsdlElementRequest"> <part name="elements" type="tns:UpdateElements" /></message>

“消息”和“部分”来自http://schemas.xmlsoap.org/wsdl/

任何想法或建议将不胜感激。谢谢!

4

1 回答 1

0

万一有人偶然发现了类似的问题,我自己想通了。我能够通过 CamelContext 检索 CxfEndpoint:

camelContext.getEndpoint(endpointUrl, CxfEndpoint.class);

然后我可以添加我创建的拦截器:

public class MyCxfInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
...

使用 CxfEndpoint 方法:

cxfEndpoint.getOutInterceptors().add(new MyCxfInterceptor());

在我的拦截器中,我还合并了另一个拦截器 SAAJOutInterceptor,它将 SOAP 转换为易于使用的对象:

private List<PhaseInterceptor<? extends Message>> extras = new ArrayList<>(1);

public MyCxfInterceptor() {
    super(Phase.USER_PROTOCOL);
    extras.add(new SAAJOutInterceptor());
}

public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
    return extras;
}

易于使用的 SOAP 消息:

@Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
    SOAPMessage msg = soapMessage.getContent(SOAPMessage.class);

    try {
        SOAPBody soapBody = msg.getSOAPBody();

然后使用 XPATH 对传出的 SOAP 消息进行更正就很简单了。

private XPath xpath = XPathFactory.newInstance().newXPath();
...
NodeList nodeList = soapBody.getElementsByTagName("tagName");
for (int x = 0; x < nodeList.getLength(); x++) {
    Node node = nodeList.item(x);
    ((Element) node).setAttribute("missingAttributeName", "missingAttributeValue");
}

我希望这可以帮助任何使用具有挑战性的 SOAP 服务的人!

感谢博客,它在使我能够实施此解决方案方面发挥了重要作用:https ://xceptionale.wordpress.com/2016/06/26/message-interceptor-to-modify-outbound-soap-request/

于 2020-01-04T03:32:26.527 回答