Unmarshaller 没有正确反序列化
Unmarshaller doesn't deserialize properly
我想从我的 Web 应用程序使用 SOAP Web 服务。我的 Web 应用程序使用 Spring 框架实现。 SOAP Web 服务需要身份验证,因此希望在 SOAP header 中发送用户名和密码信息。我通过覆盖 doWithMessage
将安全信息添加到发送 xml 消息的 header。现在我可以从 SOAP 服务获得正确的响应。但是 marshal 没有正确反序列化对 Java object 的响应。
XML 响应
<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1">
<u:Timestamp u:Id="_0">
<u:Created>2022-02-21T19:00:02.973Z</u:Created>
<u:Expires>2022-02-21T19:05:02.973Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<IsEInvoiceUserResponse
xmlns="http://tempuri.org/">
<IsEInvoiceUserResult IsSucceded="true" Value="false"/>
</IsEInvoiceUserResponse>
</s:Body>
</s:Envelope>
IsEInvoiceUserResponse.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"isEInvoiceUserResult"
})
@XmlRootElement(name = "IsEInvoiceUserResponse")
public class IsEInvoiceUserResponse {
@XmlElement(name = "IsEInvoiceUserResult")
protected FlagResponse isEInvoiceUserResult;
/**
* Gets the value of the isEInvoiceUserResult property.
*
* @return
* possible object is
* {@link FlagResponse }
*
*/
public FlagResponse getIsEInvoiceUserResult() {
return isEInvoiceUserResult;
}
/**
* Sets the value of the isEInvoiceUserResult property.
*
* @param value
* allowed object is
* {@link FlagResponse }
*
*/
public void setIsEInvoiceUserResult(FlagResponse value) {
this.isEInvoiceUserResult = value;
}
}
class 中扩展 WebServiceGatewaySupport
的函数
public IsEInvoiceUserResponse testUser() {
IsEInvoiceUser request = new ObjectFactory().createIsEInvoiceUser();
IsEInvoiceUserResponse response = (IsEInvoiceUserResponse) getWebServiceTemplate().marshalSendAndReceive(request, new SecurityHeader(authentication, ObjectFactory.SOAP_ACTION_IS_EINVOICE_USER));
return response;
}
response
不为空,但 response
的 child object 始终为空。
之后,我尝试用简单的代码反序列化 xml 响应字符串。但我也无法做到这一点。我真的不知道我哪里做错了。
String data = "<s:Envelope\n" +
" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">\n" +
" <s:Header>\n" +
" <o:Security s:mustUnderstand=\"1\"\n" +
" xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">\n" +
" <u:Timestamp u:Id=\"_0\">\n" +
" <u:Created>2022-02-18T07:44:56.344Z</u:Created>\n" +
" <u:Expires>2022-02-18T07:49:56.344Z</u:Expires>\n" +
" </u:Timestamp>\n" +
" </o:Security>\n" +
" </s:Header>\n" +
" <s:Body\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" +
" <IsEInvoiceUserResponse\n Value=\"true\" Data=\"The true\" " +
" xmlns=\"http://tempuri.org/\">\n" +
" <EInvoiceUserResult IsSucceded=\"true\" Value=\"false\"/>\n" +
" </IsEInvoiceUserResponse>\n" +
" </s:Body>\n" +
"</s:Envelope>";
JAXBContext jc;
try {
//SOAPMessage sm = MessageFactory.newInstance().createMessage(null, new ByteArrayInputStream(data.getBytes()));
jc = JAXBContext.newInstance(IsEInvoiceUserResponse2.class);
System.out.println("DATA : " + data);
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement<IsEInvoiceUserResponse2> object = unmarshaller.unmarshal(new StringSource(data), IsEInvoiceUserResponse2.class);
System.out.println("result : " + object.getValue().getValue());
} catch (JAXBException | SOAPException | IOException e) {
e.printStackTrace();
}
谢谢。
我从 WSDL 生成了 Java classes。但是我有很多 classes,我不想在我的项目中保留不必要的 classes。因此,我决定将它们重新安置在其他地方,并在真正需要 class 时复制。
我忽略了包信息在序列化和反序列化 soap 请求时非常重要。所以我的错是将 classes 放在同一个包中。我将 classes 分成包,然后添加 package-info.java
(我们可以复制生成的)然后问题就解决了。
我想从我的 Web 应用程序使用 SOAP Web 服务。我的 Web 应用程序使用 Spring 框架实现。 SOAP Web 服务需要身份验证,因此希望在 SOAP header 中发送用户名和密码信息。我通过覆盖 doWithMessage
将安全信息添加到发送 xml 消息的 header。现在我可以从 SOAP 服务获得正确的响应。但是 marshal 没有正确反序列化对 Java object 的响应。
XML 响应
<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1">
<u:Timestamp u:Id="_0">
<u:Created>2022-02-21T19:00:02.973Z</u:Created>
<u:Expires>2022-02-21T19:05:02.973Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<IsEInvoiceUserResponse
xmlns="http://tempuri.org/">
<IsEInvoiceUserResult IsSucceded="true" Value="false"/>
</IsEInvoiceUserResponse>
</s:Body>
</s:Envelope>
IsEInvoiceUserResponse.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"isEInvoiceUserResult"
})
@XmlRootElement(name = "IsEInvoiceUserResponse")
public class IsEInvoiceUserResponse {
@XmlElement(name = "IsEInvoiceUserResult")
protected FlagResponse isEInvoiceUserResult;
/**
* Gets the value of the isEInvoiceUserResult property.
*
* @return
* possible object is
* {@link FlagResponse }
*
*/
public FlagResponse getIsEInvoiceUserResult() {
return isEInvoiceUserResult;
}
/**
* Sets the value of the isEInvoiceUserResult property.
*
* @param value
* allowed object is
* {@link FlagResponse }
*
*/
public void setIsEInvoiceUserResult(FlagResponse value) {
this.isEInvoiceUserResult = value;
}
}
class 中扩展 WebServiceGatewaySupport
public IsEInvoiceUserResponse testUser() {
IsEInvoiceUser request = new ObjectFactory().createIsEInvoiceUser();
IsEInvoiceUserResponse response = (IsEInvoiceUserResponse) getWebServiceTemplate().marshalSendAndReceive(request, new SecurityHeader(authentication, ObjectFactory.SOAP_ACTION_IS_EINVOICE_USER));
return response;
}
response
不为空,但 response
的 child object 始终为空。
之后,我尝试用简单的代码反序列化 xml 响应字符串。但我也无法做到这一点。我真的不知道我哪里做错了。
String data = "<s:Envelope\n" +
" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">\n" +
" <s:Header>\n" +
" <o:Security s:mustUnderstand=\"1\"\n" +
" xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">\n" +
" <u:Timestamp u:Id=\"_0\">\n" +
" <u:Created>2022-02-18T07:44:56.344Z</u:Created>\n" +
" <u:Expires>2022-02-18T07:49:56.344Z</u:Expires>\n" +
" </u:Timestamp>\n" +
" </o:Security>\n" +
" </s:Header>\n" +
" <s:Body\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" +
" <IsEInvoiceUserResponse\n Value=\"true\" Data=\"The true\" " +
" xmlns=\"http://tempuri.org/\">\n" +
" <EInvoiceUserResult IsSucceded=\"true\" Value=\"false\"/>\n" +
" </IsEInvoiceUserResponse>\n" +
" </s:Body>\n" +
"</s:Envelope>";
JAXBContext jc;
try {
//SOAPMessage sm = MessageFactory.newInstance().createMessage(null, new ByteArrayInputStream(data.getBytes()));
jc = JAXBContext.newInstance(IsEInvoiceUserResponse2.class);
System.out.println("DATA : " + data);
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement<IsEInvoiceUserResponse2> object = unmarshaller.unmarshal(new StringSource(data), IsEInvoiceUserResponse2.class);
System.out.println("result : " + object.getValue().getValue());
} catch (JAXBException | SOAPException | IOException e) {
e.printStackTrace();
}
谢谢。
我从 WSDL 生成了 Java classes。但是我有很多 classes,我不想在我的项目中保留不必要的 classes。因此,我决定将它们重新安置在其他地方,并在真正需要 class 时复制。
我忽略了包信息在序列化和反序列化 soap 请求时非常重要。所以我的错是将 classes 放在同一个包中。我将 classes 分成包,然后添加 package-info.java
(我们可以复制生成的)然后问题就解决了。