使用RXJava和Retrofit获取头信息

21

我想将我的应用程序从目前使用的Retrofit转换为使用RX Java。 为了处理分页,我通常会从响应标头中获取nextPage URL。

@Override
    public void success(Assignment assignment, Response response) {
        response.getHeaders(); // Do stuff with header info
}

然而,自从我切换到RX Java后,我不确定如何从我的Retrofit调用中获取响应信息。

   @GET("/{item_id}/users")
    Observable<List<Objects>> getObjects(@Path("object_id") long object_id);

    @GET("/{next}")
    Observable<List<Objects>> getNextPageObjects(@Path("next") String nextURL);

是否有一种方法可以让我的Retrofit调用返回我的标题信息以及我的类型化对象?

2个回答

16

您可以使用

Observable<Response>

作为返回类型以获取响应细节

@GET("/{item_id}/users")
Observable<Response> getObjects(@Path("object_id") long object_id);

@GET("/{next}")
Observable<Response>getNextPageObjects(@Path("next") String nextURL);

这是 Response 对象的外观

enter image description here

然后您需要从可观察对象中解析头部和正文。

serviceClass.getNextPageObjects("next").flatMap(new Func1<Response, Observable<List<Objects>>() {
    @Override
    public Observable<AuthState> call(Response response) {
         List<Header> headers = response.getHeaders();
         GsonConverter converter = new GsonConverter(new Gson());
         // you would have to change this to convert the objects to list
         List<Objects> list = converter.fromBody(response.getBody(),
                            YourClass.class);

        return Observable.from(list);
    }

}

使用这种类型的可观察对象使得将两个zip调用在一起变得困难,至少从我所知道的来看是这样。还有其他方法吗? - Brandon
检查一下响应是否成功(isSuccessful())怎么样? - orium
2
Observable<Response<ResponseBody>> 这可以给你响应体和头信息。因此,如果你正在寻找带有头和体的完整响应,请使用它。 - Kidus Tekeste
对于Kotlin,您可以使用以下代码来读取头部信息:var mHeaders = it.headers() mHeaders.get("Server") - undefined

3
让我来翻译一下。从OkHttp-2.2开始,您可以拦截请求和响应。正如OkHttp Wiki所述,在使用OkUrlFactoryRetrofit中,拦截器将不起作用。您需要提供自己的Client实现,以在此自定义客户端和直接在OkHttp上执行Retrofit请求。不幸的是,这还没有发布(即将推出)。
public class ResponseHeaderInterceptor implements Interceptor {
  public interface ResponseHeaderListener{
     public void onHeadersIntercepted(Headers headers);
  }
  private ResponseHeaderListener mListener;
  public ResponseHeaderInterceptor(){};
  public ResponseHeaderInterceptor(ResponseHeaderListener listener){
     mListener = listener;
  }
  @Override public Response intercept(Chain chain) throws IOException {
    Response response = chain.proceed(chain.request());
    if(mListener != null){
       mListener.onHeadersIntercepted(response.headers());
     }
    return response;
  }

使用方法:

ResponseHeaderListener headerListener = new ResponseHeaderListener(){
 @Override
 public void onHeadersIntercepted(Headers headers){
     //do stuff with headers
 }
};
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.interceptors().add(new ResponseHeaderInterceptor(headerListener));
RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder();
restAdapterBuilder.setClient(new OkHttpClient22(okHttpClient));

这是应用拦截器,仅会被调用一次。

请注意,我通过逻辑完成了所有操作,但我仍然没有OkHttp-2.2。您可以在这里阅读相关信息。当2.2成为最新版本时,我将删除一些文本。

或者,您可以尝试创建自定义客户端,并使用一个接口提供响应:

public class InterceptableClient extends OkClient {
    private ResponseListener mListener;
    public interface ResponseListener{
        public void onResponseIntercepted(Response response);
    }
    public InterceptableClient(){};
    public InterceptableClient(ResponseListener listener){
        mListener = listener;
    }
    @Override
    public retrofit.client.Response execute(Request request) throws IOException {
        Response response =  super.execute(request);
        if(mListener != null) //runs on the executor you have provided for http execution
            mListener.onResponseIntercepted(response);
        return response;
    }
}

编辑: OkHttp 2.2已经 发布

意思是:OkHttp 2.2版本已经发布。

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