Skip to content

注解使用

liujingxing edited this page Feb 25, 2023 · 5 revisions

@DefaultDomain

该注解用于指定所有请求使用的默认域名,如下

public class Url {
    @DefaultDomain() //设置为默认域名
    public static String baseUrl = "https://www.wanandroid.com/";
}

此时发请求传入相对路径即可,如下:

RxHttp.get("/article/list/0/json")
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });

RxHttp在发送请求前,会对url做判断,如果没有域名,就会自动加上@DefaultDomain注解指定的默认域名

@Domain

该注解用于指定非默认域名,如下:

public class Url {
    @Domain(name = "Google") //设置非默认域名,name 可不传,不传默认为变量的名称
    public static String googleUrl = "https://www.google.com";

    @DefaultDomain() //设置为默认域名
    public static String baseUrl = "https://www.wanandroid.com/";
}

此时再rebuild一下项目,就会在RxHttp类中生成一个setDomainToGoogleIfAbsent()方法,其中的Google字符就是name指定的名字,然后发请求就可以这样:

RxHttp.get("/article/list/0/json")
    .setDomainToGoogleIfAbsent()
    .add("key", "value")
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });
    
//此时,完整的url为:https://www.google.com/article/list/0/json  

setDomainToGoogleIfAbsent方法内部会首先会判断我们传入的url有无域名,如果没有,就会加上我们指定的域名。

以上,可以看出,我们有3个种方式设置域名,第一种是传入的url直接带上域名;第二种使用@DefaultDomain注解指定默认的域名;第三种使用@Domain指定非默认域名,这三种优先级别如下: url带上域名 > @Domain > @DefaultDomain,其中@DefaultDomain注解优先级别最低。

注意,接下来要放大招了。。。。。

对于非默认域名,每次都要调用setDomainXxx方法才会生效,接口不多还好,多了,这种写法着实不太优雅,怎么办?

@Domain注解,其实还有一个className字段,通过指定该字段,可以生成一个RxHttp的包装类,使用该类发请求,就会默认使用@Domain注解指定的baseurl,而无需调用setDomainXxx方法,用法如下:

public class Url {
    @Domain(name = "Google"className = "Simple") 
    public static String googleUrl = "https://www.google.com";

    @DefaultDomain() //设置为默认域名
    public static String baseUrl = "https://www.wanandroid.com/";
}

此时Rebuild一下项目,就会生成一个RxSimpleHttp类,命名方法为:Rx+{className字段值}+Http,此时,我们通过RxSimpleHttp类发请求,就无需再指定非默认域名,如下:

RxSimpleHttp.get("/article/list/0/json")
    .add("key", "value")
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });

//此时,完整的url为:https://www.google.com/article/list/0/json    

扩展:动态域名

也许你已经注意到了,@DefaultDomain@Domain注解修饰的常量,并没有使用final关键字,这意味着我们可直接修改这些常量,以满足动态域名的需求,如下:

//动态更改默认域名,改完立即生效
Url.baseUrl = "https://www.baidu.com/"  
RxHttp.get("/article/list/0/json")
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });
    
//此时,完整的url为:https://www.baidu.com/article/list/0/json    

@OkClient

该注解,可以为某个请求指定单独的OkHttpClient对象,如下:

public class RxHttpManager {

    @OkClient(name = "BaiduClient")
    public static OkHttpClient baiduClient = new OkHttpClient.Builder().build();
}

此时Rebuild一下项目,就会在RxHttp类下生成setBaiduClient()方法,发请求时,调用该方法,就会使用@OkClient注解指定的OkHttpClient对象执行请求,如下:

RxHttp.get("/article/list/0/json")
    .setBaiduClient()
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });

以上代码,将使用指定的OkHttpClient对象执行请求,如未指定,将使用默认的OkHttpClient对象。

同样的,如果请求多了,这种写法着实不优雅,此时,也许你想起了@Domain注解的className字段,没错,@OkClient注解也有该字段,如下:

public class RxHttpManager {

    @OkClient(name = "BaiduClient"className = "Baidu")
    public static OkHttpClient baiduClient = new OkHttpClient.Builder().build();
}

此时Rebuild一下项目,就是生成RxBaiduHttp类,该类将默认使用@OkClient注解指定的OkHttpClient对象执行请求,通过该类发请求就无需指定OkHttpClient对象,如下:

RxBaiduHttp.get("/article/list/0/json")
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });

@Converter

该注解可以为某个请求指定单独的Converter,用于数据解析,如下:

public class RxHttpManager {

    @Converter(name = "FastJsonConverter")
    public static IConverter fastJsonConverter = FastJsonConverter.create();
}

此时Rebuild一下项目,就会在RxHttp类下生成setFastJsonConverter()方法,发请求时,调用该方法,就会使用FastJsonConverter解析数据,如下:

RxHttp.get("/article/list/0/json")
    .setFastJsonConverter()
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });

到这,或许你猜到了,该注解也有className字段,如下:

public class RxHttpManager {

    @Converter(name = "FastJsonConverter"className = "FastJson")
    public static IConverter fastJsonConverter = FastJsonConverter.create();
}

此时Rebuild一下项目,就是生成RxFastJsonHttp类,通过该类发请求,就会默认使用FastJsonConverter解析数据,如下:

RxFastJsonHttp.get("/article/list/0/json")
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });

Domain、OkClient、Converter注解的className字段

到这,我们知道,@Domain、@OkClient、@Converter注解,都可以指定className字段类生成对于的RxXxxHttp类,通过该类发请求,就会默认使用我们指定的域名、OkHttpClient及Converter,那么,试想一下,如果我们这三个注解,指定的className的名字都一样,会发生什么呢?如下:

public class RxHttpManager {

    @Domain(name = "Google"className = "Simple") 
    public static String googleUrl = "https://www.google.com";
    
    @OkClient(name = "BaiduClient"className = "Simple")
    public static OkHttpClient baiduClient = new OkHttpClient.Builder().build();
    
    @Converter(name = "FastJsonConverter"className = "Simple")
    public static IConverter fastJsonConverter = FastJsonConverter.create();
}

以上,className字段都取名为Simple,此时只会生成一个RxSimpleHttp类,该类默认使用的域名是googleUrl;默认的OkHttpClient对象为baiduClient;默认的Converter为FastJsonConverter,此时,使用RxSimpleHttp 发请求,如下:

RxSimpleHttp.get("/article/list/0/json")
    .toObservableString()  
    .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
       //成功回调
    }, throwable -> {
       //失败回调
    });

//请求url:https://www.google.com/article/list/0/json 
//使用BaiduClient执行请求
//使用FastJsonConverter解析数据

注:同一类型注解,className字段取名不能一样,否则编译不通过