一招彻底解决retrofit中对单个接口请求属性进行设置的难题

   笔者学习retrofit已经有一段时间了,虽然retrofit的轻易上手,使用简单,但是有一个问题一直是笔者心中的困惑,就是如何优雅地对某个接口的请求单独地执行某些行为,例如修改超时时间,是否对参数加密等,因为诸如超时时间这些设置是在初始化httpClient的时候就已经设置好的,并且是全局且唯一的,为了解决这个问题笔者花了大量的时间搜索互联网寻求解决方案,得到的有以下几种:

   1.每次请求都生成新的retrofit。这种是极其恶劣的行为,因为这样会导致大量的内存浪费,这种方案一开始就被笔者抛弃了。

  2.给请求设置特定含义的header。使用okhttp的拦截器捕获这些特定含义的header,然后执行操作(添加特定含义header案例)。笔者尝试过使用这种方案去构建过框架,但是随着需要定制的配置越来越多,代码显得越来越臃肿,而且也不优雅,也被笔者抛弃了。

  3.修改retrofit源码,识别更多自定义的注解。(修改源码的案例)retrofit在网络框架中核心的工作就是根据注解动态代理的设计思想生成对应的okhttp的request。因此,如果我们可以通过修改retrofit中的源码,让retrofit识别我们的注解,进而改变最终生成的request,即可解决这个问题。但是,这就意味着,我们要彻底和github上开源的retrofit脱轨,这种侵入性极大的方案也被笔者抛弃了。

  那么,有没有一种非侵入性的,优雅的,简单的方案,可以达到配置单次请求的方案呢,是有的。

  实际上,在retrofit2.6之后,作者就在源码中,就对request的tag中加入了对接口注解的设置,如果我们在okhttp自定义拦截器中获取tag,就可以获得该接口的所有注解信息了

  使用案例:

@Target(METHOD)
@Retention(RUNTIME)
public @interface ConnectionTime {

    long connectionTime();

}

  这里笔者创建了一个自定义注解,作用是定义某个接口的超时时间(覆盖全局配置),然后在retrofit的某个接口中使用该注解:

public interface TestApi {

    @POST
    @Headers({ "Content-Type: application/json;charset=UTF-8"})
    @ConnectionTime(connectionTime = 5000)
    Observable<String> getResult(@Url String url, @QueryMap Map<String, String> params);

}

  这样该注解还没有发挥作用,我们自定义okhttp拦截器,在request的tag中获取该注解的值。

	@Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        LogUtil.d("超时时间"+request.tag(Invocation.class).method().getAnnotation(ConnectionTime.class).connectionTime());

  这样,我们就可以在自定义拦截器中截取到刚才定义的超时时间值了,然后重写request中的对应值,就可以达到只对该接口进行配置的目的。
  :这里笔者只是做个简单演示,实际上接口不一定会有这个注解,记得判空否则会导致空指针异常。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Retrofit是一个基于OkHttp的RESTful风格的网络请求框架,它可以将一个HTTP API转换为Java接口。在Retrofit,我们需要定义一个Java接口来描述HTTP API,然后通过Retrofit.create()方法来创建该接口的实例。下面是一个简单的示例: 假设我们有一个HTTP API,它的URL为https://example.com/api,请求方式为GET,请求参数为id和name,返回类型为JSON格式的字符串。那么我们可以定义一个Java接口来描述这个API: ```java public interface MyApi { @GET("/api") Call<String> getData(@Query("id") String id, @Query("name") String name); } ``` 在这个接口,我们使用了@GET注解来指定请求方式和URL,使用@Query注解来指定请求参数,使用Call<String>来指定返回类型。 接下来,我们可以使用Retrofit.create()方法来创建该接口的实例: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com") .build(); MyApi myApi = retrofit.create(MyApi.class); ``` 在这个示例,我们首先创建了一个Retrofit实例,并通过baseUrl()方法指定了API的基础URL。然后,我们调用create()方法来创建MyApi接口的实例。 最后,我们可以使用该实例来发起网络请求: ```java Call<String> call = myApi.getData("123", "test"); call.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { String data = response.body(); // 处理返回数据 } @Override public void onFailure(Call<String> call, Throwable t) { // 处理请求失败 } }); ``` 在这个示例,我们调用了MyApi接口的getData()方法来发起网络请求,并通过enqueue()方法来异步处理请求结果。在请求成功时,我们可以通过response.body()方法获取返回的数据,在请求失败时,我们可以在onFailure()方法处理请求失败的情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值