Android Retrofit Parametrierte @Header

Lesezeit: 5 Minuten

Ich verwende OAuth und muss das OAuth-Token bei jeder Anfrage in meinen Header einfügen. ich sehe das @Header Anmerkung, aber gibt es eine Möglichkeit, sie zu parametrisieren, damit ich sie zur Laufzeit übergeben kann?

Hier ist das Konzept

@Header({Authorization:'OAuth {var}', api_version={var} })

Können Sie sie zur Laufzeit übergeben?

@GET("https://stackoverflow.com/users")
void getUsers(
    @Header("Authorization") String auth, 
    @Header("X-Api-Version") String version, 
    Callback<User> callback
)

  • Hast du das jemals herausgefunden? Ich muss auch ein Token im Header übergeben

    – das gesellige Ich

    11. September 2013 um 15:40 Uhr

  • Ich suche auch nach einer Lösung dafür, wie es sich aus der Dokumentation anhört @Kopfzeilen() Anmerkung zur Methode fügt Felder hinzu nacheinander zu überschreiben, unterstützt aber nur Literale. Und @Header(“Parameter”) Zeichenfolge Zeichenfolge Parameteranmerkung ersetzt den Header mit dem gelieferten Wert.

    – Nana

    12. September 2013 um 1:02 Uhr

  • Auch hier konnte ich nicht herausfinden, wie Sitzungen bei der Verwendung von Retrofit gehandhabt werden.

    – franklot

    27. Mai 2014 um 2:21 Uhr

  • Wir mussten nicht alle Artikel übergeben, sondern alle selbst nachrüsten. Bitte überprüfen Sie meinen Antwortlink in StackOverflow.

    – Subin Babu

    21. April 2018 um 7:07 Uhr

Benutzer-Avatar
Felix

Neben der Verwendung des @Header-Parameters würde ich lieber RequestInterceptor verwenden, um alle Ihre Anfragen zu aktualisieren, ohne Ihre Schnittstelle zu ändern. Verwenden Sie etwas wie:

RestAdapter.Builder builder = new RestAdapter.Builder()
    .setRequestInterceptor(new RequestInterceptor() {
        @Override
        public void intercept(RequestFacade request) {
            request.addHeader("Accept", "application/json;versions=1");
            if (isUserLoggedIn()) {
                request.addHeader("Authorization", getToken());
            }                    
        }
    });

p/s : Wenn Sie Retrofit2 verwenden, sollten Sie verwenden Interceptor Anstatt von RequestInterceptor

Seit RequestInterceptor ist in Retrofit 2.0 nicht mehr verfügbar

  • Dies steht nicht in direktem Zusammenhang, aber wenn Sie feststellen, dass Sie Werte aus dem Anforderungsobjekt abrufen müssen, um Ihren Autorisierungsheader zu generieren, müssen Sie ApacheClient erweitern und das Anforderungsobjekt duplizieren (List

    headers = … ; Request requestNew = new Request(request.getMethod(), request.getUrl(), headers, request.getBody()); request = requestNew).

    Benutzer153275

    7. Januar 2014 um 18:14 Uhr

  • Das ist ein Trick, der einen Code durcheinander bringt, verwenden Sie besser die Antwort von @nana

    – Ivan Fazaniuk

    23. März 2016 um 11:32 Uhr

  • RestAdapter hängt von Retrofit1 ab, in Retrofit2 schon Retrofit. Ich werde Retrofit2 verwenden, also keine Probleme bei der Verwendung RequestInterceptor wie oben Code?

    – Huy-Turm

    16. September 2016 um 9:12 Uhr


Benutzer-Avatar
nana

Ja, Sie können sie zur Laufzeit übergeben. Eigentlich ziemlich genau so, wie Sie es abgetippt haben. Dies wäre in Ihrer API-Schnittstellenklasse mit dem Namen sagen SecretApiInterface.java

public interface SecretApiInterface {

    @GET("/secret_things")
    SecretThing.List getSecretThings(@Header("Authorization") String token)

}

Dann übergeben Sie die Parameter von Ihrer Anfrage an diese Schnittstelle, etwa so: (Diese Datei wäre zum Beispiel SecretThingRequest.java)

public class SecretThingRequest extends RetrofitSpiceRequest<SecretThing.List, SecretApiInteface>{

    private String token;

    public SecretThingRequest(String token) {
        super(SecretThing.List.class, SecretApiInterface.class);
        this.token = token;
    }

    @Override
    public SecretThing.List loadDataFromNetwork() {
        SecretApiInterface service = getService();
        return service.getSecretThings(Somehow.Magically.getToken());
    }
}

Wo Somehow.Magically.getToken() ein Methodenaufruf ist, der ein Token zurückgibt, es liegt an Ihnen, wo und wie Sie es definieren.

