Retrofit

[]Retrofit

Retrofit是一个HTTP网络请求框架的封装。Retrofit 2.0内置OkHttp,Retrofit用于接口的封装,OkHttp用于执行网络请求操作,

Retrofit请求网络,使用 Retrofit 接口层封装请求参数,Header,Url 等信息。然后由 OkHttp 完成后续的请求操作,在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析的过程。

先看一下官方案例

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();

GitHubService service = retrofit.create(GitHubService.class);

Call<List<Repo>> repos = service.listRepos("octocat");

[]Url 配置

Retrofit支持的协议有GET,POST,PUT,DELETE,HEAD,PATCH。还可以直接用HTTP来自定义请求。这些协议均以注解的形式进行配置。

请求的完整Url是通过baseUrl()的baseUrl参数和注解的value参数组合起来的。

具体的规则如下:

value是绝对路径的形式:
value = “/apath”,baseUrl = “http://host:port/a/b
Url = “http://host:port/apath

value是相对路径,baseUrl 是目录形式:
value = “apath”,baseUrl = “http://host:port/a/b/
Url = “http://host:port/a/b/apath

value是相对路径,baseUrl 是文件形式:
value = “apath”,baseUrl = “http://host:port/a/b
Url = “http://host:port/a/apath

value是完整的 Url:
value = “http://host:port/aa/apath“,baseUrl = “http://host:port/a/b
Url = “http://host:port/aa/apath

建议采用第二种方式来配置,并尽量使用同一种路径形式。

[]参数类型

()Path(用于URL替换)

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

()Query & QueryMap(用于GET请求)

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

如果有多个Query时,采用QueryMap 。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

()Body Body配置的对象(User)会转化为json,服务器获取参数时需要注意

@POST("users/new")
Call<User> createUser(@Body User user);

()Field & FieldMap(用于POST请求)

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

同样FieldMap用于有多个Field 。

()Part & PartMap(用于上传文件)

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

如果上传多个文件采用PartMap

()设置Headers

[]静态配置

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();

或者

@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);

[]动态配置

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

[]通过拦截器(Interceptor)设置Header

OkHttpClient client = new OkHttpClient.Builder()
    //错误是否重连
    .retryOnConnectionFailure(false)

    //设置超时,默认是10s
    .connectTimeout(15, TimeUnit.SECONDS)
    .readTimeout(20, TimeUnit.SECONDS)
    .writeTimeout(20, TimeUnit.SECONDS)

    .addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request()
                .newBuilder()
                .addHeader("Content-Type", "")
                .addHeader("Accept", "")
                .addHeader("Cookie", "you cookie")
                .build();

                return chain.proceed(request);
        }
    }).build();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .client(client)
    .build();

GitHubService service = retrofit.create(GitHubService.class);

[]Converter (必须要指定,不然请求不成功。可以指定多个)

()返回的结果为json,设置能自动解析成对象。

compile 'com.squareup.retrofit2:converter-gson:2.2.0'

//防止你需要调整json里面的一些格式,比如DateFormat。
Gson gson = new GsonBuilder()
    .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
    .create();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build();

GitHubService service = retrofit.create(GitHubService.class);

Square提供的官方Converter modules列表

Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars(primitives boxed and String):com.squareup.retrofit2:converter-scalars

()自定义Converter

1.自定义请求Converter(RequestBodyConverter)

假如上传图片时参数是File对象而不是RequestBody对象。

@Multipart
@PUT("user/photo")
Call<User> uploadImg(@Part("photo") File file);

public class UploadImgConverterFactory extends Converter.Factory {

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return new UploadImgRequestBodyConverter();
    }

    static class UploadImgRequestBodyConverter implements Converter<File, RequestBody> {

        @Override
        public RequestBody convert(File value) throws IOException {
            /**
             *上传文件
             */
            //RequestBody.create(MediaType.parse("application/otcet-stream"), value);

            /**
             *上传图片
             */
            return RequestBody.create(MediaType.parse("image/jpeg"), value);
        }
    }

}

2.自定义响应Converter(ResponseBodyConverter)

假如服务器返回的是字符串。

public class StringConverterFactory extends Converter.Factory {

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        return new StringResponseConverter();
    }

    static class StringResponseConverter implements Converter<ResponseBody, String> {

        @Override
        public String convert(ResponseBody value) throws IOException {
            return value.toString();
        }
    }

}

构造Retrofit时需要添加自定义Converter。

[]与RxJava配合使用

compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0'

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    //与RxJava配合
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .build();

MyService service = retrofit.create(MyService.class);

[]OKHttp其他设置

()离线缓存策略

File directory = new File(this.getExternalCacheDir(), "");
Cache cache = new Cache(directory, 1024 * 1024 * 50);

OkHttpClient client = new OkHttpClient.Builder()
    //开启缓存
    .cache(cache)
    .addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {

            Request request = chain.request();
            if (没有网络) {
                request.newBuilder()
                    //FORCE_NETWORK 只走网络
                    //FORCE_CACHE 只走缓存                                
                    //无网络时只从缓存中读取
                    .cacheControl(CacheControl.FORCE_CACHE)
                    .build();
            }

            Response response = chain.proceed(request);
                if (有网络) {
                    //设置缓存超时时间1个小时
                    int maxAge = 60 * 60;
                    response.newBuilder()
                        //清除头信息,因为服务器如果不支持,
                        //会返回一些干扰信息,不清除下面无法生效
                        .removeHeader("Pragma")
                        //设置缓存超时时间
                        .header("Cache-Control", "public, max-age=" + maxAge)
                        .build();
                } else {
                    //设置超时为4周
                    int maxStale = 60 * 60 * 24 * 28;
                    response.newBuilder()
                            .removeHeader("Pragma")
                            .header("Cache-Control", "ppublic, only-if-cached, max-stale=" + maxStale)
                            .build();
                }
            return response;
    }
}).build();

()公共参数

@Override
public Response intercept(Chain chain) throws IOException {

    Request originalRequest = chain.request();

    HttpUrl modifiedUrl =originalRequest.url()
                .newBuilder()
                .addQueryParameter("platform", "adnroid")
                .addQueryParameter("version", "1.2.0")
                .build();

    Request request =originalRequest.newBuilder()
                .url(modifiedUrl)
                .build();

                ......

            return chain.proceed(request);     
}

[]Mock Server

相关文章

Retrofit官网
http://square.github.io/retrofit/

Retrofit GitHub项目
https://github.com/square/retrofit

RxJava 与 Retrofit 结合的最佳实践
http://gank.io/post/56e80c2c677659311bed9841

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值