无法使用 Retrofit 2 和 Simple XML 转换器获取 SOAP 信封正文
Cannot get SOAP envelope body using Retrofit 2 and Simple XML Converter
我正在使用 Retrofit 2.2.0 和 Retrofit SimpleXML Converter 2.2.0。我使用 addConverterFactory
方法将 SimpleXmlConverter
添加到 Retrofit
实例。
问题是当我收到响应时,出现以下错误
java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: Element 'Body' does not have a match in class ResponseEnvelope at line 1
我应该得到这样的 XML 响应:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:autenticarUsuarioPorEmailResponse xmlns:ns="http://business.curitiba.org.br">
<ns:return xsi:type="ax2471:AutenticaUsuarioPorEmailSaida" xmlns:ax2471="http://saidas.curitiba.org/xsd" xmlns:ax2469="http://entities.curitiba.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ax2467="http://entradas.curitiba.org/xsd">
<ax2471:idCredencial>3282</ax2471:idCredencial>
<ax2471:tokenAcesso>635E3DA9-7C02-4DB7-9653-E7688C66B02C</ax2471:tokenAcesso>
</ns:return>
</ns:autenticarUsuarioPorEmailResponse>
</soapenv:Body>
</soapenv:Envelope>
ResponseEnvelope.java
@Root(name = "soapenv:Envelope")
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
public class ResponseEnvelope {
@Element(name = "soapenv:Body", required = false)
private ResponseBody body;
public ResponseBody getBody() {
return body;
}
public void setBody(ResponseBody body) {
this.body = body;
}
}
ResponseBody.java
@Root(name = "soapenv:Body", strict = false)
public class ResponseBody {
@Element(name = "ns:cadastrarCredencialEmailResponse", required = false)
private ResponseData requestData;
public ResponseData getRequestData() {
return requestData;
}
public void setRequestData(ResponseData requestData) {
this.requestData = requestData;
}
}
ResponseData.java
@Root(name = "ns:cadastrarCredencialEmailResponse", strict = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
public class ResponseData {
@Element(name = "ns:return", required = false)
private ResponseInfo info;
public ResponseInfo getInfo() {
return info;
}
public void setInfo(ResponseInfo info) {
this.info = info;
}
}
ResponseInfo.java
@Root(name = "ns:return", strict = false)
@NamespaceList({
@Namespace(prefix = "ax2471", reference = "http://saidas.curitiba.org/xsd"),
@Namespace(prefix = "ax2469", reference = "http://entities.curitiba.org/xsd"),
@Namespace(prefix = "xsi", reference = "http://www.w3.org/2001/XMLSchema-instance"),
@Namespace(prefix = "ax2467", reference = "http://entradas.curitiba.org/xsd")
})
public class ResponseInfo {
@Element(name = "ax2471:codigoAtivacao", required = false)
private String codigoAtivacao;
@Element(name = "ax2471:idCredencial", required = false)
private String idCredencial;
public String getCodigoAtivacao() {
return codigoAtivacao;
}
public void setCodigoAtivacao(String codigoAtivacao) {
this.codigoAtivacao = codigoAtivacao;
}
public String getIdCredencial() {
return idCredencial;
}
public void setIdCredencial(String idCredencial) {
this.idCredencial = idCredencial;
}
}
我猜问题出在 ResponseInfo
class,我不知道如何将属性 xsi:type
放入其中。有人可以帮助我吗?
我不知道简单 XML 转换器是如何工作的,但元素名称是元素名称,它们可以是 前缀。这似乎是混淆,因为 :
字符用于分隔物理 XML 文档(标签)中的名称空间前缀和元素名称。
您可以只从名称中删除 "prefix" 并添加 @Namespace
注释。例如:
ResponseEnvelope.java
@Root(name = "Envelope")
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
final class ResponseEnvelope {
@Element(name = "Body", required = false)
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
final ResponseBody body;
private ResponseEnvelope(
@Element(name = "Body") final ResponseBody body
) {
this.body = body;
}
}
ResponseBody.java
@Root(name = "Body", strict = false)
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
final class ResponseBody {
@Element(name = "autenticarUsuarioPorEmailResponse", required = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final ResponseData requestData;
private ResponseBody(
@Element(name = "autenticarUsuarioPorEmailResponse") final ResponseData requestData
) {
this.requestData = requestData;
}
}
ResponseData.java
@Root(name = "autenticarUsuarioPorEmailResponse", strict = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final class ResponseData {
@Element(name = "return", required = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final ResponseInfo info;
private ResponseData(
@Element(name = "return") final ResponseInfo info
) {
this.info = info;
}
}
ResponseInfo.java
@Root(name = "return", strict = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final class ResponseInfo {
@Element(name = "tokenAcesso", required = false)
@Namespace(prefix = "ax2471", reference = "http://saidas.curitiba.org/xsd")
final String accessToken;
@Element(name = "idCredencial", required = false)
@Namespace(prefix = "ax2471", reference = "http://saidas.curitiba.org/xsd")
final String credentialId;
private ResponseInfo(
@Element(name = "tokenAcesso") final String accessToken,
@Element(name = "idCredencial") final String credentialId
) {
this.accessToken = accessToken;
this.credentialId = credentialId;
}
}
所以下面的例子:
final ResponseInfo info = responseEnvelope.body.requestData.info;
System.out.println(info.accessToken);
System.out.println(info.credentialId);
将输出:
635E3DA9-7C02-4DB7-9653-E7688C66B02C
3282
我正在使用 Retrofit 2.2.0 和 Retrofit SimpleXML Converter 2.2.0。我使用 addConverterFactory
方法将 SimpleXmlConverter
添加到 Retrofit
实例。
问题是当我收到响应时,出现以下错误
java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: Element 'Body' does not have a match in class ResponseEnvelope at line 1
我应该得到这样的 XML 响应:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:autenticarUsuarioPorEmailResponse xmlns:ns="http://business.curitiba.org.br">
<ns:return xsi:type="ax2471:AutenticaUsuarioPorEmailSaida" xmlns:ax2471="http://saidas.curitiba.org/xsd" xmlns:ax2469="http://entities.curitiba.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ax2467="http://entradas.curitiba.org/xsd">
<ax2471:idCredencial>3282</ax2471:idCredencial>
<ax2471:tokenAcesso>635E3DA9-7C02-4DB7-9653-E7688C66B02C</ax2471:tokenAcesso>
</ns:return>
</ns:autenticarUsuarioPorEmailResponse>
</soapenv:Body>
</soapenv:Envelope>
ResponseEnvelope.java
@Root(name = "soapenv:Envelope")
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
public class ResponseEnvelope {
@Element(name = "soapenv:Body", required = false)
private ResponseBody body;
public ResponseBody getBody() {
return body;
}
public void setBody(ResponseBody body) {
this.body = body;
}
}
ResponseBody.java
@Root(name = "soapenv:Body", strict = false)
public class ResponseBody {
@Element(name = "ns:cadastrarCredencialEmailResponse", required = false)
private ResponseData requestData;
public ResponseData getRequestData() {
return requestData;
}
public void setRequestData(ResponseData requestData) {
this.requestData = requestData;
}
}
ResponseData.java
@Root(name = "ns:cadastrarCredencialEmailResponse", strict = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
public class ResponseData {
@Element(name = "ns:return", required = false)
private ResponseInfo info;
public ResponseInfo getInfo() {
return info;
}
public void setInfo(ResponseInfo info) {
this.info = info;
}
}
ResponseInfo.java
@Root(name = "ns:return", strict = false)
@NamespaceList({
@Namespace(prefix = "ax2471", reference = "http://saidas.curitiba.org/xsd"),
@Namespace(prefix = "ax2469", reference = "http://entities.curitiba.org/xsd"),
@Namespace(prefix = "xsi", reference = "http://www.w3.org/2001/XMLSchema-instance"),
@Namespace(prefix = "ax2467", reference = "http://entradas.curitiba.org/xsd")
})
public class ResponseInfo {
@Element(name = "ax2471:codigoAtivacao", required = false)
private String codigoAtivacao;
@Element(name = "ax2471:idCredencial", required = false)
private String idCredencial;
public String getCodigoAtivacao() {
return codigoAtivacao;
}
public void setCodigoAtivacao(String codigoAtivacao) {
this.codigoAtivacao = codigoAtivacao;
}
public String getIdCredencial() {
return idCredencial;
}
public void setIdCredencial(String idCredencial) {
this.idCredencial = idCredencial;
}
}
我猜问题出在 ResponseInfo
class,我不知道如何将属性 xsi:type
放入其中。有人可以帮助我吗?
我不知道简单 XML 转换器是如何工作的,但元素名称是元素名称,它们可以是 前缀。这似乎是混淆,因为 :
字符用于分隔物理 XML 文档(标签)中的名称空间前缀和元素名称。
您可以只从名称中删除 "prefix" 并添加 @Namespace
注释。例如:
ResponseEnvelope.java
@Root(name = "Envelope")
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
final class ResponseEnvelope {
@Element(name = "Body", required = false)
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
final ResponseBody body;
private ResponseEnvelope(
@Element(name = "Body") final ResponseBody body
) {
this.body = body;
}
}
ResponseBody.java
@Root(name = "Body", strict = false)
@Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/")
final class ResponseBody {
@Element(name = "autenticarUsuarioPorEmailResponse", required = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final ResponseData requestData;
private ResponseBody(
@Element(name = "autenticarUsuarioPorEmailResponse") final ResponseData requestData
) {
this.requestData = requestData;
}
}
ResponseData.java
@Root(name = "autenticarUsuarioPorEmailResponse", strict = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final class ResponseData {
@Element(name = "return", required = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final ResponseInfo info;
private ResponseData(
@Element(name = "return") final ResponseInfo info
) {
this.info = info;
}
}
ResponseInfo.java
@Root(name = "return", strict = false)
@Namespace(prefix = "ns", reference = "http://business.curitiba.org")
final class ResponseInfo {
@Element(name = "tokenAcesso", required = false)
@Namespace(prefix = "ax2471", reference = "http://saidas.curitiba.org/xsd")
final String accessToken;
@Element(name = "idCredencial", required = false)
@Namespace(prefix = "ax2471", reference = "http://saidas.curitiba.org/xsd")
final String credentialId;
private ResponseInfo(
@Element(name = "tokenAcesso") final String accessToken,
@Element(name = "idCredencial") final String credentialId
) {
this.accessToken = accessToken;
this.credentialId = credentialId;
}
}
所以下面的例子:
final ResponseInfo info = responseEnvelope.body.requestData.info;
System.out.println(info.accessToken);
System.out.println(info.credentialId);
将输出:
635E3DA9-7C02-4DB7-9653-E7688C66B02C
3282