更新元素列表时,Apache Camel CXF 难以调用 RPC/Encoded WSDL

Posted

技术标签:

【中文标题】更新元素列表时,Apache Camel CXF 难以调用 RPC/Encoded WSDL【英文标题】:Apache Camel CXF difficulty calling an RPC/Encoded WSDL when updating list of elements 【发布时间】:2019-12-15 19:02:22 【问题描述】:

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

<elements arrayType="UpdateElement">

VS 这里是发送的内容:

<elements>

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

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

MyService client = ???

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

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

'message'和'part'来自http://schemas.xmlsoap.org/wsdl/。

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

【问题讨论】:

【参考方案1】:

万一有人偶然发现了类似的问题,我自己想通了。我能够通过 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/

【讨论】:

以上是关于更新元素列表时,Apache Camel CXF 难以调用 RPC/Encoded WSDL的主要内容,如果未能解决你的问题,请参考以下文章

apache camel 条件路由

Apache Camel 遍历列表

CXF & Camel:不支持 List<Object> 作为 Web 服务参数

为什么Aries Blueprint没有为camel-cxf和camel-blueprint注册名称空间处理程序?

Mark:Camel SQL Route

Jetty服务器关闭流生成500错误