【问题标题】:UnmarshalException : camel soap unmarshaling error unexpected elementUnmarshalException:骆驼肥皂解组错误意外元素
【发布时间】:2018-08-17 16:16:29
【问题描述】:

[com.sun.istack.SAXParseException2;行号:1;列号:1;意外元素(uri:“http://service.example.com/”,本地:“custDetails”)。预期的元素是 http://schemas.xmlsoap.org/soap/envelope/}Body>、、http://schemas.xmlsoap.org/soap/envelope/}Envelope>、http://schemas.xmlsoap.org/soap/envelope/}Fault>、http://schemas.xmlsoap.org/soap/envelope/}Header>]

问题说明:Camel 不希望收到 custDetails(webmethod)和命名空间。
期望:使用 camel-soap 将有效负载解组为开箱即用的soapJaxb。

  1. 使用 maven-jaxb2-plugin 为下面的 xsd 生成 JAXB 类。结果生成了三个带有注释的类 - Customer.java、ObjectFactory、java、Order.java。

    <?xml version="1.0"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified"
           >
    <xs:element name="Customer">
    <xs:complexType >
    <xs:sequence>
      <xs:element name="Id" type="xs:string"/>
      <xs:element name="Address" type="xs:string"/>
      <xs:element name="ListOfOrders" type="order" minOccurs="0" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:complexType name="order">
    <xs:sequence>
          <xs:element name="Id" type="xs:string"/>
          <xs:element name="ProductName" type="xs:string"/>
          <xs:element name="ListOfDevice" minOccurs="0" >
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="DeviceName" type="xs:string"/>
                    <xs:element name="ManufactureDate" type="xs:date"/>
                </xs:sequence>
            </xs:complexType>
          </xs:element>
       </xs:sequence>
    </xs:complexType>
    </xs:schema>
    
  2. 使用 DataFormat 设置为 PAYLOAD 的 cxf 端点公开 webservice custDetails(..),如下所示。 [使用@Configuration 更新]

        @Configuration
       public class WebServiceConfig {
         @Autowired 
        private Bus bus;
    
        @Bean 
        public CxfEndpoint getCustomerDetails() {
            CxfEndpoint cxfEndpoint = new CxfEndpoint();
            cxfEndpoint.setAddress("/customerProvide");
            cxfEndpoint.setServiceClass(CustomerSvc.class);
            cxfEndpoint.setBus(bus);
            cxfEndpoint.setDataFormat(DataFormat.PAYLOAD);return cxfEndpoint ;}
    
        @Webservice
        public interface CustomerSvc {
        @WebMethod
        Customer  custDetails ( @WebParam(name="Customer")Customer Customer ) ;}
    
        // Simple route in Route class.
        @Component
        public class CustomerRoute extends RouteBuilder {
          public void configure (){
        SoapJaxbDataFormat soapDF 
        = new SoapJaxbDataFormat("com.example.service", new TypeNameStrategy());
    
         from("cxf:bean:getCustomerDetails").unmarshal(soapDF)
        .log("receive : ${body}")
        }
    
  3. Wsdl 生成并导入到soapUI。要测试的示例 SOAPUI 请求如下。

    <soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:ser="http://service.example.com/">
    <soapenv:Header/>
    <soapenv:Body>
      <ser:custDetails>
         <ser:Customer>
            <Id>1-abc</Id>
            <Address>23 Sydney Oxley road</Address>
            <ListOfOrders>
               <Id>P1344</Id>
               <ProductName>DRAM</ProductName>
               <ListOfDevice>
                  <DeviceName>20nm</DeviceName>
                  <ManufactureDate>15-8-2017</ManufactureDate>
               </ListOfDevice>
            </ListOfOrders>
         </ser:Customer>
      </ser:custDetails>
     </soapenv:Body>
    </soapenv:Envelope>
    
  4. 当我尝试使用 soap 数据格式解组 PAYLOAD 时,camel 抛出错误。这是命中命名空间错误。我不确定为什么没有生成 package-info 类。任何帮助是极大的赞赏。谢谢。

  5. 更新,wsdl 给出如下。 <?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://service.example.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="CustomerSvcService" targetNamespace="http://service.example.com/"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.example.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://service.example.com/"> <xs:element name="Customer"> <xs:complexType> <xs:sequence> <xs:element name="Id" type="xs:string"/> <xs:element name="Address" type="xs:string"/> <xs:element minOccurs="0" name="ListOfOrders" type="tns:order"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="order"> <xs:sequence> <xs:element name="Id" type="xs:string"/> <xs:element name="ProductName" type="xs:string"/> <xs:element minOccurs="0" name="ListOfDevice"> <xs:complexType> <xs:sequence> <xs:element name="DeviceName" type="xs:string"/> <xs:element name="ManufactureDate" type="xs:date"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:element name="custDetails" type="tns:custDetails"/> <xs:complexType name="custDetails"> <xs:sequence> <xs:element minOccurs="0" ref="tns:Customer"/> </xs:sequence> </xs:complexType> <xs:element name="custDetailsResponse" type="tns:custDetailsResponse"/> <xs:complexType name="custDetailsResponse"> <xs:sequence> <xs:element minOccurs="0" ref="tns:Customer"/> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="custDetails"> <wsdl:part element="tns:custDetails" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="custDetailsResponse"> <wsdl:part element="tns:custDetailsResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:portType name="CustomerSvc"> <wsdl:operation name="custDetails"> <wsdl:input message="tns:custDetails" name="custDetails"> </wsdl:input> <wsdl:output message="tns:custDetailsResponse" name="custDetailsResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="CustomerSvcServiceSoapBinding" type="tns:CustomerSvc"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="custDetails"> <soap:operation soapAction="" style="document"/> <wsdl:input name="custDetails"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="custDetailsResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="CustomerSvcService"> <wsdl:port binding="tns:CustomerSvcServiceSoapBinding" name="CustomerSvcPort"> <soap:address location="http://localhost:12000/services/customerProvide"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

【问题讨论】:

    标签: apache soap apache-camel spring-camel cxf-codegen-plugin


    【解决方案1】:

    因更新问题而编辑

    您尝试使用 Jax-B 根据您在问题顶部发布的 XML 架构解组请求负载。

    但在此架构中元素 custDetails 不存在。它存在于 WSDL 的模式部分中,但不存在于模式中?!?因此出现错误unexpected element

    【讨论】:

    • 非常感谢您的回复。我认为生成的 wsdl 是正确的。如果观察上面的第 2 点,我们得到 @webmethod custDetails 导致 wsdl 部分
    • 我开始认为用soapUI进行测试是不可行的
    • SoapUI 在测试 Web 服务方面非常流行,这应该可以正常工作。有关更多详细信息,您需要将 WSDL 添加到您的问题中。否则不可能看到请求的样子。 wsdl:operation 元素引用消息 tns:custDetailswsdl:message 元素定义该消息。
    • 这些都试过了,还是不行。我很好奇它为什么会失败。当我不用骆驼路线包裹它时,一切都很完美。此外,如果将 CxfEndpoint 设置为 POJO 模式,它可以工作并将消息正文正确绑定到客户类。 – Nahfees 13 分钟前
    • 我不太了解代码优先的 Web 服务,但显然请求包装器元素是问题所在。不确定 @RequestWrapper 注释在这种情况下是否有帮助。但是,在有效负载模式下,您只需将 soap:Body 内容作为 XML(包括 custDetails 元素,当 custDetails 元素不属于已知类型时,您就无法使用 Jax-B 解组它。您将拥有首先“解包” Customer 元素。在 POJO 模式下,CXF 还处理主体,它知道来自 WSDL 的 custDetails 元素。
    猜你喜欢
    • 2018-11-27
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多