在 Kotlin 中通过改造操作复杂的 url?

Manipulating complex url with retrofit in Kotlin?

我想将我的 ArticleDataProvider with fuel 转换为 Retrofit,但我不知道如何操作 URL。

我有一个对象 Urls 来获取随机文章或搜索文章:

object Urls {

private const val BaseUrl = "https://en.wikipedia.org/w/api.php"

fun getSearchUrl(term: String, skip: Int, take: Int): String {
    return BaseUrl + "?action=query" +
            "&formatversion=2" +
            "&generator=prefixsearch" +
            "&gpssearch=$term" +
            "&gpslimit=$take" +
            "&gpsoffset=$skip" +
            "&prop=pageimages|info" +
            "&piprop=thumbnail|url" +
            "&pithumbsize=200" +
            "&pilimit=$take" +
            "&wbptterms=description" +
            "&format=json" +
            "&inprop=url"
}

fun getRandomUrl(take: Int): String {
    return BaseUrl + "?action=query" +
            "&format=json" +
            "&formatversion=2" +
            "&generator=random" +
            "&grnnamespace=0" +
            "&prop=pageimages|info" +
            "&grnlimit=$take" +
            "&inprop=url" +
            "&pithumbsize=200"
}

}

还有我的文章提供者:

class ArticleDataProvider {

init {
    FuelManager.instance.baseHeaders = mapOf("User-Agent" to "Pluralsight Wikipedia")
}


fun search(term: String, skip: Int, take: Int, responseHandler: (result: WikiResult) -> Unit?) {
    Urls.getSearchUrl(term, skip, take).httpGet()
        .responseObject(WikipediaDataDeserializer()) { _, response, result ->

            try {

                //do something with result
                if (response.statusCode == STATUS_CODE) {
                    val (data, _) = result
                    responseHandler.invoke(data as WikiResult)

                }
            } catch (e: HttpException) {


            }
        }
}

fun getRandom(take: Int, responseHandler: (result: WikiResult) -> Unit?) {
    Urls.getRandomUrl(take).httpGet()
        .responseObject(WikipediaDataDeserializer()) { _, response, result ->
            try {
                //do something with result
                if (response.statusCode == STATUS_CODE) {
                    val (data, _) = result
                    responseHandler.invoke(data as WikiResult)
                }
            } catch (e: HttpException) {
                //    Log.e("error", e.message)
            }
        }
}


class WikipediaDataDeserializer : ResponseDeserializable<WikiResult> {
    override fun deserialize(reader: Reader) = Gson().fromJson(reader, WikiResult::class.java)!!
}

}

这是我为 getRandom 请求改造的界面

private const val BaseUrl = "https://en.wikipedia.org/w/"

interface ArticleProvider {

  @GET("api.php?action=query&format=json&generator=random&prop=pageimages|info&grnlimit={take}&inprop=url&pithumbsize=200")
  fun getRandom (@Query("grnlimit") take: Int) : Call<WikiResult>

companion object{
    fun create() : ArticleProvider {
        val retrofit = Retrofit.Builder()
            .baseUrl(BaseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        return retrofit.create(ArticleProvider::class.java)
    }
}

}

我应该在我的 GET 中将所有值从 Urls 更改为 Query 或者我应该怎么做?

那么你可以把不需要改变的查询参数直接放到URL。然后,如果您有一些需要更改的参数,则将它们放在函数参数中,就像您已经放置的那样。您还可以将每个查询参数定义为具有默认值的函数参数,以便更好地记录请求。您可以将函数参数声明为可空类型,这样如果它设置为空,它就不会转到 URL。

这是您的代码中的一个小示例:

@GET("api.php")
fun getRandom(
        @Query("action") action: String? = "query",
        @Query("format") format: String? = "json",
        @Query("generator") generator: String? = "random",
        @Query("prop") prop: String? = "pageimages|info",
        @Query("grnlimit") grnlimit: Int? = 0, // This can be left without default value so it must be given always
        @Query("inprop") inprop: String? = "url",
        @Query("pithumbsize") pithumbsize: Int? = 200) : Call<WikiResult>

然后你可以用很多不同的方式调用它:

instanceToArticleProvider.getRandom() // Because every parameter has default values
instanceToArticleProvider.getRandom(grnlimit = 123) // You can use named params to change only one to URL
instanceToArticleProvider.getRandom("query", "json", "random", etc...)

下面是一个示例,如果您只需要更改一些参数并保留 URL 中的常量参数:

@GET("api.php?action=query&format=json&generator=random&inprop=url&pithumbsize=200")
fun getRandom(
        // This can be left without default value so it must be given always
        @Query("grnlimit") grnlimit: Int? = 0) : Call<WikiResult>