Du kannst natürlich auch mehrere haben @Header("Blah") String blah Anmerkungen in der Schnittstellenimplementierung, wie in Ihrem Fall!

Ich fand es auch verwirrend, die Dokumentation sagt es ganz klar ersetzt die Überschrift, aber es NICHT!
Es wird tatsächlich wie mit hinzugefügt @Headers("hardcoded_string_of_liited_use") Anmerkung

Hoffe das hilft 😉

  • Ich habe in den Dokumenten festgestellt, dass ein vorhandener Header nicht ersetzt wird: “Beachten Sie, dass sich Header nicht gegenseitig überschreiben.” Prüfen square.github.io/retrofit und “Header-Manipulation”

    – Amio.io

    28. Juni 2014 um 7:41 Uhr


Die akzeptierte Antwort bezieht sich auf eine ältere Version von Retrofit. Für zukünftige Zuschauer die Möglichkeit, dies mit zu tun Retrofit 2.0 verwendet einen benutzerdefinierten OkHttp-Client:

OkHttpClient httpClient = new OkHttpClient.Builder()
  .addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
      Builder ongoing = chain.request().newBuilder();
      ongoing.addHeader("Accept", "application/json;versions=1");
      if (isUserLoggedIn()) {
        ongoing.addHeader("Authorization", getToken());
      }
      return chain.proceed(ongoing.build());
    }
  })
  .build();

Retrofit retrofit = new Retrofit.Builder()
  // ... extra config
  .client(httpClient)
  .build();

Hoffe es hilft jemandem. 🙂

  • Im allgemeinen Gebrauch mit dagger2 wird retrofit2 Singleton sein, daher wird httpclient nicht jedes Mal erstellt. in diesem Fall macht isUserLoggedIn() keinen Sinn, habe ich recht? Die einzige Lösung, die ich derzeit sehen kann, besteht darin, die Reinitialisierung von Retrofit2 zu erzwingen, wenn der Anmeldestatus des Benutzers geändert wird, sodass der entsprechende Header hinzugefügt oder aus der Anfrage entfernt wird. Oder gibt es eine offensichtliche Lösung, die ich derzeit nicht sehen kann? Vielen Dank.

    – bajicdusko

    7. Mai 2016 um 15:06 Uhr


  • @bajicdusko das ist genau mein Rätsel. Haben Sie eine Lösung gefunden? Es scheint so verschwenderisch und seltsam, dass die vorherige Version effizienter war.

    – Urkunde02392

    12. Juni 2016 um 20:11 Uhr

  • @deed02392 Sie können eine Zusammensetzung festlegen Interceptor auf die Sie den Interceptor später einstellen oder zurücksetzen können. Ich würde jedoch argumentieren, dass eine Nachrüstung als Singleton ein Zeichen für eine frühzeitige Optimierung sein kann. Beim Erstellen einer neuen Retrofit-Instanz entsteht kein Overhead: github.com/square/retrofit/blob/master/retrofit/src/main/java/…

    – Pablisko

    12. Juni 2016 um 20:48 Uhr

  • Ich habe nicht wirklich darüber nachgedacht. Ich habe eine ApiFactory-Klasse, die auch mit dagger2 initialisiert wird und für die Initialisierung der Nachrüstung verantwortlich ist. Ich habe eine öffentliche Methode in ApiFactory verfügbar gemacht, die bei Bedarf die Neuinitialisierung der Retrofit-Instanz erzwingt, also ist es ganz einfach. Ich mache es vielleicht falsch, aber es hat den Job gemacht, und ich verwende es nur für den Authorization-Header, also wird es beim Anmelden oder Abmelden des Benutzers verwendet. Eine andere Option ist die Verwendung der @Header-Annotation innerhalb der Endpunktdefinition, was für mich nicht akzeptabel war. Ich sollte es auf jedem Endpunkt einstellen, was nicht praktikabel ist.

    – bajicdusko

    12. Juni 2016 um 20:49 Uhr


  • @pablisco Ah, nach meinem Verständnis konntest du nichts hinzufügen oder entfernen Interceptors sobald Sie eine Retrofit2-Instanz erstellt haben.

    – Urkunde02392

    12. Juni 2016 um 21:11 Uhr

Nachrüstung 2.3.0

OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder
            .addInterceptor(new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    Request.Builder newRequest = request.newBuilder().header("Authorization", accessToken);
                    return chain.proceed(newRequest.build());
                }
            });

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(GithubService.BASE_URL)
            .client(okHttpClientBuilder.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

Ich verwende dies, um eine Verbindung zu GitHub herzustellen.

1245730cookie-checkAndroid Retrofit Parametrierte @Header

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy