Java服务-SOAP响应始终将NULL返回到.NET

时间:2019-04-25 06:53:02

标签: java .net xml soap xsd

我有一个用Java的Spring Boot开发的SOAP 1.1服务,它对我的​​任何请求都没有任何问题,并且可以提供有效的SOAP响应。

现在的问题是,一旦将此服务作为“服务引用”添加到任何.NET / C#项目,该引用就会创建,并且我可以发送请求,但是响应(肯定是从SOAP服务发送的)无法映射返回,我的.NET应用程序中的对象始终为null。

我已经发现了问题所在,但是我不知道如何更改xsd / wsdl以正确生成所有源(如果可能的话)。

首先,这里是Java Spring Boot项目中的.xsd,用于生成WSDL和服务参考:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://atu.de/soaptransformer/base"
           xmlns:tns="http://atu.de/soaptransformer/base"
           xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
           jaxb:version="1.0">

    <xs:complexType name="ArrayOfMessages">
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="unbounded" name="message" nillable="true"
                        type="tns:AppDataMessageData"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="AppDataMessageData">
        <xs:sequence>
            <xs:element name="messageCode" type="xs:int"/>
            <xs:element name="messageText" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataMessageData" nillable="true" type="tns:AppDataMessageData"/>
    <xs:complexType name="AppDataHeaderData">
        <xs:sequence>
            <xs:element name="authorization" type="xs:string"/>
            <xs:element name="branchNumber" type="xs:string"/>
            <xs:element name="mainSystemOrderNumber" type="xs:string"/>
            <xs:element name="callMode" type="xs:string"/>
            <xs:element name="damageType" type="xs:string"/>
            <xs:element name="misc1" type="xs:string"/>
            <xs:element name="misc2" type="xs:string"/>
            <xs:element name="countryRegionId" type="xs:string"/>
            <xs:element name="messages" type="tns:ArrayOfMessages"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataHeaderData" nillable="true" type="tns:AppDataHeaderData"/>
    <xs:complexType name="ArrayOfPositions">
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="unbounded" name="position" nillable="true"
                        type="tns:AppDataPositionData"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="AppDataPositionData">
        <xs:sequence>
            <xs:element name="inventTransId" type="xs:string"/>
            <xs:element name="positionNumber" type="xs:int"/>
            <xs:element name="itemId" type="xs:string"/>
            <xs:element name="itemType" type="xs:string"/>
            <xs:element name="articleDescription" type="xs:string"/>
            <xs:element name="deleteFlag" type="xs:boolean"/>
            <xs:element name="itemPosType" type="xs:string"/>
            <xs:element name="itemParentId" type="xs:string"/>
            <xs:element name="installDuration" type="xs:double"/>
            <xs:element name="misc" type="xs:string"/>
            <xs:element name="messages" type="tns:ArrayOfMessages"/>
            <xs:element name="quantity" type="xs:double"/>
            <xs:element name="salesPrice" type="xs:double"/>
            <xs:element name="lineDiscAuto" type="xs:double"/>
            <xs:element name="lineDiscMan" type="xs:double"/>
            <xs:element name="lineDiscEmpl" type="xs:double"/>
            <xs:element name="lineAmount" type="xs:double"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataPositionData" nillable="true" type="tns:AppDataPositionData"/>
    <xs:complexType name="AppDataInsuranceData">
        <xs:sequence>
            <xs:element name="retention" type="xs:double"/>
            <xs:element name="policyNumber" type="xs:string"/>
            <xs:element name="lossNumber" type="xs:string"/>
            <xs:element name="directPlacing" type="xs:boolean"/>
            <xs:element name="inputTaxDeduction" type="xs:boolean"/>
            <xs:element name="lossDate" type="xs:string"/>
            <xs:element name="arranger" type="xs:string"/>
            <xs:element name="retentionRenounceWorkshop" type="xs:double"/>
            <xs:element name="retentionRenounceInsurance" type="xs:double"/>
            <xs:element name="transmitted" type="xs:boolean"/>
            <xs:element name="automatedCDVProvided" type="xs:boolean"/>
            <xs:element name="insuranceDamageCauseDesc" type="xs:string"/>
            <xs:element name="insuranceDamageDesc" type="xs:string"/>
            <xs:element name="costCovered" type="xs:boolean"/>
            <xs:element name="costCoveringCheckState" type="xs:string"/>
            <xs:element name="messages" type="tns:ArrayOfMessages"/>
            <xs:element name="directPayer" type="xs:boolean"/>
            <xs:element name="insuranceDamageType" type="xs:string"/>
            <xs:element name="insuranceDebitorNumber" type="xs:int"/>
            <xs:element name="insuranceName" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataInsuranceData" nillable="true" type="tns:AppDataInsuranceData"/>
    <xs:complexType name="AppDataCustomerData">
        <xs:sequence>
            <xs:element name="custAccount" type="xs:string"/>
            <xs:element name="custAccountDBM" type="xs:string"/>
            <xs:element name="authorizationId" type="xs:string"/>
            <xs:element name="noticeId" type="xs:string"/>
            <xs:element name="flagDNEPost" type="xs:boolean"/>
            <xs:element name="flagDNEElec" type="xs:boolean"/>
            <xs:element name="custGroup" type="xs:string"/>
            <xs:element name="approvalNo" type="xs:string"/>
            <xs:element name="leasingNo" type="xs:string"/>
            <xs:element name="messages" type="tns:ArrayOfMessages"/>
            <xs:element name="salutation" type="xs:string"/>
            <xs:element name="firstName" type="xs:string"/>
            <xs:element name="lastName" type="xs:string"/>
            <xs:element name="company" type="xs:string"/>
            <xs:element name="zipCode" type="xs:string"/>
            <xs:element name="city" type="xs:string"/>
            <xs:element name="street" type="xs:string"/>
            <xs:element name="addressHouseNumber" type="xs:string"/>
            <xs:element name="addressHouseNumberAdd" type="xs:string"/>
            <xs:element name="phone" type="xs:string"/>
            <xs:element name="mobil" type="xs:string"/>
            <xs:element name="telefax" type="xs:string"/>
            <xs:element name="email" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataCustomerData" nillable="true" type="tns:AppDataCustomerData"/>
    <xs:complexType name="AppDataVehicleData">
        <xs:sequence>
            <xs:element name="vehicleId" type="xs:string"/>
            <xs:element name="licenseNumber" type="xs:string"/>
            <xs:element name="vin" type="xs:string"/>
            <xs:element name="atuKtypNr" type="xs:int"/>
            <xs:element name="tecDocKtypNr" type="xs:int"/>
            <xs:element name="kba1" type="xs:string"/>
            <xs:element name="kba2" type="xs:string"/>
            <xs:element name="kba3" type="xs:string"/>
            <xs:element name="kba32" type="xs:string"/>
            <xs:element name="natCode" type="xs:string"/>
            <xs:element name="mileage" type="xs:int"/>
            <xs:element name="registrationDate" type="xs:string"/>
            <xs:element name="categoryId" type="xs:string"/>
            <xs:element name="manufacturerName" type="xs:string"/>
            <xs:element name="modelName" type="xs:string"/>
            <xs:element name="messages" type="tns:ArrayOfMessages"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataVehicleData" nillable="true" type="tns:AppDataVehicleData"/>
    <xs:complexType name="AppDataMiscData">
        <xs:sequence>
            <xs:element name="EmplName" type="xs:string"/>
            <xs:element name="messages" type="tns:ArrayOfMessages"/>
            <xs:element name="IntDummy_1" type="xs:int"/>
            <xs:element name="IntDummy_2" type="xs:int"/>
            <xs:element name="IntDummy_3" type="xs:int"/>
            <xs:element name="IntDummy_4" type="xs:int"/>
            <xs:element name="IntDummy_5" type="xs:int"/>
            <xs:element name="DoubleDummy_1" type="xs:double"/>
            <xs:element name="DoubleDummy_2" type="xs:double"/>
            <xs:element name="DoubleDummy_3" type="xs:double"/>
            <xs:element name="DoubleDummy_4" type="xs:double"/>
            <xs:element name="DoubleDummy_5" type="xs:double"/>
            <xs:element name="StringDummy_1" type="xs:string"/>
            <xs:element name="StringDummy_2" type="xs:string"/>
            <xs:element name="StringDummy_3" type="xs:string"/>
            <xs:element name="StringDummy_4" type="xs:string"/>
            <xs:element name="StringDummy_5" type="xs:string"/>
            <xs:element name="BooleanDummy_1" type="xs:boolean"/>
            <xs:element name="BooleanDummy_2" type="xs:boolean"/>
            <xs:element name="BooleanDummy_3" type="xs:boolean"/>
            <xs:element name="BooleanDummy_4" type="xs:boolean"/>
            <xs:element name="BooleanDummy_5" type="xs:boolean"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataMiscData" nillable="true" type="tns:AppDataMiscData"/>
    <xs:complexType name="ArrayOfAdditionals">
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="unbounded" name="additional" nillable="true"
                        type="tns:AppDataAdditionalData"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="AppDataAdditionalData">
        <xs:sequence>
            <xs:element name="data1" type="xs:string"/>
            <xs:element name="data2" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="AppDataAdditionalData" nillable="true" type="tns:AppDataAdditionalData"/>
    <xs:complexType name="AppDataDataRequest">
        <xs:sequence>
            <xs:element name="headerData" type="tns:AppDataHeaderData"/>
            <xs:element name="positions" type="tns:ArrayOfPositions"/>
            <xs:element name="insuranceData" type="tns:AppDataInsuranceData"/>
            <xs:element name="customerData" type="tns:AppDataCustomerData"/>
            <xs:element name="vehicleData" type="tns:AppDataVehicleData"/>
            <xs:element name="miscData" type="tns:AppDataMiscData" form="unqualified"/>
            <xs:element name="additionals" type="tns:ArrayOfAdditionals" form="unqualified"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="processingRequest">
        <xs:sequence>
            <xs:element name="AppDataDataRequest" type="tns:AppDataDataRequest"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="processingRequest" nillable="true" type="tns:processingRequest"/>
    <xs:complexType name="AppDataDataResult">
        <xs:sequence>
            <xs:element name="headerData" type="tns:AppDataHeaderData"/>
            <xs:element name="positions" type="tns:ArrayOfPositions"/>
            <xs:element name="insuranceData" type="tns:AppDataInsuranceData"/>
            <xs:element name="customerData" type="tns:AppDataCustomerData"/>
            <xs:element name="vehicleData" type="tns:AppDataVehicleData"/>
            <xs:element name="miscData" type="tns:AppDataMiscData"/>
            <xs:element name="additionals" type="tns:ArrayOfAdditionals"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="processingResponse">
        <xs:sequence>
            <xs:element name="AppDataDataResult" type="tns:AppDataDataResult"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="processingResponse" nillable="true" type="tns:AppDataDataResult"/>
