jaxb- unmarshaller试图实例化抽象类而无法序列化到正确的类 - 忽略@xmlseealso
我一直在为Jaxb和Pojos创建的Jaxb和Pojos遇到艰难的问题(使用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.<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. <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. <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. <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>
WSIMPORT生成的Java类:
tsysinquiryresponseponsementype <
@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;
}
}
/stsysinquiryresponseptem /strong>
@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;
}
}
inqaccttatusresponseType
@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;
}
}
,因此您可以看到抽象 tsysinquiryresponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseponseType 包含 @xmlseealso 将其链接到另一个摘要 tsysacctinquryResponseTypeponseType 班级,这又是 @xmlseealso 链接到具体 inqaccttatusresponseponseptype class-又有 @xmltype 标签。
我的理解是,这种继承和上下文加载的组合应该使Unmarshaller能够处理以下肥皂消息并创建正确的Inqaccttatusresponseponseponsepe class;但是,我得到了一个实例化感受 - 因为Unmarshaller试图实例化摘要 tsysinquiryresponseponsepy 。
<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错误3604 --- [O-AUTO-1-EXEC-2] cvpswtsyswebclient:捕获的例外 检索AccountId的查询:00000097686,例外: org.springframework.oxm.unmarshallingfailureException:jaxb 解除异常;嵌套异常是 javax.xml.bind.unmarshalexception:无法创建一个实例 com.virginmoney.tsys.ws.client.generated.tsysinquiryresponstype 与链接的例外:[java.lang.instantiationException]
我进行了搜索,并发现了类似的问题: jaxb:
似乎没有任何建议有所作为。我正在使用Java11和Spring-Boot-Starter-Parent v2.6.0
有人有任何想法吗?我觉得我要盲目了。
提前致谢。
更新 - 解决方案 操纵对注入命名空间的肥皂响应导致Unmarshaller按预期工作
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've been struggling with an unmarshalling issue with JAXB and POJOs created from the below WSDL (using the jaxws-maven-plugin and 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.<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. <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. <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. <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:
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
@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
@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.
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; however, I'm getting an InstantiationException - as the unmarshaller is trying to instantiate the abstract 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]
c.v.p.s.w.TsysWebClient : Exception caught whilst
retrieving Inquiry for AccountId: 00000097686, Exception:
org.springframework.oxm.UnmarshallingFailureException: JAXB
unmarshalling exception; 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]
I had a search and found similar issues being described:
JAXB: Unmarshaller tries to instantiate abstract class (ignoring xsi:type)
None of the suggestions seem to have made a difference. I'm using Java11 and 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
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:");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我设法解决了自己的问题 - 事实证明,我收到的肥皂反应缺乏预期的名称空间声明。将它们添加到(通过某些字符串操纵)中,使Unmarshaller可以按预期工作
I managed to resolve my issue - it turns out the SOAP response I was receiving was lacking the expected namespace declarations. Adding these in (via some string manipulation) allowed the unmarshaller to work as expected