Android 2:如何将请求查询参数传递给响应?

Android 2:如何将请求查询参数传递给响应?,android,retrofit2,Android,Retrofit2,我正在为RESTAPI编写一个库。库必须尽可能地向用户隐藏API的内部复杂性 我依赖于配置为使用RxJava包装响应并使用GSon解析响应的Reformation2 我正在用它做休息服务 @GET("search") Observable<SearchResult> search(@Query("q") String query); @GET("search") Observable<SearchResult> search(@QueryMap Map<Strin

我正在为RESTAPI编写一个库。库必须尽可能地向用户隐藏API的内部复杂性

我依赖于配置为使用RxJava包装响应并使用GSon解析响应的Reformation2

我正在用它做休息服务

@GET("search")
Observable<SearchResult> search(@Query("q") String query);

@GET("search")
Observable<SearchResult> search(@QueryMap Map<String, String> params);

@GET("search")
Observable<SearchResult> searchNext(@Query("q") String query, @Query("startKey") String startKey);

@GET("search")
Observable<SearchResult> searchNext(@QueryMap Map<String, String> params, @Query("startKey") String startKey);
  • 结果的总计数
  • 用于检索下一批列表的键
  • 结果的实际数组
要获得下一批,必须使用相同的参数和返回的密钥再次调用服务

例如,假设搜索
q=foo
limit=20
:REST API将返回与字符串foo匹配的结果,这些字符串按段分批处理,每个结果20个。要获得下一批,我需要使用相同的两个参数创建另一个请求,
q=foo
limit=20
,添加
startKey=

我想/需要对库的用户隐藏这些内部机制

在我的库中,我初始化改造如下:

Retrofit retrofit = new Retrofit.Builder()
    .client(okHttpClient) // added interceptors
    .baseUrl(baseUrl) // my base url
    .addConverterFactory(GsonConverterFactory.create(gson)) // custom type adapter factory
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .build();
// obtain the service
MyService service = MyLibrarySDK.getService(context);
// perform the search operation
Observable<SearchResult> resultObservable =
    service.search(params); 
// then later result == the SearchResult
Observable<SearchResult> nextBatch =
    result.searchNext();
它为我的接口生成服务,并使用
Gson
解析用
RxJava
Observable
包装它的响应

然后我获得服务:

MyService service = retrofit.create(MyService.class)
请注意,我没有编写此服务的代码,因为改型可以使用我的界面(
MyService
)注释自动生成服务

从图书馆用户的角度来看,所有这些都是隐藏的,他将只接收服务并像这样使用它:

Retrofit retrofit = new Retrofit.Builder()
    .client(okHttpClient) // added interceptors
    .baseUrl(baseUrl) // my base url
    .addConverterFactory(GsonConverterFactory.create(gson)) // custom type adapter factory
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .build();
// obtain the service
MyService service = MyLibrarySDK.getService(context);
// perform the search operation
Observable<SearchResult> resultObservable =
    service.search(params); 
// then later result == the SearchResult
Observable<SearchResult> nextBatch =
    result.searchNext();
//获取服务
MyService service=MyLibrarySDK.getService(上下文);
//执行搜索操作
可观察到的结果=
服务搜索(params);
我希望使用我的库的开发人员能够获得下一批,如下所示:

Retrofit retrofit = new Retrofit.Builder()
    .client(okHttpClient) // added interceptors
    .baseUrl(baseUrl) // my base url
    .addConverterFactory(GsonConverterFactory.create(gson)) // custom type adapter factory
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .build();
// obtain the service
MyService service = MyLibrarySDK.getService(context);
// perform the search operation
Observable<SearchResult> resultObservable =
    service.search(params); 
// then later result == the SearchResult
Observable<SearchResult> nextBatch =
    result.searchNext();
//然后later result==搜索结果
可观测下一批次=
result.searchNext();
searchNext()
调用不接受任何参数。这意味着我在上一次调用中创建的
SearchResult
对象在使用方法
searchNext(映射参数,字符串键)
时应该在内部知道要使用哪些参数

如果用户使用
q=foo
执行搜索调用,则响应中不会收到此信息。我需要它

由于改型创建了服务,我不知道如何截获调用
service.search()
传递的方法参数

我必须解决的唯一想法是使用
OkHttp
拦截器,将查询参数映射放置在
ThreadLocal
中,然后使用自定义
Gson
TypeAdapter
将这些参数注入
SearchResult
对象

这个解决方案在技术上应该是可行的,但我认为它很难看。此外,拦截器将为RESTAPI的任何方法运行,但我只需要它用于搜索查询


你有更好的/有创意的/优雅的想法吗?

不要认为你应该在
结果上使用
searchNext()
,而应该在
服务上使用

请尝试以下操作:

MyService.java

public class MyService {
    RestClient.GitApiInterface service = RestClient.getClient();
    String query;
    Observable<GitResult> resultObservable;

    public Observable<GitResult> getUsersByName(String query) {
        this.query = query;
        resultObservable = service.getUsersByName(query, 0).cache();
        return resultObservable;
    }

    public Observable<GitResult> searchNext() {
        Observable nextResultObservable = resultObservable
                .flatMap(new Func1<GitResult, Observable<?>>() {
                    @Override
                    public Observable<?> call(GitResult gitResult) {
                        return service.getUsersByName(query, gitResult.getNextPage());
                    }
                });

        return nextResultObservable;
    }
} 
示例应用程序-

参考资料


您不是要从数据模型中获取查询参数吗?你在做这样的事情吗?@Krishnaraj我的问题写得不好吗?因为你问的让我觉得你不明白。如果你告诉我它在哪里,我可以改进这个问题confused@Krishnaraj无论如何,假设“数据模型”是指搜索的json响应:它只包含结果、总计数和获取下一批的键。因此,如果我需要获得下一批,我需要该键和第一次调用使用的所有参数。我想在客户端API中使其透明,因此我需要一种传递这些参数的方法。@Krishnaraj您认为我应该编辑我的问题以使其更清楚吗?我的建议是,如果您需要这种级别的自定义和对返回内容的控制,只需手动创建OkHttp调用,而不是使用改型。但是,如果您决心使用改型,那么您可以通过在
MyService
接口周围创建一个包装器,在结果模型中注入必要的数据,或者创建一个自定义
CallAdapter
,从它接收的
调用
参数解析
请求
,来实现您想要的功能,并基于它生成所需的结果对象(可能围绕
RxJavaCallAdapterFactory
实现)。为什么您认为拥有SearchResult.next()方法不好?SearchResult可能是一个模型类,将服务调用绑定到它似乎不是一个好主意。我认为拥有一个状态为的服务甚至是最糟糕的:)
MyService
只是实际服务的包装器-
RestClient.GitApiInterface服务
,你可以称它为其他东西:)它不是名字。这是该组件的作用。该方法的结果取决于您之前调用的另一个方法。这太错误了。