wake-up-neo.com

Gibt es eine Möglichkeit, mit Retrofit 2 jeder Anforderung Abfrageparameter hinzuzufügen?

Ich muss zu jeder Anfrage der Retrofit 2.0.0-beta2-Bibliothek einen Abfrageparameter hinzufügen. Ich habe diese Lösung für Retrofit 1.9 gefunden, aber wie füge ich RequestInterceptor in der neuesten Bibliotheksversion hinzu?

Meine Schnittstelle:

@GET("user/{id}")
Call<User> getUser(@Path("id")long id);

@GET("users/")
Call<List<User>> getUser();

Klient:

Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(CLIENT)  // custom OkHTTP Client
                    .build();
service = retrofit.create(userService.class);
48
Max

Der Vollständigkeit halber ist hier der vollständige Code, den Sie benötigen, um zu jeder Retrofit 2.x-Anforderung einen Parameter mit einem OkHttp-Interceptor hinzuzufügen:

OkHttpClient client = new OkHttpClient();

client.interceptors().add(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        HttpUrl url = request.url().newBuilder().addQueryParameter("name","value").build();
        request = request.newBuilder().url(url).build();
        return chain.proceed(request);
    }
});

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("...")
        .client(client)
        .build();
94
lukle

das Retrofit hat jetzt das Release 2.0.0 und dies ist meine Lösung:

OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {

                String uid = "0";
                long timestamp = (int) (Calendar.getInstance().getTimeInMillis() / 1000);
                String signature = MD5Util.crypt(timestamp + "" + uid + MD5_SIGN);
                String base64encode = signature + ":" + timestamp + ":" + uid;
                base64encode = Base64.encodeToString(base64encode.getBytes(), Base64.NO_WRAP | Base64.URL_SAFE);

                Request request = chain.request();
                HttpUrl url = request.url()
                        .newBuilder()
                        .addQueryParameter("pageSize", "2")
                        .addQueryParameter("method", "getAliasList")
                        .build();

                request = request
                        .newBuilder()
                        .addHeader("Authorization", "zui " + base64encode)
                        .addHeader("from_client", "ZuiDeer")
                        .url(url)
                        .build();

                Response response = chain.proceed(request);
                return response;
            }
        }).build();


Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(ApiConstants.API_BASE_URL)
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();

mRestfulService = retrofit.create(RestfulService.class);
7
zenghui.wang

Sie müssen zu Interceptor von OkHttp wechseln. Erstellen Sie ein OkHttpClient, fügen Sie das Interceptor hinzu und übergeben Sie diesen Client im Retrofit Builder.

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        ...
    }
});

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("...")
        .client(client)
        .build();

Sie können die Anfrage dann mit chain.request().newBuilder() an Ihre Bedürfnisse anpassen. Einzelheiten finden Sie in der Dokumentation documentation .

4
sebastian

In 3.2.0 und höher sollten Sie stattdessen addInterceptor() in OkHttpClient.Builder verwenden.

Zum Beispiel mit Retrolambda :

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor()
        .setLevel(HttpLoggingInterceptor.Level.BASIC);

Interceptor clientInterceptor = chain -> {
    Request request = chain.request();
    HttpUrl url = request.url().newBuilder().addQueryParameter("name", "value").build();
    request = request.newBuilder().url(url).build();
    return chain.proceed(request);
};

OkHttpClient client = new OkHttpClient.Builder()
        .addNetworkInterceptor(clientInterceptor)
        .addInterceptor(loggingInterceptor)
        .build();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();
3
Sergey Nikitin

Viele dieser Antworten sind ähnlich, aber ein Problem, das ich angesprochen habe, ist die Verkettung von Funktionen in Interceptor, was dazu führte, dass es für mich fehlschlug. Änderungen können nicht direkt an einer URL entsprechend dem verknüpften Video vorgenommen werden. Stattdessen muss eine Kopie der URL erstellt und anschließend wieder der ursprünglichen URL zugewiesen werden, wie unten gezeigt:

{

public method(){
    final String api_key = "key";

    OkHttpClient client = new OkHttpClient.Builder()
                          .addInterceptor(new Interceptor() {
                              @Override
                              public Response intercept(Chain chain) throws IOException {
                                    Request original = chain.request();
                                    HttpUrl httpUrl = original.url();

                                    HttpUrl newHttpUrl = httpUrl
                                                        .newBuilder()
                                                        .addQueryParameter("api_key", api_key)
                                                        .build();

                                    Request.Builder requestBuilder = original
                                                                 .newBuilder()
                                                             .url(newHttpUrl);

                                    Request request = requestBuilder
                                                      .build();
                                    return chain.proceed(request);
                              }
                          }).build();


    retrofit = new Retrofit.Builder()
            .baseUrl("https://base.url.ext/")
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}

Während die aufgerufenen Funktionen mit der ersten Antwort identisch sind, teilt diese Antwort die Funktion auf. Die ursprüngliche URL sowie die neue URL werden in separaten lokalen Variablen gespeichert. Dadurch wird verhindert, dass die ursprüngliche URL überschrieben wird, bis OkHttpClient dies wünscht. 

0
isakbob