【问题标题】:Cannot get SOAP envelope body using Retrofit 2 and Simple XML Converter无法使用 Retrofit 2 和 Simple XML Converter 获取 SOAP 信封主体
【发布时间】:2017-04-20 00:32:41
【问题描述】:

我正在使用 Retrofit 2.2.0 和 Retrofit SimpleXML Converter 2.2.0。我使用addConverterFactory 方法将SimpleXmlConverter 添加到Retrofit 实例中。

问题是当我收到响应时,它得到以下错误

java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: 元素 'Body' 在第 1 行的类 ResponseEnvelope 中没有匹配项

我应该得到这样的 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 类中,我不知道如何将属性xsi:type 放入其中。有人可以帮帮我吗?

【问题讨论】:

    标签: android xml soap retrofit simple-framework


    【解决方案1】:

    我不知道简单 XML 转换器是如何工作的,但元素名称就是元素名称,它们可以是前缀。这似乎是一种混淆,因为: 字符用于分隔物理 XML 文档(标签)中的命名空间前缀和元素名称。

    您只需从名称中删除“前缀”并添加@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章

    【讨论】:

    • 它会抛出这个错误“java.lang.RuntimeException: org.simpleframework.xml.core.PersistenceException: Constructor not match for class”
    • @LyubomyrShaydariv 请您查看stackoverflow.com/questions/50808494/… 这个链接并回答我.. 我太累了,无法查看它
    • 您好,我是否需要每次都为新的 Web 服务创建新的 ResponseBody 和 ResponseData 类?如何将其转换为一些常见的结构? @LyubomyrShaydariv
    • 你让我很开心。感谢@Lyubomyr 的回答。
    猜你喜欢
    • 2018-03-19
    • 2017-07-20
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    相关资源
    最近更新 更多