使用Retrofit和SimpleXML解析SOAP请求(Android)

时间:2018-07-19 10:25:54

标签: android soap kotlin retrofit2

我需要在kotlin中解析此响应XML

     <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.isban.es/webservices/TECHNICAL_FACADES/Security/F_facseg_security/internet/loginServicesNSegSAN/v1">
   <soapenv:Header/>
   <soapenv:Body>
      <v1:authenticateCredential facade="loginServicesNSegSAN">
         <CB_AuthenticationData>
            <password>12313212</password>
            <documento>
               <TIPO_DOCUM_PERSONA_CORP>N</TIPO_DOCUM_PERSONA_CORP>
               <CODIGO_DOCUM_PERSONA_CORP>12312321d</CODIGO_DOCUM_PERSONA_CORP>
            </documento>
         </CB_AuthenticationData>
         <!--<userAddress>182...</userAddress>-->
      </v1:authenticateCredential>
   </soapenv:Body>
</soapenv:Envelope>

这是我的响应映射类

 @Root(name = "soap-env:Envelope", strict = false)
    @Namespace(prefix = "soap-env", reference "http://schemas.xmlsoap.org/soap/envelope/")

    class Envelope {
    @field:Element(name = "soap-env:Body", required = false)
    var body: Body? = null
    }

    @Root(name = "soap-env:Header", strict = false)
    class Header {

    }

    @Root(name = "soap-env:Body", strict = false)
    class Body {
    @field:Element(name = "prefixRigel0:authenticateCredentialResponse", required = false)
    @Namespace(prefix = "prefixRigel0", reference = "http://www....")
    var credResponse: CredentialResponse? = null
    }

    @Root(name = "prefixRigel0:authenticateCredentialResponse", strict = false)
    @Namespace(prefix = "prefixRigel0", reference = "http://www....")
    class CredentialResponse {
    @field:Element(name = "methodResult", required = false)
    var methodResponse: MethodResult? = null
    }


    @Root(name = "methodResult", strict = false)
    class MethodResult {
    @field:Element(name = "tokenCredential", required = false)
    var token: String? = null
    }

我已经阅读了Kotlin 1.2.21 + SimpleXml 2.3.0 - consume List error (must mark set get method)Parsing Soap Service use of Retrofit I am facing exception like this(i.e)mismatched body model in the class envelope model in the response之类的帖子

这是我的改造要求

val requestBodyText = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:v1=\"http://www....\">\n" +
            "   <soapenv:Header/>\n" +
            "   <soapenv:Body>\n" +
            "      <v1:authenticateCredential facade=\"login...\">\n" +
            "         <CB_AuthenticationData>\n" +
            "            <password>1111</password>\n" +
            "            <documento>\n" +
            "               <TIPO_DOCUM_PERSONA_CORP>N</TIPO_DOCUM_PERSONA_CORP>\n" +
            "               <CODIGO_DOCUM_PERSONA_CORP>1111H</CODIGO_DOCUM_PERSONA_CORP>\n" +
            "            </documento>\n" +
            "         </CB_AuthenticationData>\n" +
            "         <!--<userAddress>180...</userAddress>-->\n" +
            "      </v1:authenticateCredential>\n" +
            "   </soapenv:Body>\n" +
            "</soapenv:Envelope>"

    val requestBody = RequestBody.create(MediaType.parse("text/xml"), requestBodyText)

    val gson = GsonBuilder().setLenient().create()
    val retrofit = Retrofit.Builder().baseUrl("https://www...").addConverterFactory(SimpleXmlConverterFactory.create()).build()

    val api = retrofit.create(ServicesSoap::class.java!!)
    var call: Call<Envelope>? = null

    call = api.getToken(requestBody)
    if (call != null) {
        call!!.enqueue(object : Callback<Envelope> {
            override fun onResponse(call: Call<Envelope>, response: Response<Envelope>) {
                if (response.body() != null) {

                    Log.v("Retrofit call ", "response: " + response.isSuccessful() + " Message: " + response.message())
                    var v = response.body()
                }
            }

            override fun onFailure(call: Call<Envelope>, t: Throwable) {
                var v = "" + t.localizedMessage + " - " + t.message
            }
        })
    }
}

我的body = null时得到200 OK响应

enter image description here

编辑 我也尝试使用@get而不是@field但也无法正常工作 Retrofit2 + SimpleXML in Kotlin: MethodException: Annotation must mark a set or get method,并且更改为具有Parsing xml kotlin android中说明的参数的数据类,但也无法正常工作

我已经用这样的Java类尝试过了,但是也没用

 @Root(name = "soap-env:Envelope", strict = false)
@Namespace(prefix = "soap-env", reference = "http://schemas.xmlsoap.org/soap/envelope/")
public class Envelope {
    @Element(name = "soap-env:Body", required = false)
    Body body;
}


@Root(name = "soap-env:Header", strict = false)
class Header {

}

@Root(name = "soap-env:Body", strict = true)
class Body {
    @Element(name = "prefixRigel0:authenticateCredentialResponse", required = false)
    @Namespace(prefix = "prefixRigel0", reference = "http://www....")
    CredentialResponse credResponse;
}

@Root(name = "prefixRigel0:authenticateCredentialResponse", strict = true)
@Namespace(prefix = "prefixRigel0", reference = "http://www....")
class CredentialResponse {
    @Element(name = "methodResult", required = false)
    MethodResult methodResponse;
}



@Root(name = "methodResult", strict = true)
class MethodResult {
    @Element(name = "tokenCredential", required = false)
    String token;
}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

最后以这种方式在科特林工作了.....

    @Root(name = "soapenv:Envelope", strict = true)
@NamespaceList(Namespace(prefix = "soapenv", reference = "http://schemas.xmlsoap.org/soap/envelope/"), Namespace(prefix = "v1", reference = "http://www..."))
data class Envelope2(
        @field:Element(name = "Body", required = false)
        @param:Element(name = "Body", required = false)
        var body: Body2? = null,
        @field:Element(name = "Header", required = false)
        @param:Element(name = "Header", required = false)
        var header: Header2? = null
)


@Root(name = "soapenv:Header", strict = true)
class Header2 {

}

@Root(name = "soapenv:Body", strict = true)
data class Body2 constructor(
        @field:Element(name = "authenticateCredentialResponse", required = false)
        @Namespace(prefix = "v1", reference = "http://www...")
        var credResponse: CredentialResponse2? = null
)


@Root(name = "v1:authenticateCredentialResponse", strict = true)
@Namespace(prefix = "v1", reference = "http://www...")
data class CredentialResponse2 constructor(
        @field:Element(name = "methodResult", required = false)
        @param:Element(name = "methodResult", required = false)
        var methodResponse: MethodResult2? = null
)


@Root(name = "methodResult", strict = true)
data class MethodResult2 constructor(
        @field:Element(name = "cookieCredential", required = false)
        @param:Element(name = "cookieCredential", required = false)
        var cookie: String? = null,
        @field:Element(name = "tokenCredential", required = false)
        @param:Element(name = "tokenCredential", required = false)
        var token: String? = null
)