Camel cxfws生成器,POJO格式,抛出“获取错误的参数大小以调用out服务”错误

时间:2018-05-25 02:30:52

标签: apache-camel cxf-client

我的情况类似于Camel CXF POJO mode using Java DSL

以下是我为“GetReport”操作获得的错误。

java.lang.IllegalArgumentException: Get the wrong parameter size to invoke the out service, Expect size 7, Parameter size 4.
Please check if the message body matches the CXFEndpoint POJO Dataformat request.

这是我正在处理的操作的绑定信息。

<wsdl:operation name="GetReport">
<soap:operation soapAction="https://api.eventcore.com/GetReport" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
<soap:header message="tns:GetReportAuthTokenHeader" part="AuthTokenHeader" use="literal"/>
<soap:header message="tns:GetReportCredentialsHeader" part="CredentialsHeader" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
<soap:header message="tns:GetReportAuthTokenHeader" part="AuthTokenHeader" use="literal"/>
</wsdl:output>
</wsdl:operation>

作为交换体的一部分,我发送带有CredentialHeader,GetReport Object和必要数据的对象列表。我还为Response消息添加了持有者参数。

GetReport getReport = new GetReport();
getReport.setReportID(123);
getReport.setSortColumn("LastModified");
getReport.setStartRow(1);
getReport.setEndRow(2);
getReport.setSortAscending(true);
ReportFilter filter = new ReportFilter();
filter.setField("LastModified");
filter.setComparison(ComparisonType.GREATER_THAN);
filter.setMatchValue("2018-05-09T23:23:51.8769404Z");
filter.setMode(FilterMode.SELF);
getReport.setFilter(filter);

CredentialsHeader credentials = new CredentialsHeader();
credentials.setUserName("foo");
credentials.setPassword("bar");
credentials.setEventID(11111);

List<Object> params = new ArrayList<Object>();
params.add(getReport);
params.add(credentials);
params.add(null); //params.add(new AuthTokenHeader());
params.add(new javax.xml.ws.Holder<AuthTokenHeader>());
//params.add(new javax.xml.ws.Holder<GetReportResponse>());

exchange.getIn().setBody(params);

这是cxfEndpoint配置。

org.apache.camel.component.cxf.CxfEndpoint endpoint_cSOAP_1 = getCxfEndpoint(
                "cxf://"
                        + "https://api.stage.eventcore.com/ReportService.asmx"
                        + "?dataFormat=POJO"
                        + "&serviceClass="
                        + "tableau.ea.eventcore.api.reportservice.ReportServiceSoap"
                        + "&serviceName="
                        + "{https://api.eventcore.com/}ReportService"
                        + "&endpointName="
                        + "{https://api.eventcore.com/}ReportServiceSoap"
                        + "&defaultOperationNamespace="
                        + javax.xml.namespace.QName.valueOf(
                                "{https://api.eventcore.com/}GetReport")
                                .getNamespaceURI()
                        + "&defaultOperationName="
                        + javax.xml.namespace.QName.valueOf(
                                "{https://api.eventcore.com/}GetReport")
                                .getLocalPart() + "&" + "loggingFeatureEnabled"
                        + "=" + "true" + "&" + "continuationTimeout" + "="
                        + 600000
                        + "&headerFilterStrategy=#CXF_PAYLOAD_HEADER_FILTER"
                        + "&properties.id=" + "cSOAP_1", false, false, false,
                (String[]) null);

我不明白的是,为什么cxf期待7个参数?那7个参数是什么?我尝试通过添加一些空值来创建它,但它失败了“参数类型不匹配”错误。请帮助我理解此特定操作中的输入消息部分。

2 个答案:

答案 0 :(得分:0)

我后来意识到这个操作有隐含的SOAP头,我不得不使用&#34; -exsh true&#34;同时生成wsdl2java库。

现在,我可以看到库中的Porttype类接受标头作为参数。

public abstract void getReport(
@WebParam(name="reportID", targetNamespace="https://api.eventcore.com/") Integer paramInteger1, 
@WebParam(name="reportName", targetNamespace="https://api.eventcore.com/") String paramString1, 
@WebParam(name="sortColumn", targetNamespace="https://api.eventcore.com/") String paramString2, 
@WebParam(name="sortAscending", targetNamespace="https://api.eventcore.com/") boolean paramBoolean, 
@WebParam(name="startRow", targetNamespace="https://api.eventcore.com/") Integer paramInteger2, 
@WebParam(name="endRow", targetNamespace="https://api.eventcore.com/") Integer paramInteger3, 
@WebParam(name="filter", targetNamespace="https://api.eventcore.com/") ReportFilter paramReportFilter, 
@WebParam(mode=WebParam.Mode.INOUT, name="AuthTokenHeader", targetNamespace="https://api.eventcore.com/", header=true) Holder<AuthTokenHeader> paramHolder, 
@WebParam(name="CredentialsHeader", targetNamespace="https://api.eventcore.com/", header=true) CredentialsHeader paramCredentialsHeader, 
@WebParam(mode=WebParam.Mode.OUT, name="GetReportResult", targetNamespace="https://api.eventcore.com/") Holder<GetReportResponse.GetReportResult> paramHolder1, 
@WebParam(mode=WebParam.Mode.OUT, name="recordCount", targetNamespace="https://api.eventcore.com/") Holder<Integer> paramHolder2);

我正在设置参数列表如下。

List<Object> params = new ArrayList<Object>();
params.add(1037); //reportID
params.add(null); //reportName
params.add("LastModified"); //sortColumn
params.add(true); //sortAscending
params.add(1); //startRow
params.add(2); //endRow
params.add(filter); //filter
params.add(new javax.xml.ws.Holder<AuthTokenHeader>()); // INOUT soap header
params.add(credentials); // IN Soap Header
params.add(new javax.xml.ws.Holder<GetReportResponse.GetReportResult>()); // Out Body
params.add(new javax.xml.ws.Holder<Integer>()); // Out parameter

但是,我仍然收到错误

Get the wrong parameter size to invoke the out service, Expect size 10, Parameter size 11. Please check if the message body matches the CXFEndpoint POJO Dataformat request.

当我查看CxfProducer的代码(checkParameterSize方法)时,看起来它将soapHeadersSize变为0,甚至认为有2个SOAP输入头。

任何线索如何解决这个问题?

答案 1 :(得分:0)

我通过不使用&#34; -exsh true&#34;解决了这个问题。生成wsdl时使用选项,并使用Holders.LIST头设置SOAP标头。在这样做的时候,我必须为CredentialsHeader设置mustUnderstand = true。

最后我将标头添加到SOAP请求中。但是,我真的想知道为什么传递所有标题加上body作为参数列表的路径(使用&#34; -exsh true&#34;选项)不起作用。我有一个完全相同的方法为不同的Web服务工作,但不适用于这个。我很好奇是什么造成了不同。

如果有人有洞察力,请分享。