如何使用 Retrofit2 获取邮政编码 JSON body 的地址列表

How to use Retrofit2 to GET list of addresses with the postcode JSON body

我是第一次使用 Retrofit2,所以我不知道如何进行。我有以下代码

fun getAddressFromPostCode(postCode: String): List<PXAddress>{

    val trimmedPostCode = postCode.replace("\s".toRegex(),"").trim()
    val dataBody = JSONObject("""{"postCode":"$trimmedPostCode"}""").toString()
    val hmac = HMAC()
    val hmacResult = hmac.sign(RequestConstants.CSSecretKey, dataBody)
    val body = JSONObject("""{"data":"$dataBody", "data_signature":"$hmacResult"}""").toString()
    val url = RequestConstants.getAddress

    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(url)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val address: PXAddress = retrofit.create(PXAddress::class.java)
}

考虑到 body 需要看起来像这样:

    "data":{
        "postcode": "WA1 1LD"
    },
    "data_signature": "{{getSignature}}"
}

响应应该是

    "success": 1,
    "addresses": [
        {
            "address1": "47 Museum Street",
            "address2": null,
            "address3": null,
            "town": "WARRINGTON",
            "county": "",
            "postcode": "WA1 1LD"
        },
        {
            "address1": "49a Museum Street",
            "address2": null,
            "address3": null,
            "town": "WARRINGTON",
            "county": "",
            "postcode": "WA1 1LD"
        },
        {
            "address1": "Leda Recruitment",
            "address2": "49 Museum Street",
            "address3": null,
            "town": "WARRINGTON",
            "county": "",
            "postcode": "WA1 1LD"
        }
    ]
}

我需要将该响应转换为 PXAddress 列表,即

open class PXAddress : RealmObject() {

    var addressLine1: String? = null
    var addressLine2: String? = null
    var addressLine3: String? = null
    var town: String? = null
    var county: String? = null
    var postcode: String? = null
}

由于某些原因,您的实施是错误的:

  1. 使用一个接口来定义web服务请求,你必须这样定义一个class:
    interface ApiService {
        @POST("your/webservice/path")
        fun getPXAddress(@Body dataBody: YourBodyModel): Call<List<PXAddress>>
    }
  1. 您必须使用数据 class 作为主体调用您的网络服务,gson 转换器将在 json 中转换您的模型,在您的主代码中您必须这样做:
fun getAddressFromPostCode(postCode: String): List<PXAddress>{
    val trimmedPostCode = postCode.replace("\s".toRegex(),"").trim()
    val dataBody = DataBodyObject(postCode = trimmedPostCode)

    val hmac = HMAC()
    val hmacResult = hmac.sign(RequestConstants.CSSecretKey, dataBody)

    val yourBodyModel = YourBodyModel(data = dataBody, data_signature = hmacResult)

    val url = RequestConstants.getUrl() // This address must be only the host, the path is specified in ApiService interface

    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(url)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val api: ApiService = retrofit.create(ApiService::class.java) // With this you create a instance of your apiservice

    val myCall: Call<List<PXAddress>> = api.getPXAddress(yourBodyModel) //with this you can call your service synchronous

}
  1. 最后一件事,您必须使用 rxjava、livedata 或协程调用异步模式的方法。他们都提供转换器进行改造。默认情况下,retrofit 有一个调用方法,就像我向您展示的示例一样,您可以这样做来完成您的代码:
    myCall.enqueue(object : Callback<List<PXAddress>> {
        override fun onFailure(call: Call<List<PXAddress>>?, t: Throwable?) {
            // Error response
        }

        override fun onResponse(call: Call<List<PXAddress>>?, response: Response<List<PXAddress>>?) {
            // Success response
            val myList : List<PXAddress> = response?.body
        }

    })

此致!