如何将拦截器添加到除一两个之外的所有 API 请求?
How to add interceptor to all API requests except one or two?
我知道可以通过 OkHttpClient
向所有请求添加拦截器,但我想知道是否可以向 Okhttp
中的所有请求添加 headers除了一个或两个使用 OkHttpClient
.
的请求
例如,在我的 API 中,除了 oauth/token
(获取令牌)和 api/users
(注册用户)路由。是否可以一步为使用 OkHttpClient
的所有请求添加拦截器,或者我应该为每个请求单独添加 headers 吗?
我找到答案了!
基本上我像往常一样需要一个拦截器,我需要检查那里的 URL 以了解我是否应该添加授权 header。
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by Omar on 4/17/2017.
*/
public class NetInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (request.url().encodedPath().equalsIgnoreCase("/oauth/token")
|| (request.url().encodedPath().equalsIgnoreCase("/api/v1/users") && request.method().equalsIgnoreCase("post"))) {
return chain.proceed(request);
}
Request newRequest = request.newBuilder()
.addHeader("Authorization", "Bearer token-here")
.build();
Response response = chain.proceed(newRequest);
return response;
}
}
@Omar 回答很好 :) 但我发现了一种使用自定义注释实现的更简洁的方法。
添加注释
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
private annotation class DECRYPTRESPONSE
在这样的拦截器中检查注释是真还是假
val method = chain.request().tag(Invocation::class.java)!!.method()
if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
//when annotion is present
} else..
改造界面添加注解
@DECRYPTRESPONSE
@GET
Call<ItemsModel> getListing(@Url String url);
下面是我的拦截器的完整代码也不要忘记在 Okhttpclient 构建器中添加拦截器
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
private annotation class DECRYPTRESPONSE
class DecryptInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response = chain
.run {
proceed(request())
}
.let { response ->
return@let if (response.isSuccessful) {
val body = response.body!!
val contentType = body.contentType()
val charset = contentType?.charset() ?: Charset.defaultCharset()
val buffer = body.source().apply { request(Long.MAX_VALUE) }.buffer()
val bodyContent = buffer.clone().readString(charset)
val method = chain.request().tag(Invocation::class.java)!!.method()
if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
response.newBuilder()
.body(ResponseBody.create(contentType, bodyContent.let(::decryptBody)))
.build()
}
else{
response.newBuilder()
.body(ResponseBody.create(contentType, bodyContent))
.build()
}
} else response
}
private fun decryptBody(content: String): String {
return content //your decryption code
}
}
我知道可以通过 OkHttpClient
向所有请求添加拦截器,但我想知道是否可以向 Okhttp
中的所有请求添加 headers除了一个或两个使用 OkHttpClient
.
例如,在我的 API 中,除了 oauth/token
(获取令牌)和 api/users
(注册用户)路由。是否可以一步为使用 OkHttpClient
的所有请求添加拦截器,或者我应该为每个请求单独添加 headers 吗?
我找到答案了!
基本上我像往常一样需要一个拦截器,我需要检查那里的 URL 以了解我是否应该添加授权 header。
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by Omar on 4/17/2017.
*/
public class NetInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (request.url().encodedPath().equalsIgnoreCase("/oauth/token")
|| (request.url().encodedPath().equalsIgnoreCase("/api/v1/users") && request.method().equalsIgnoreCase("post"))) {
return chain.proceed(request);
}
Request newRequest = request.newBuilder()
.addHeader("Authorization", "Bearer token-here")
.build();
Response response = chain.proceed(newRequest);
return response;
}
}
@Omar 回答很好 :) 但我发现了一种使用自定义注释实现的更简洁的方法。
添加注释
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
private annotation class DECRYPTRESPONSE
在这样的拦截器中检查注释是真还是假
val method = chain.request().tag(Invocation::class.java)!!.method()
if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
//when annotion is present
} else..
改造界面添加注解
@DECRYPTRESPONSE
@GET
Call<ItemsModel> getListing(@Url String url);
下面是我的拦截器的完整代码也不要忘记在 Okhttpclient 构建器中添加拦截器
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
private annotation class DECRYPTRESPONSE
class DecryptInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response = chain
.run {
proceed(request())
}
.let { response ->
return@let if (response.isSuccessful) {
val body = response.body!!
val contentType = body.contentType()
val charset = contentType?.charset() ?: Charset.defaultCharset()
val buffer = body.source().apply { request(Long.MAX_VALUE) }.buffer()
val bodyContent = buffer.clone().readString(charset)
val method = chain.request().tag(Invocation::class.java)!!.method()
if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
response.newBuilder()
.body(ResponseBody.create(contentType, bodyContent.let(::decryptBody)))
.build()
}
else{
response.newBuilder()
.body(ResponseBody.create(contentType, bodyContent))
.build()
}
} else response
}
private fun decryptBody(content: String): String {
return content //your decryption code
}
}