3 votes

format du paramètre @Query - Retrofit 2

J'ai changé pour utiliser Retrofit2 et tout est beau et propre... Mais il y a un appel de service qui exige qu'un paramètre de requête soit à l'intérieur d'une expression régulière (ne me demandez pas pourquoi, j'ai déjà demandé qu'il soit modifié).

Voici à quoi ressemble ma méthode :

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

Si j'appelle searchProducts("lala") la requête sera la suivante : prod/search?q=lala mais j'ai besoin que ça ressemble à prod/search?q=(?i)\\Qlala\\E

Existe-t-il un moyen simple de formater le paramètre de requête pour faire cela ?

2voto

tynn Points 17673

Vous pourriez utiliser le typage statique à votre avantage. De la @Query documentation :

Les valeurs sont converties en chaînes de caractères en utilisant Retrofit.stringConverter(Type, Annotation[]) (ou Object.toString() (si aucun convertisseur de chaîne correspondant n'est installé) et ensuite codé en URL.

Il suffit de créer un simple wrapper de l'option String et de passer outre toString() :

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

Ensuite, utilisez RegularString comme paramètre de la requête :

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

1voto

Eduard Kornev Points 228

Réfléchissez, vous ne pouvez utiliser qu'une autre méthode. Quelque chose comme ça :

    searchProducts(prepareParameter("lala"))

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

Vous pouvez aussi utiliser Interceptor. Mais il serait appelé dans chaque requête, donc je vous recommande d'utiliser la première variante.

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

Et dans votre entreprise de rénovation :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X