使用数据格式作为 POJO 通过 Camel 调用 Web 服务时无法设置 SOAP Header
Unable to set SOAP Header while calling Web Service through Camel using dataFormat as POJO
我在我们的项目中使用 Camel 并请求 WebServices,dataFormat 是 POJO。当我的 SOAP 消息不包含 SOAP header 时,我可以请求,但是当它包含 Headers 时,我无法设置它们。我查看了文档,但无法理解并有几个问题。
我想创建如下消息:
<soapenv:Envelope`enter code here`
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<platformMsgs:documentInfo
xmlns:platformMsgs="urn:messages_2015_1.platform.webservices.netsuite.com">
<platformMsgs:nsId>WEBSERVICES_3479023</platformMsgs:nsId>
</platformMsgs:documentInfo>
</soapenv:Header>
<soapenv:Body>
<addListResponse
xmlns="">
<platformMsgs:writeResponseList
xmlns:platformMsgs="urn:messages_2015_1.platform.webservices.netsuite.com">
<platformCore:status isSuccess="true"
xmlns:platformCore="urn:core_2015_1.platform.webservices.netsuite.com"/>
<platformMsgs:writeResponse>
<platformCore:status isSuccess="false"
xmlns:platformCore="urn:core_2015_1.platform.webservices.netsuite.com">
<platformCore:statusDetail type="ERROR">
<platformCore:code>DUP_ENTITY</platformCore:code>
<platformCore:message>This entity already exists.</platformCore:message>
</platformCore:statusDetail>
</platformCore:status>
</platformMsgs:writeResponse>
</platformMsgs:writeResponseList>
</addListResponse>`enter code here`
</soapenv:Body>
</soapenv:Envelope>
如果只有 Body,我将能够发送消息,但是有人可以给我包含 header 部分的代码片段吗?数据格式为 POJO。
当使用数据格式为 POJO 的 CXF 端点时,Camel Exchange object 中的 body 是 org.apache.cxf.message.MessageContentsList
的 object。它是 java.util.ArrayList<Object>
的扩展,它按 WSDL 中定义的顺序包含部分 SOAP 消息,以及 WebService class 中的相应方法。
元素0有一个Body.
因此,使用 Java 的一种方法是创建一个处理器 class 实现 org.apache.camel.Processor
接口,并在其 process
方法中设置您的 SOAP header.类似于:
@Override
public void process(Exchange camelExchange) throws Exception {
MessageContentsList messageBody = (MessageContentsList) camelExchange.getIn().getBody();
DocumentInfo docInfoHeader = new DocumentInfo();
... set docInfoHeader properties ...
messageBody.add(docInfoHeader);
}
(样本未测试,只是想法,如何处理...)
您可以在这里找到关于类似问题的其他答案:Setting Custom Soap Header-To Pojo Message In Camel Cxf
它描述了如何使用 Camel Exchange headers 作为 SOAP Headers。
我 100% 不确定哪种方式适合您,哪种方式更好...
我想,这取决于您使用的 WSDL。
UPD:第二种选择是通过使用 CxfMessageSoapHeaderOutInterceptor
自定义实现来使用纯 CXF 解决方案。
它可能看起来像:
public class MyCxfInterceptor extends CxfMessageSoapHeaderOutInterceptor {
@Override
public void handleMessage( org.apache.cxf.binding.soap.SoapMessage message) {
org.apache.cxf.binding.soap.SoapHeader myCustomHeader = new org.apache.cxf.binding.soap.SoapHeader(new QName(
{custom name space}, {custom local name}), {Custom content object}));
myCustomHeader.setMustUnderstand(true);
message.getHeaders().add(myCustomHeader);
}
并将 Camel Cxf 端点中的拦截器设置为:
<cxfEndpoint ...>
<outInterceptors>
<spring:bean class="MyCxfInterceptor"/>
</outInterceptors>
...
好吧,假设我请求 Web 服务但它失败了,将生成一条故障消息。那么我是否也会在 MessageContentsList 的位置 0 处获得 Fault 对象?还是只获取位置 0 的响应对象?
我在我们的项目中使用 Camel 并请求 WebServices,dataFormat 是 POJO。当我的 SOAP 消息不包含 SOAP header 时,我可以请求,但是当它包含 Headers 时,我无法设置它们。我查看了文档,但无法理解并有几个问题。
我想创建如下消息:
<soapenv:Envelope`enter code here`
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<platformMsgs:documentInfo
xmlns:platformMsgs="urn:messages_2015_1.platform.webservices.netsuite.com">
<platformMsgs:nsId>WEBSERVICES_3479023</platformMsgs:nsId>
</platformMsgs:documentInfo>
</soapenv:Header>
<soapenv:Body>
<addListResponse
xmlns="">
<platformMsgs:writeResponseList
xmlns:platformMsgs="urn:messages_2015_1.platform.webservices.netsuite.com">
<platformCore:status isSuccess="true"
xmlns:platformCore="urn:core_2015_1.platform.webservices.netsuite.com"/>
<platformMsgs:writeResponse>
<platformCore:status isSuccess="false"
xmlns:platformCore="urn:core_2015_1.platform.webservices.netsuite.com">
<platformCore:statusDetail type="ERROR">
<platformCore:code>DUP_ENTITY</platformCore:code>
<platformCore:message>This entity already exists.</platformCore:message>
</platformCore:statusDetail>
</platformCore:status>
</platformMsgs:writeResponse>
</platformMsgs:writeResponseList>
</addListResponse>`enter code here`
</soapenv:Body>
</soapenv:Envelope>
如果只有 Body,我将能够发送消息,但是有人可以给我包含 header 部分的代码片段吗?数据格式为 POJO。
当使用数据格式为 POJO 的 CXF 端点时,Camel Exchange object 中的 body 是 org.apache.cxf.message.MessageContentsList
的 object。它是 java.util.ArrayList<Object>
的扩展,它按 WSDL 中定义的顺序包含部分 SOAP 消息,以及 WebService class 中的相应方法。
元素0有一个Body.
因此,使用 Java 的一种方法是创建一个处理器 class 实现 org.apache.camel.Processor
接口,并在其 process
方法中设置您的 SOAP header.类似于:
@Override
public void process(Exchange camelExchange) throws Exception {
MessageContentsList messageBody = (MessageContentsList) camelExchange.getIn().getBody();
DocumentInfo docInfoHeader = new DocumentInfo();
... set docInfoHeader properties ...
messageBody.add(docInfoHeader);
}
(样本未测试,只是想法,如何处理...)
您可以在这里找到关于类似问题的其他答案:Setting Custom Soap Header-To Pojo Message In Camel Cxf
它描述了如何使用 Camel Exchange headers 作为 SOAP Headers。
我 100% 不确定哪种方式适合您,哪种方式更好... 我想,这取决于您使用的 WSDL。
UPD:第二种选择是通过使用 CxfMessageSoapHeaderOutInterceptor
自定义实现来使用纯 CXF 解决方案。
它可能看起来像:
public class MyCxfInterceptor extends CxfMessageSoapHeaderOutInterceptor {
@Override
public void handleMessage( org.apache.cxf.binding.soap.SoapMessage message) {
org.apache.cxf.binding.soap.SoapHeader myCustomHeader = new org.apache.cxf.binding.soap.SoapHeader(new QName(
{custom name space}, {custom local name}), {Custom content object}));
myCustomHeader.setMustUnderstand(true);
message.getHeaders().add(myCustomHeader);
}
并将 Camel Cxf 端点中的拦截器设置为:
<cxfEndpoint ...>
<outInterceptors>
<spring:bean class="MyCxfInterceptor"/>
</outInterceptors>
...
好吧,假设我请求 Web 服务但它失败了,将生成一条故障消息。那么我是否也会在 MessageContentsList 的位置 0 处获得 Fault 对象?还是只获取位置 0 的响应对象?