</xs:schema>

这是C#项目中Visual Studio生成的Service Reference中的代码:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://atu.de/soaptransformer/base/processing", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute("processingResponse", Namespace="http://atu.de/soaptransformer/base", IsNullable=true)]
public processingResponse processing([System.Xml.Serialization.XmlElementAttribute(Namespace="http://atu.de/soaptransformer/base", IsNullable=true)] processingRequest processingRequest) {
    object[] results = this.Invoke("processing", new object[] {
        processingRequest});
    return ((processingResponse)(results[0]));
}

我发现是否更改了以下行

[return: System.Xml.Serialization.XmlElementAttribute("processingResponse", Namespace="http://atu.de/soaptransformer/base", IsNullable=true)]

并添加“ Form = System.Xml.Schema.XmlSchemaForm.Unqualified”:

[return: System.Xml.Serialization.XmlElementAttribute("processingResponse", Namespace="http://atu.de/soaptransformer/base", IsNullable=true, Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

响应已正确映射到我的对象,并且现在看起来像这样工作,没有任何问题。

问题是我想从一开始就更改.xsd以正确生成这些源-我已经尝试过将Form = Unqualified添加到“ processingResponse” complexType内的“ AppDataDataResult”元素中,但是它不起作用。

将此属性直接添加到processingResponse元素不起作用,原因之一是不可能,原因是架构定义/标记下的一层。

我还没有找到解决此问题的任何具体解决方案,因为它似乎与Spring Boot Framework Java和wsdl的生成非常具体。

我希望有人可以帮助我解决这个问题,因为它似乎不是一个大问题(它的“唯一”属性是在生成源文件时需要添加的属性),但是我似乎找不到解决方案。预先感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我找到了问题,并且它是此问题的非常简单的解决方案-在我的Spring Boot项目中,我返回了JAXBElements,响应的参数是“ QName”,它指示响应的对象。这里的问题是,在.NET中生成Sources期间,SOAP-Response没有相关的命名空间来标识对象。因此,我向QName-Object添加了正确的Namespace-URI,现在对象已解析并返回正确的响应:

final QName qname = new QName(NAMESPACE_URI, "processingResponse");
return new JAXBElement<>(qname, ProcessingResponse.class, processingResponse);

最后,这是一个非常愚蠢/简单的问题,但我尝试了其他所有方法,但还没有尝试最明显/最简单的方法。