简体   繁体   English

JAXB - Unmarshaller 试图实例化一个抽象类并且未能序列化到正确的类 - 忽略 @XmlSeeAlso

[英]JAXB - Unmarshaller trying to instantiate an abstract class and failing to serialise to the correct class - ignoring @XmlSeeAlso

I've been struggling with an unmarshalling issue with JAXB and POJOs created from the below WSDL (using the jaxws-maven-plugin and wsimport):我一直在努力解决从以下 WSDL 创建的 JAXB 和 POJO 的解组问题(使用 jaxws-maven-plugin 和 wsimport):

<wsdl:definitions targetNamespace="urn://tsys.com/xmlmessaging/CH" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tsys="urn://tsys.com/xmlmessaging/CH" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
 <wsdl:types>
    <xsd:schema targetNamespace="urn://tsys.com/xmlmessaging/CH" xmlns:tsys="urn://tsys.com/xmlmessaging/CH" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn://tsys.com/xmlmessaging/CH" elementFormDefault="qualified" attributeFormDefault="unqualified">
       <xsd:complexType name="TSYSMsgType" abstract="true">
          <xsd:attribute name="reqID" use="optional">
             <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                   <xsd:maxLength value="8"/>
                </xsd:restriction>
             </xsd:simpleType>
          </xsd:attribute>
       </xsd:complexType>
       <xsd:complexType name="TSYSRequestMsgType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSMsgType"></xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:complexType name="TSYSResponseMsgType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSMsgType">
                <xsd:attribute name="status" type="xsd:string" use="required"/>
                <xsd:attribute name="statusMsg" use="required">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:string">
                         <xsd:enumeration value="passed"/>
                         <xsd:enumeration value="failed"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
                <xsd:attribute name="version" use="optional" type="xsd:token"/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:complexType name="TSYSInquiryRequestType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSRequestMsgType">
                <xsd:attribute name="pageToken" use="optional">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:string">
                         <xsd:minLength value="0"/>
                         <xsd:maxLength value="200"/>
                         <xsd:whiteSpace value="preserve"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
                <xsd:attribute name="pageItems" use="optional">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:integer">
                         <xsd:minInclusive value="1"/>
                         <xsd:maxInclusive value="999"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:attributeGroup name="baseKeyGroup">
          <xsd:attribute name="key" type="xsd:token" use="optional"/>
          <xsd:attribute name="keyType" use="optional">
             <xsd:simpleType>
                <xsd:restriction base="xsd:token">
                   <xsd:enumeration value="cardNbr"/>
                   <xsd:enumeration value="acctID"/>
                </xsd:restriction>
             </xsd:simpleType>
          </xsd:attribute>
       </xsd:attributeGroup>
       <xsd:attributeGroup name="acctKeyGroup">
          <xsd:attribute name="key" type="xsd:token" use="optional"/>
          <xsd:attribute name="keyType" use="optional">
             <xsd:simpleType>
                <xsd:restriction base="xsd:token">
                   <xsd:enumeration value="cardNbr"/>
                   <xsd:enumeration value="acctID"/>
                </xsd:restriction>
             </xsd:simpleType>
          </xsd:attribute>
       </xsd:attributeGroup>
       <xsd:complexType name="TSYSAcctInquiryRequestType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSInquiryRequestType">
                <xsd:attributeGroup ref="acctKeyGroup"/>
                <xsd:attribute name="cardNbr" type="xsd:token" use="optional"/>
                <xsd:attribute name="acctID" type="xsd:token" use="optional"/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:complexType name="TSYSBaseInquiryRequestType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSInquiryRequestType">
                <xsd:attributeGroup ref="baseKeyGroup"/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType> 
       <xsd:complexType name="TSYSMultipleInquiryRequestType" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSRequestMsgType">
                <xsd:sequence>
                   <xsd:element name="inquireRequest" type="TSYSInquiryRequestType" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:sequence>
                <xsd:attributeGroup ref="baseKeyGroup"/>
                <xsd:attribute name="cardNbr" type="xsd:token" use="optional"/>
                <xsd:attribute name="acctID" type="xsd:token" use="optional"/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
      <xsd:complexType name="TSYSInquiryResponseType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSResponseMsgType">
                <xsd:attribute name="restartToken" use="optional">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:string">
                         <xsd:minLength value="0"/>
                         <xsd:maxLength value="200"/>
                         <xsd:whiteSpace value="preserve"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:complexType name="TSYSAcctInquiryResponseType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSInquiryResponseType">
                <xsd:attributeGroup ref="acctKeyGroup"/>
                <xsd:attribute name="cardNbr" type="xsd:token" use="optional"/>
                <xsd:attribute name="acctID" type="xsd:token" use="optional"/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:complexType name="TSYSBaseInquiryResponseType" abstract="true" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSInquiryResponseType">
                <xsd:attributeGroup ref="baseKeyGroup"/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
      
       <xsd:complexType name="TSYSMultipleInquiryResponseType" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="TSYSResponseMsgType">
                <xsd:sequence>
                   <xsd:element name="inquireResult" type="TSYSInquiryResponseType" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:sequence>
                <xsd:attributeGroup ref="baseKeyGroup"/>
                <xsd:attribute name="cardNbr" type="xsd:token" use="optional"/>
                <xsd:attribute name="acctID" type="xsd:token" use="optional"/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:element name="inqAcctStatus">
          <xsd:annotation id="inqAcctStatus">
          </xsd:annotation>
          <xsd:complexType>
             <xsd:sequence>
                <xsd:element ref="tsys:inqAcctStatusRequest"/>
             </xsd:sequence>
          </xsd:complexType>
       </xsd:element>
       <xsd:element name="inqAcctStatusResponse">
          <xsd:complexType>
             <xsd:sequence>
                <xsd:element ref="tsys:inqAcctStatusResult"/>
             </xsd:sequence>
          </xsd:complexType>
       </xsd:element>
       <xsd:complexType name="inqAcctStatusRequestType" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="tsys:TSYSAcctInquiryRequestType">
                <xsd:sequence>
                   <xsd:element name="acctNbrRef" minOccurs="0">
                      <xsd:annotation id="inqAcctStatus.inqAcctStatusRequest.acctNbrRef">
                         <xsd:documentation>Last four characters of the account number when account id is used as the key field in the request. This element is used to retrieve statuses from the account level segment.</xsd:documentation>
                      </xsd:annotation>
                      <xsd:simpleType>
                         <xsd:restriction base="xsd:integer">
                            <xsd:totalDigits value="4"/>
                         </xsd:restriction>
                      </xsd:simpleType>
                   </xsd:element>
                </xsd:sequence>
                <xsd:attribute name="statusReqCnt">
                   <xsd:annotation id="inqAcctStatus.inqAcctStatusRequest.statusReqCnt">
                      <xsd:documentation>Number of status codes that you are requesting.&lt;br>If you do not send a value in statusReqCnt, TSYS returns all status codes for the account. The maximum number returned is 200.</xsd:documentation>
                   </xsd:annotation>
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:integer">
                         <xsd:totalDigits value="3"/>
                         <xsd:minInclusive value="1"/>
                         <xsd:maxInclusive value="200"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
                <xsd:attribute name="version" use="required">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="1.2.0"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:complexType name="inqAcctStatusResponseType" mixed="false">
          <xsd:complexContent mixed="false">
             <xsd:extension base="tsys:TSYSAcctInquiryResponseType">
                <xsd:sequence>
                   <xsd:element name="statusCode" type="IASstatusCodeResponseDataType" minOccurs="0" maxOccurs="1" nillable="true"/>
                </xsd:sequence>
                <xsd:anyAttribute/>
             </xsd:extension>
          </xsd:complexContent>
       </xsd:complexType>
       <xsd:complexType name="IASstatusCodeResponseDataType">
          <xsd:sequence>
             <xsd:element name="status" minOccurs="0" maxOccurs="200" nillable="true">
                <xsd:annotation id="inqAcctStatus.inqAcctStatusResponse.statusCode.status">
                   <xsd:documentation>Container for status information.</xsd:documentation>
                </xsd:annotation>
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element name="reason" nillable="true">
                         <xsd:annotation id="inqAcctStatus.inqAcctStatusResponse.statusCode.status.reason">
                            <xsd:documentation>Reason code that further defines the condition of the account.  &lt;br>See Account Status and Reason Codes in the TS2 Codes and Definitions manual.</xsd:documentation>
                         </xsd:annotation>
                         <xsd:simpleType>
                            <xsd:restriction base="xsd:token">
                               <xsd:minLength value="1"/>
                               <xsd:maxLength value="2"/>
                            </xsd:restriction>
                         </xsd:simpleType>
                      </xsd:element>
                      <xsd:element name="desc" minOccurs="0" nillable="true">
                         <xsd:annotation id="inqAcctStatus.inqAcctStatusResponse.statusCode.status.desc">
                            <xsd:documentation>Description of the reason for the account status. &lt;br>For example, if an account status is CL (Account closed), and the reason is IR, the description shows the meaning of IR (Closed Interest Rate).</xsd:documentation>
                         </xsd:annotation>
                         <xsd:simpleType>
                            <xsd:restriction base="xsd:token">
                               <xsd:minLength value="1"/>
                               <xsd:maxLength value="25"/>
                            </xsd:restriction>
                         </xsd:simpleType>
                      </xsd:element>
                      <xsd:element name="x_1.0.0" nillable="true" type="xsd:string"/>
                      <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
                   </xsd:sequence>
                   <xsd:attribute name="code">
                      <xsd:annotation id="inqAcctStatus.inqAcctStatusResponse.statusCode.status.code">
                         <xsd:documentation>Code for the condition of the account. &lt;br>See Account Status and Reason Codes in the TS2 Codes and Definitions manual.</xsd:documentation>
                      </xsd:annotation>
                      <xsd:simpleType>
                         <xsd:restriction base="xsd:token">
                            <xsd:length value="2"/>
                         </xsd:restriction>
                      </xsd:simpleType>
                   </xsd:attribute>
                   <xsd:anyAttribute/>
                </xsd:complexType>
             </xsd:element>
             <xsd:element name="x_1.0.0" nillable="true" type="xsd:string"/>
             <xsd:element name="digitalIssuanceInd" minOccurs="0" nillable="true">
                <xsd:simpleType>
                   <xsd:restriction base="xsd:token">
                      <xsd:enumeration value="DII not indicated"/>
                      <xsd:enumeration value="DII special processing"/>
                      <xsd:enumeration value="DII CRV Activated"/>
                      <xsd:enumeration value="NIL"/>
                   </xsd:restriction>
                </xsd:simpleType>
             </xsd:element>
             <xsd:element name="x_1.2.0" nillable="true" type="xsd:string"/>
             <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
          </xsd:sequence>
          <xsd:anyAttribute/>
       </xsd:complexType>
       
       <xsd:element name="inqAcctStatusRequest" type="inqAcctStatusRequestType" substitutionGroup="inquireRequest"/>
       <xsd:element name="inqAcctStatusResult" type="inqAcctStatusResponseType" substitutionGroup="inquireResponse"/>

       <xsd:element name="inqMulti">
          <xsd:complexType>
             <xsd:sequence>
                <xsd:element name="inqMultiRequest" type="tsys:TSYSMultipleInquiryRequestType" minOccurs="0"/>
             </xsd:sequence>
          </xsd:complexType>
       </xsd:element>
       <xsd:element name="inqMultiResponse">
          <xsd:complexType>
             <xsd:sequence>
                <xsd:element name="inqMultiResult" type="tsys:TSYSMultipleInquiryResponseType" minOccurs="0"/>
             </xsd:sequence>
          </xsd:complexType>
       </xsd:element>
       <xsd:element name="inquireRequest" type="tsys:TSYSInquiryRequestType"/>
       <xsd:element name="inquireResponse" type="tsys:TSYSInquiryResponseType" nillable="true"/>

       <xsd:complexType name="currency">
          <xsd:simpleContent>
             <xsd:extension base="xsd:decimal">
                <xsd:attribute name="code" use="required">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:token">
                         <xsd:length value="3"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
             </xsd:extension>
          </xsd:simpleContent>
       </xsd:complexType>
       <xsd:simpleType name="phoneNumber">
          <xsd:restriction base="xsd:string"/>
       </xsd:simpleType>
       <xsd:complexType name="base64Binary">
          <xsd:simpleContent>
             <xsd:extension base="xsd:base64Binary">
                <xsd:attribute name="checksum">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:token">
                         <xsd:length value="8"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
             </xsd:extension>
          </xsd:simpleContent>
       </xsd:complexType>
       <xsd:complexType name="charLargeObj">
          <xsd:simpleContent>
             <xsd:extension base="xsd:string">
                <xsd:attribute name="checksum">
                   <xsd:simpleType>
                      <xsd:restriction base="xsd:token">
                         <xsd:length value="8"/>
                      </xsd:restriction>
                   </xsd:simpleType>
                </xsd:attribute>
             </xsd:extension>
          </xsd:simpleContent>
       </xsd:complexType>
        <xsd:simpleType name="TSYScustID">
          <xsd:restriction base="xsd:token">
             <xsd:length value="9"/>
             <xsd:pattern value="\d+"/>
          </xsd:restriction>
       </xsd:simpleType>
    </xsd:schema>
 </wsdl:types>
 <wsdl:message name="soapTSYSprofileInq">
    <wsdl:part element="tsys:TSYSprofileInq" name="TSYSprofile"/>
 </wsdl:message>

 <wsdl:message name="inqMultiSoapIn">
    <wsdl:part element="tsys:inqMulti" name="parameters"/>
 </wsdl:message>
 <wsdl:message name="inqMultiSoapOut">
    <wsdl:part element="tsys:inqMultiResponse" name="parameters"/>
 </wsdl:message>

 <wsdl:portType name="TSYSXMLMessagingSoapInquiry">
    <wsdl:operation name="inqMulti">
       <wsdl:input message="tsys:inqMultiSoapIn"/>
       <wsdl:output message="tsys:inqMultiSoapOut"/>
    </wsdl:operation>
