format @Query参数 - Retrofit 2

时间:2017-09-27 11:34:28

标签: android kotlin retrofit2

我转而使用Retrofit2,一切都很干净...... 但是有一个服务调用要求查询参数在正则表达式中(不要问我为什么,我已经要求它被更改)。

以下是我的方法的样子:

@GET("prod/search")
fun searchProducts(@Query("q") q: String?): Call<Array<Product>>

如果我致电searchProducts("lala"),查询将如下:prod/search?q=lala,但我需要它看起来像prod/search?q=(?i)\\Qlala\\E

有没有一种简单的方法来格式化查询参数来做到这一点?

2 个答案:

答案 0 :(得分:2)

您可以使用静态类型来发挥自己的优势。从@Query文档中:

  

使用Retrofit.stringConverter(Type, Annotation[])(或Object.toString(),如果未安装匹配的字符串转换器)将值转换为字符串,然后进行URL编码。

您只需要创建一个String的简单包装并覆盖toString()

data class RegularString(val value: String) {
    override fun toString() = "(?i)\\\\Q$value\\\\E"
}

然后使用RegularString作为查询参数:

@GET("prod/search")
fun searchProducts(@Query("q") q: RegularString): Call<Array<Product>>

答案 1 :(得分:1)

想想,你只能使用另一种方法。像这样:

    searchProducts(prepareParameter("lala"))

    fun prepareParameter(query: String) = "(?i)\\\\Q" + query + "\\\\E"

你也可以使用Interceptor。但它会在每个请求中调用,因此我建议您使用第一个变体。

object : Interceptor {
            override fun intercept(chain: Interceptor.Chain?): Response {
                val original = chain!!.request()
                val originalUrl = original.url()
                if (originalUrl.encodedPath().contains("prod/search")) {
                    val value = originalUrl.queryParameter("q")
                    val newUrl = originalUrl.newBuilder()
                            .setQueryParameter("q", "(?i)\\\\Q$value\\\\E")
                            .build()

                    val request = original.newBuilder().url(newUrl).build()
                    return chain.proceed(request)
                }

                return chain.proceed(original) 
            }
        }

在您的改造建造者中:

val client = new OkHttpClient.Builder()
                 .addInteceptor(yourInterceptor)
                 .build()
val retrofit = Retrofit.Builder().client(client).build()