【问题标题】:format @Query parameter - Retrofit 2格式化@Query 参数 - 改造 2
【发布时间】:2017-09-27 11:34:27
【问题描述】:

我改用 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

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

【问题讨论】:

    标签: android kotlin retrofit2


    【解决方案1】:

    您可以使用静态类型来获得优势。来自@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>>
    

    【讨论】:

      【解决方案2】:

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

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

      您也可以使用拦截器。但它会在每个请求中调用,所以我建议你使用第一个变体。

      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()
      

      【讨论】:

      • 这就是我现在的解决方案。我只是想知道改造库中是否有我不知道的方法。我是改造新手。到目前为止,一直在为 REST Api 调用使用自定义解决方案。
      • @Mugur 更新答案,你也可以使用 inteceptor。但我认为,这是更糟糕的选择。
      猜你喜欢
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 2022-07-31
      • 2012-02-14
      相关资源
      最近更新 更多