</wsdl:portType>
 <wsdl:binding name="TSYSXMLMessagingSoapInquiry" type="tsys:TSYSXMLMessagingSoapInquiry">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="inqMulti">
       <soap:operation soapAction="urn://tsys.com/xmlmessaging/CH/inqMulti" style="document"/>
       <wsdl:input>
          <soap:header message="tsys:soapTSYSprofileInq" part="TSYSprofile" use="literal"/>
          <soap:body use="literal"/>
       </wsdl:input>
       <wsdl:output>
          <soap:header message="tsys:soapTSYSprofileInq" part="TSYSprofile" use="literal"/>
          <soap:body use="literal"/>
       </wsdl:output>
    </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="TSYSXMLMessagingInquiry">
    <wsdl:port binding="tsys:TSYSXMLMessagingSoapInquiry" name="TSYSXMLMessagingSoapInquiry05">
       <soap:address location="HTTP://YOUR.URL.HERE"/>
    </wsdl:port>
    <wsdl:port binding="tsys:TSYSXMLMessagingSoapInquiry" name="TSYSXMLMessagingSoapInquiry06">
       <soap:address location="HTTP://YOUR.URL.HERE"/>
    </wsdl:port>
 </wsdl:service>
</wsdl:definitions>

The Java classes generated by wsimport: wsimport 生成的 Java 类:

