Retrofit中的阻塞请求拦截器?

4
有没有一种好的方式来实现“拦截”请求拦截器?
主要思想是所有请求都应该被拦截并添加额外的头部 - token
如果token不存在,则应首先检索它,然后将其添加到该请求中并缓存以供将来使用。通过API调用获取token
我尝试过同步请求,但这会产生android.os.NetworkOnMainThreadException。使用in_progress标志实现不太好看。
3个回答

2
您可以使用 RequestInterceptor 来完成“拦截”部分。只需使用 RestAdapter.Builder.setRequestInterceptor()即可。
然而,最好从API中获取令牌,而不是在RequestInterceptor中执行此操作。第一次调用后,在 RequestInterceptor.intercept() 中的任何位置都可以添加令牌。
类似于以下内容:
Builder builder = new RestAdapter.Builder()
//Set Endpoint URL, Retrofit class... etc
.setRequestInterceptor(new RequestInterceptor() {
       @Override
       public void intercept(RequestFacade request) {
           String authToken = getAuthToken(); //Not included here, retrieve the token.
           request.addHeader("Authorization", "Bearer " + authToken);
       }
);

是的,我正在寻找一种解决方案,以便除非获取了令牌,否则不会执行任何请求。而且似乎将此工作委托给拦截器是一个好主意。 - Martynas Jurkus
1
我在第一次请求(成功登录)后获得了我的令牌,我该如何获取并将其保存到变量中? - frankelot

1
从OkHTTP 2.2开始,您现在可以添加在网络线程上运行的拦截器:

https://github.com/square/okhttp/wiki/Interceptors

一个添加认证令牌的示例拦截器可能像这样;
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();

    // Get your auth token by going out over the network.. 

    // add authorization header, defaulting to the original request.
    Request authedRequest = request;
    if (!TextUtils.isEmpty(authToken)) {
        authedRequest = request.newBuilder().addHeader("Auth", authToken).build();
    }

    return chain.proceed(authedRequest);
}

1

你已经实现了“拦截”拦截器,但问题是Android不允许你在主线程中阻塞网络调用。

你应该将Retrofit调用包装在一个服务类中,该类异步调用你的getToken方法,并仅在第一个请求成功完成时才进行“主”请求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接