Retrofit 2-Dokumentation sagt:
Header, die zu jeder Anfrage hinzugefügt werden müssen, können mit einem OkHttp-Interceptor angegeben werden.
Das geht ganz einfach mit der Vorgängerversion, hier der zugehörigen QA.
Mit Retrofit 2 konnte ich jedoch nichts wie setRequestInterceptor
oder setInterceptor
-Methode finden, die auf Retrofit.Builder
-Objekt angewendet werden können.
Es scheint auch, dass es in OkHttp nicht mehr RequestInterceptor
gibt. Das Dokument von Retrofit weist uns auf Interceptor , dass ich es nicht richtig verstanden habe, wie ich es für diesen Zweck verwenden kann.
Wie kann ich das machen?
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("parameter", "value").build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(url).client(httpClient.build()).build();
Lambda-Version:
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
});
hässliche lange Version:
builder.addInterceptor(new Interceptor() {
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
}
});
Vollversion:
class Factory {
public static APIService create(Context context) {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(5, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addInterceptor(interceptor);
}
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
});
builder.addInterceptor(new UnauthorisedInterceptor(context));
OkHttpClient client = builder.build();
Retrofit retrofit =
new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
return retrofit.create(APIService.class);
}
}
gradle-Datei (Sie müssen den Protokollierungs-Interceptor hinzufügen, wenn Sie ihn verwenden möchten):
//----- Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile "com.squareup.retrofit2:converter-gson:2.1.0"
compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"
compile 'com.squareup.okhttp3:logging-interceptor:3.4.0'
Um Ihre Anfrage und Antwort zu protokollieren, benötigen Sie einen Interceptor und für das Setzen des Headers einen Interceptor. Hier ist die Lösung, um den Interceptor auf einmal mit Retrofit 2.1 hinzuzufügen
public OkHttpClient getHeader(final String authorizationValue ) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addNetworkInterceptor(
new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = null;
if (authorizationValue != null) {
Log.d("--Authorization-- ", authorizationValue);
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Authorization", authorizationValue);
request = requestBuilder.build();
}
return chain.proceed(request);
}
})
.build();
return okClient;
}
Fügen Sie nun in Ihrem Retrofit-Objekt diesen Header im Client hinzu
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(getHeader(authorizationValue))
.addConverterFactory(GsonConverterFactory.create())
.build();
Ich habe einen anderen Weg für Retrofit 1.9 und 2.0 (Json Content Type) gefunden.
@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);
Sie können viele weitere Header hinzufügen, d
@Headers({
"Accept: application/json",
"User-Agent: Your-App-Name",
"Cache-Control: max-age=640000"
})
In meinem Fall addInterceptor()
did nicht gearbeitet, um HTTP-Header zu meiner Anfrage hinzuzufügen, musste ich addNetworkInterceptor()
verwenden. Code lautet wie folgt:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addNetworkInterceptor(new AddHeaderInterceptor());
Und der Interceptor-Code:
public class AddHeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
builder.addHeader("Authorization", "MyauthHeaderContent");
return chain.proceed(builder.build());
}
}
Dies und noch mehr Beispiele zu diesem Gist
Wenn Sie die addInterceptor-Methode zum Hinzufügen von HttpLoggingInterceptor verwenden, werden nicht die Dinge protokolliert, die von anderen Interceptors hinzugefügt wurden, die später als HttpLoggingInterceptor hinzugefügt wurden.
Zum Beispiel: Wenn Sie zwei Interceptors "HttpLoggingInterceptor" und "AuthInterceptor" und HttpLoggingInterceptor zuerst angewendet haben, können Sie die von AuthInterceptor festgelegten http-params oder -Header nicht anzeigen.
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());
Ich habe es mit der Methode addNetworkInterceptor gelöst.
Verwenden Sie diesen Retrofit-Client
class RetrofitClient2(context: Context) : OkHttpClient() {
private var mContext:Context = context
private var retrofit: Retrofit? = null
val client: Retrofit?
get() {
val logging = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
val client = OkHttpClient.Builder()
.connectTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
.readTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
client.addInterceptor(logging)
client.interceptors().add(AddCookiesInterceptor(mContext))
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create()
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(Constants.URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client.build())
.build()
}
return retrofit
}
}
Ich übergebe die JWT mit jeder Anfrage. Bitte kümmern Sie sich nicht um die Variablennamen, es ist etwas verwirrend.
class AddCookiesInterceptor(context: Context) : Interceptor {
val mContext: Context = context
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder()
val preferences = CookieStore().getCookies(mContext)
if (preferences != null) {
for (cookie in preferences!!) {
builder.addHeader("Authorization", cookie)
}
}
return chain.proceed(builder.build())
}
}