TSYSInquiryResponseType TSYSInquiryResponseType

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TSYSInquiryResponseType")
@XmlSeeAlso({
    TSYSAcctInquiryResponseType.class,
    TSYSBaseInquiryResponseType.class,
    TSYSCustomerInquiryResponseType.class
})
public  class TSYSInquiryResponseType
    extends TSYSResponseMsgType
{
    @XmlAttribute(name = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
    private String xsiType;

    @XmlAttribute(name = "restartToken")
    protected String restartToken;

    /**
     * Gets the value of the restartToken property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getRestartToken() {
        return restartToken;
    }

    /**
     * Sets the value of the restartToken property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setRestartToken(String value) {
        this.restartToken = value;
    }

    public String getXsiType() {
        return xsiType;
    }

    public void setXsiType(String xsiType) {
        this.xsiType = xsiType;
    }
}

InqAcctStatusResponseType InqAcctStatusResponseType

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TSYSAcctInquiryResponseType")
@XmlSeeAlso({
    InqAcctStatusResponseType.class
})
public abstract class TSYSAcctInquiryResponseType
    extends TSYSInquiryResponseType
{

    @XmlAttribute(name = "cardNbr")
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlSchemaType(name = "token")
    protected String cardNbr;
    @XmlAttribute(name = "acctID")
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlSchemaType(name = "token")
    protected String acctID;

    /**
     * Gets the value of the cardNbr property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getCardNbr() {
        return cardNbr;
    }

    /**
     * Sets the value of the cardNbr property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setCardNbr(String value) {
        this.cardNbr = value;
    }

    /**
     * Gets the value of the acctID property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getAcctID() {
        return acctID;
    }

    /**
     * Sets the value of the acctID property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setAcctID(String value) {
        this.acctID = value;
    }
}

InqAcctStatusResponseType InqAcctStatusResponseType

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "inqAcctStatusResponseType", propOrder = {
    "statusCode"
})
public class InqAcctStatusResponseType
    extends TSYSAcctInquiryResponseType
{

    @XmlElementRef(name = "statusCode", namespace = "urn://tsys.com/xmlmessaging/CH", type = JAXBElement.class, required = false)
    protected JAXBElement<IASstatusCodeResponseDataType> statusCode;
    @XmlAnyAttribute
    private Map<QName, String> otherAttributes = new HashMap<QName, String>();

    /**
     * Gets the value of the statusCode property.
     * 
     * @return
     *     possible object is
     *     {@link JAXBElement }{@code <}{@link IASstatusCodeResponseDataType }{@code >}
     *     
     */
    public JAXBElement<IASstatusCodeResponseDataType> getStatusCode() {
        return statusCode;
    }

    /**
     * Sets the value of the statusCode property.
     * 
     * @param value
     *     allowed object is
     *     {@link JAXBElement }{@code <}{@link IASstatusCodeResponseDataType }{@code >}
     *     
     */
    public void setStatusCode(JAXBElement<IASstatusCodeResponseDataType> value) {
        this.statusCode = value;
    }

    /**
     * Gets a map that contains attributes that aren't bound to any typed property on this class.
     * 
     * <p>
     * the map is keyed by the name of the attribute and 
     * the value is the string value of the attribute.
     * 
     * the map returned by this method is live, and you can add new attribute
     * by updating the map directly. Because of this design, there's no setter.
     * 
     * 
     * @return
     *     always non-null
     */
    public Map<QName, String> getOtherAttributes() {
        return otherAttributes;
    }

}

So you can see that the abstract TSYSInquiryResponseType contains an @XmlSeeAlso linking it to another abstract TSYSAcctInquiryResponseType class, which in turn @XmlSeeAlso links to the concrete InqAcctStatusResponseType class - which in turn has the @XmlType tag.因此,您可以看到抽象TSYSInquiryResponseType包含一个@XmlSeeAlso将其链接到另一个抽象TSYSAcctInquiryResponseType类,而后者又将@XmlSeeAlso链接到具体的InqAcctStatusResponseType类 - 该类又具有@XmlType标记。

It's my understanding that the combination of this inheritance and context loading should enable the unmarshaller to process the below SOAP message and create the correct inqAcctStatusResponseType class;我的理解是这种继承和上下文加载的结合应该使解组器能够处理下面的 SOAP 消息并创建正确的 inqAcctStatusResponseType 类; however, I'm getting an InstantiationException - as the unmarshaller is trying to instantiate the abstract TSYSInquiryResponseType .但是,我得到了一个 InstantiationException - 因为解组器正在尝试实例化抽象的TSYSInquiryResponseType

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn://tsys.com/xmlmessaging/CH">
   <soap:Header>
      <TSYSprofileInq xsi:type="TSYSprofileType">
         <clientID>8571</clientID>
         <userID>MOBAPP</userID>
         <vendorID>00000000</vendorID>
         <securityID>8571</securityID>
         <logID>MOBAPP</logID>
         <TSYSInfo>CIC1VS0P-MQP0</TSYSInfo>
      </TSYSprofileInq>
   </soap:Header>
   <soap:Body>
      <inqMultiResponse>
         <inqMultiResult status="000" statusMsg="passed" acctID="00000096432" key="5276690020709766" keyType="cardNbr">
            <inquireResult xsi:type="inqAcctStatusResponseType" status="000" statusMsg="passed" key="5276690020709766" keyType="cardNbr" version="1.2.0">
               <statusCode>
                  <status code="IN">
                     <reason>C</reason>
                     <desc>INACTIVE SINCE OPEN</desc>
                     <x_1.0.0/>
                  </status>
                  <status code="DC">
                     <reason>Q1</reason>
                     <desc>FIXED REPAYMENT PROGRAM</desc>
                     <x_1.0.0/>
                  </status>
                  <status code="FU">
                     <reason>PU</reason>
                     <desc>FIRST USE WAS PURCHASE</desc>
                     <x_1.0.0/>
                  </status>
                  <status code="TA">
                     <reason>P</reason>
                     <desc>PERSONAL TYPE ACCOUNT</desc>
                     <x_1.0.0/>
                  </status>
                  <status code="YT">
                     <reason>Y</reason>
                     <desc>ACCOUNT CYCLED TODAY</desc>
                     <x_1.0.0/>
                  </status>
                  <x_1.0.0/>
                  <digitalIssuanceInd>DII not indicated</digitalIssuanceInd>
                  <x_1.2.0/>
               </statusCode>
            </inquireResult>
         </inqMultiResult>
      </inqMultiResponse>
   </soap:Body>
</soap:Envelope>

2022-06-10 09:58:07.816 ERROR 3604 --- [o-auto-1-exec-2] cvpswTsysWebClient : Exception caught whilst retrieving Inquiry for AccountId: 00000097686, Exception: org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling exception; 2022-06-10 09:58:07.816 错误 3604 --- [o-auto-1-exec-2] cvpswTsysWebClient:在检索 AccountId 查询时捕获异常:00000097686,异常:org.springframework.oxm.UnmarshallingFailureException:JAXB 解组例外; nested exception is javax.xml.bind.UnmarshalException: Unable to create an instance of com.virginmoney.tsys.ws.client.generated.TSYSInquiryResponseType with linked exception: [java.lang.InstantiationException]嵌套异常是 javax.xml.bind.UnmarshalException: Unable to create an instance of com.virginmoney.tsys.ws.client.generated.TSYSInquiryResponseType with linked exception: [java.lang.InstantiationException]

I had a search and found similar issues being described: JAXB: Unmarshaller tries to instantiate abstract class (ignoring xsi:type)我进行了搜索,发现描述了类似的问题: JAXB: Unmarshaller trying to instantiate abstract class (ignoring xsi:type)

InstantiationException during JAXB Unmarshalling (abstract base class, with @XmlSeeAlso concrete sub class) JAXB Unmarshalling 期间的 InstantiationException(抽象基类,带有 @XmlSeeAlso 具体子类)

None of the suggestions seem to have made a difference.这些建议似乎都没有产生任何影响。 I'm using Java11 and spring-boot-starter-parent v2.6.0我正在使用 Java11 和 spring-boot-starter-parent v2.6.0

Does anyone have any ideas please?请问有人有什么想法吗? I feel like I'm going a bit code blind.我觉得我有点代码盲了。

Thanks in advance.提前致谢。

UPDATE - SOLUTION Manipulating the SOAP response to inject namespaces resulted in the unmarshaller working as expected更新 - 解决方案操纵 SOAP 响应以注入命名空间导致解组器按预期工作

StreamResult result = new StreamResult(bytArrayOutputStream);
    getWebServiceTemplate().sendSourceAndReceiveToResult(marshall(inqMulti), webServiceMessage -> {
        try {
            SoapHeader soapHeader = ((SoapMessage) webServiceMessage).getSoapHeader();

            // create the header element
            ObjectFactory factory = new ObjectFactory();
            TSYSprofileType inqAcctStatusSoapHeader =
                    factory.createTSYSprofileType();
            inqAcctStatusSoapHeader.setClientID(profileHeaderClientId);
            inqAcctStatusSoapHeader.setUserID(profileHeaderUserId);
            inqAcctStatusSoapHeader.setVendorID(profileHeaderVendorId);

            JAXBElement<TSYSprofileType> headers =
                    factory.createTSYSprofileInq(inqAcctStatusSoapHeader);

            // create a marshaller
            JAXBContext context = JAXBContext.newInstance(TSYSprofileType.class);
            Marshaller marshaller = context.createMarshaller();

            // marshal the headers into the specified result
            marshaller.marshal(headers, soapHeader.getResult());
        } catch (JAXBException e) {
            logger.error("Exception caught whilst activation for AccountId: {}, Exception: {}", accountId, e);
        }
    }, result);

    String inqMultiResponseString = new String(bytArrayOutputStream.toByteArray());
    inqMultiResponseString = inqMultiResponseString.replaceAll("<inqMultiResponse xmlns=\"urn://tsys.com/xmlmessaging/CH\">", "<inqMultiResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:tsys=\"urn://tsys.com/xmlmessaging/CH\">");
    inqMultiResponseString = inqMultiResponseString.replaceAll("</", "</tsys:");
    inqMultiResponseString = inqMultiResponseString.replaceAll("<(?!/)", "<tsys:");
    inqMultiResponseString = inqMultiResponseString.replaceFirst("<tsys:", "<"); //fixing the <xml version> tag
    inqMultiResponseString = inqMultiResponseString.replaceAll("xsi:type=\"", "xsi:type=\"tsys:");

I managed to resolve my issue - it turns out the SOAP response I was receiving was lacking the expected namespace declarations.我设法解决了我的问题 - 结果发现我收到的 SOAP 响应缺少预期的命名空间声明。 Adding these in (via some string manipulation) allowed the unmarshaller to work as expected添加这些(通过一些字符串操作)允许解组器按预期工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM