I am using Retrofit 2.2.0 and Retrofit SimpleXML Converter 2.2.0. I added SimpleXmlConverter
to the Retrofit
instance with the addConverterFactory
method.
The problem is that when I receive the response, it gets the following error
java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: Element 'Body' does not have a match in class ResponseEnvelope at line 1
I should get an XML response like this:
<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>
@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;
}
}
@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;
}
}
@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;
}
}
@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;
}
}
I guess the problem is in the ResponseInfo
class, that I don't know how to put the attribute xsi:type
into it. Can anybody help me?
The SOAP Envelope encapsulates all the data in a message and identifies the XML document as a SOAP message. The Header element contains additional information about the SOAP message. This information could be authentication credentials, for example, which are used by the calling application.
The SOAPEnvelope interface provides three methods for creating Name objects. One method creates Name objects with a local name, a namespace prefix, and a namesapce URI. The second method creates Name objects with a local name and a namespace prefix, and the third creates Name objects with just a local name.
Retrofit is type-safe REST client for Android and Java which aims to make it easier to consume RESTful web services. We'll not go into the details of Retrofit 1. x versions and jump onto Retrofit 2 directly which has a lot of new features and a changed internal API compared to the previous versions.
I don't know how the Simple XML Converter works exactly, but element names are elements names, and they can be prefixed. This seems to be the confusion because the :
character is used to delimit namespace prefixes and element names in physical XML document (tags).
You can just remove the "prefix" from the name and add the @Namespace
annotation. For example:
@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;
}
}
@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;
}
}
@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;
}
}
@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;
}
}
So the following example:
final ResponseInfo info = responseEnvelope.body.requestData.info;
System.out.println(info.accessToken);
System.out.println(info.credentialId);
will output:
635E3DA9-7C02-4DB7-9653-E7688C66B02C
3282
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With