Camel 的编组问题,无法正确编组 SOAP 请求?

Posted

技术标签:

【中文标题】Camel 的编组问题,无法正确编组 SOAP 请求?【英文标题】:Marshaling issue with Camel, unable to correctly marshal SOAP request? 【发布时间】:2013-09-16 04:15:12 【问题描述】:

我正在尝试使用 Camel 路由通过 SOAP/JAX-WS 调用 Web 服务,并不断收到错误消息:CaughtExceptionMessage:HTTP operation failed invoking http://xyz.com/Service with statusCode: 404.

使用 Soap UI 工作文件调用相同的服务,所以我的猜测是请求没有得到相同的编组,并且服务无法找到正在调用的方法,导致 404。Soap UI 给出以下请求XML:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:bfg="http://xyz.com/Service">
   <soapenv:Header/>
   <soapenv:Body>
      <bfg:login>
         <bfg:request>
            <ipAddress>1.2.3.4</ipAddress>
            <locationId>0</locationId>
            <password>Foo</password>
            <productId>1</productId>
            <username>Bar</username>
            <vendorSoftwareId>0</vendorSoftwareId>
         </bfg:request>
       </bfg:login>
   </soapenv:Body>
</soapenv:Envelope>

Camel 吐出以下 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" 
      xmlns:ns3="http://xyz.com/Service" 
      xmlns:ns4="http://xyz.com/Other">    
<ns2:Body>        
    <ns3:login>            
       <ns3:request>                
           <ipAddress>1.2.3.4</ipAddress>                
           <locationId>0</locationId>                
           <password>Foo</password>                
           <productId>0</productId>                
           <username>Bar</username>               
           <vendorSoftwareId>0</vendorSoftwareId>            
       </ns3:request>       
    </ns3:login>    
  </ns2:Body>
</ns2:Envelope> 

差异很小,实际上只是名称空间。将 XML 复制并粘贴到 SoapUI 中,然后使用它将产生有效的请求/响应。

骆驼路线和配置如下:

private final SoapJaxbDataFormat globalServiceSoap = 
    new SoapJaxbDataFormat(Service.class.getPackage().getName(),  
     new ServiceInterfaceStrategy(Service.class, true));

from(RouteConstants.LOGIN_SERVICE_END_POINT_URI)
     .routeId("internal::loginGlobalService").marshal(globalServiceSoap)
    .to(endpointUri).unmarshal(globalServiceSoap).process(postLoginProcessor);

要编组的请求对象是进入该 Camel 路由的消息正文。骆驼在请求上做了什么导致它以 404 失败?

任何帮助或想法将不胜感激。

【问题讨论】:

【参考方案1】:

事实证明,Camel 没有添加 contentType 标头或 SOAPAction 标头,因此 Web 服务抛出 404,因为它不接受作为有效 SOAP 调用的请求(很可能是 @987654323 @ 对于让它工作并不重要)。我原以为 Camel 和 SoapJaxbDataFormat 会足够聪明地添加这种类型的东西(我看到的例子表明它应该)但似乎不是。

使用基于 java 代码的路由定义很容易添加缺少的标头:

from(RouteConstants.LOGIN_SERVICE_END_POINT_URI)
    .routeId("internal::loginGlobalService")
    .setHeader(Exchange.CONTENT_TYPE, constant("text/xml"))
    .setHeader("SOAPAction",   constant("login")).marshal(globalServiceSoap)
    .to(endpointUri).unmarshal(globalServiceSoap).process(postLoginProcessor);

结果请求被很好地接受了。将请求编组到 XML 工作正常,无需更改。

【讨论】:

以上是关于Camel 的编组问题,无法正确编组 SOAP 请求?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用camel编组格式化LocalDate对象

使用SOAP编组的Spring 5 Web服务客户端问题

使用 SOAP Web 服务错误(未注册编组器。检查 WebServiceTemplate 的配置)

如何使用 JAXB2 用动态元素编组 XML

在 JAXB 编组时删除命名空间前缀

netty 编解码器与 smooks 编组