2017-03-21 4 views
1

Wie oben @Query Anmerkung in the Retrofit documentation erklärt:Ändern das Format der Liste/Array in URL [Retrofit 2]

eine Liste oder Array-Passing in einem Abfrageparameter für jeden Nicht-Null-Punkt führen wird.


Wie nun von meinem Ruf sieht ungefähr so ​​aus:

@GET("questions") 
Call<List<QuestionHolder>> getQuestionsExcludingTheSpecified(
     @Query("exclude_ids") long[] excludedQuestionIds 
); 

Dies funktioniert aber Ergebnisse in ziemlich langer URLs recht schnell.

z. Für excludedQuestionIds = new long[]{1L, 4L, 16L, 64L} ist die Anforderungs-URL bereits /questions?exclude_ids=1&exclude_ids=4&exclude_ids=16&exclude_ids=64.


Gibt es eine einfache Möglichkeit, dieses Verhalten in Arrays resultierenden auszutauschen formatiert als exclude_ids=[1,4,16,64] oder ähnliches?

Was mir in den Sinn kam, noch war, zu:

  • Verwendung JsonArray als Parameter, aber dann muss ich jedes Array/Liste konvertieren, bevor jeder Anfrage den Anruf
  • abfangen zu machen und komprimieren duplizierten Schlüssel
  • die integrierten in @Query Dekorateur außer Kraft setzen

Irgendwelche Ideen?

Antwort

0

Ich entschied mich für den Interceptor-Ansatz. Ich ändere einfach jede ausgehende Anfrage, die mehr als einen Wert für einen einzelnen Abfrageparameter enthält.

public class QueryParameterCompressionInterceptor implements Interceptor { 

    @Override 
    public Response intercept(Interceptor.Chain chain) throws IOException { 
     Request request = chain.request(); 

     HttpUrl url = request.url(); 
     for (String parameterName : url.queryParameterNames()) { 
      List<String> queryParameterValues = url.queryParameterValues(parameterName); 

      if (queryParameterValues.size() > 1) { 
       String formattedValues= "[" + TextUtils.join(",", queryParameterValues) + "]"; 

       request = request.newBuilder() 
         .url(
           url.newBuilder() 
             .removeAllQueryParameters(parameterName) 
             .addQueryParameter(parameterName, formattedValues) 
             .build() 
         ).build(); 
      } 
     } 

     return chain.proceed(request); 
    } 

nicht android Lösung

textutils ist Teil des Android SDK, Sie im Falle entwickelst nicht für Android Sie könnten TextUtils.join für eine Methode wie folgt auszutauschen:

Sie können sich auch this SO question für weitere Lösungen in Bezug auf die Verkettung ansehen.