Retrofit 基础

作者: zcwfeng | 来源:发表于2020-09-30 19:58 被阅读0次

Retrofit是什么

官网介绍是A type-safe HTTP client for Android and Java,是一个 RESTful 的 HTTP 网络请求框架的 封装,但网络请求不是Retrofit来完成的,它只是封装了请求参数、Header、Url、返回结果处理等信 息,而请求是由OkHttp3来完成的。

入门

  1. 导包
//网络请求相关 implementation
"com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion" implementation "com.squareup.retrofit2:retrofit-
mock:$rootProject.retrofitVersion"
implementation "com.squareup.retrofit2:converter-
gson:$rootProject.retrofitVersion"
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0' implementation "com.squareup.retrofit2:converter-
scalars:$rootProject.retrofitVersion"
implementation "com.squareup.retrofit2:adapter-
rxjava2:$rootProject.retrofitVersion"
implementation "com.squareup.retrofit2:converter-
gson:$rootProject.retrofitVersion"
  1. 定义一个HTTP API接口类
interface WanAndroidApi {
   @GET("project/tree/json")
    Call<ProjectBean> getProject();
}
  1. 使用Retrofit类生成WanAndroidApi 接口实现
Retrofit retrofit = new Retrofit.Builder()//建造者模式 .baseUrl("https://www.wanandroid.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
WanAndroidApi wanAndroidApi = retrofit.create(WanAndroidApi.class);//
代理实例
  1. 发送HTTP请求,返回Response可以同步或者异步处理
Call<ProjectBean> call = wanAndroidApi.getProject();//获取具体的某个业务 //同步请求
Response<ProjectBean> response = call.execute();
ProjectBean projectBean = response.body();
//异步请求
call.enqueue(new Callback<ProjectBean>() {
@Override
            public void onResponse(final Call<ProjectBean> call, final
Response<ProjectBean> response) {
Log.i("zcw","response: " + response.body()); }
@Override
            public void onFailure(final Call<ProjectBean> call, final
Throwable t) {}
});

注解分类解析

请求方法类

序号 名称 说明
1 GET get请求
2 POST post请求
3 PUT put请求
4 DELETE delete请求
5 PATCH patch请求,该请求是对put请求的补充,用于更新局部资源 head请求
6 HEAD head请求
7 OPTIONS option请求
8 HTTP 通用注解,可以替换以上所有的注解,其拥有method, path, hasBody 三 个属性

序号 1 ~ 7​

  • 分别对应 HTTP 的请求方法;
  • 接收一个字符串表示接口 path ,与 baseUrl 组成完整的 Url;
  • 可以不指定,结合 @Url 注解使用;
  • url 中可以使用变量,如 {id} ,并使用 @Path(“id”) 注解为 {id} 提供值。
@GET("project/tree/json")
 Call<ProjectBean> getProject1();

序号 8

  • 可用于替代以上 7 个,及其他扩展方法;
  • 有 3 个属性:method、path、hasBody、 举个例子
@HTTP(method="get",path="project/tree/json",hasBody=false)  
Call<ProjectBean> getProject2();

标记类

分类 名称 说明
表单请求 FormUrlEncoded 表示请求实体是一个Form表单,每个键值对需要使用@Field注解
请求参数 Multipart 表示请求实体是一个支持文件上传的Form表单,需要配合使用@Part,适用于 有文件 上传的场景
标记 Streaming 表示响应体的数据用流的方式返回,适用于返回的数据比较大, 该注解在在下载大文件的特别有用

FormUrlEncoded

登录页面使用: Content-Type:application/x-www-form-urlencoded

  • 用于修饰Field注解和FieldMap注解 使用该注解,表示请求正文将-
  • 使用表单网址编码。字段应该声明为参数,并用@Field注释或 FieldMap注释。使用FormUrlEncoded注解的请求将具”application/ x-www-form-urlencoded” MIME类型。字段名称和值将先进行UTF-8进行编码,再根据RFC-3986进行URI编码.

Multipart

上传文件使用: Content-Type:multipart/form-data

///////上传单张图片////// 
/**
* Multipart:表示请求实体是一个支持文件上传的Form表单,需要配合使用@Part,适用于 有文件 上传的场景
* Part:用于表单字段,Part和PartMap与Multipart注解结合使用,适合文件上传的情况
* PartMap:用于表单字段,默认接受的类型是Map<String,REquestBody>,可用于实现多 文件上传
* Part 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型;
*
* @param file 服务器指定的上传图片的key值 * @return
*/
@Multipart
@POST("project/upload")
Call<ProjectBean> upload1(@Part("file" + "\";filename=\"" + "test.png") RequestBody file);
@Multipart
@POST("project/xxx")
Call<ProjectBean> upload2(@Part MultipartBody.Part file);
////////请求/////////// 
//上传单个图片1
File file = new File("");
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"),file); wanAndroidApi.upload1(requestBody).execute(); //上传单个图片2
MultipartBody.Part imagePart = MultipartBody.Part.createFormData("上传的 key"
,file.getName(),requestBody); wanAndroidApi.upload2(imagePart)
.enqueue(new Callback<ProjectBean>() { @Override
                public void onResponse(Call<ProjectBean> call,
Response<ProjectBean> response) { }
t) { }
@Override
 public void onFailure(Call<ProjectBean> call, Throwable
});
///////上传多张图片//////
@Multipart
@POST("project/upload")
Call<ProjectBean> upload3(@PartMap Map<String, RequestBody> map);
@Multipart
@POST("project/xxx")
Call<ProjectBean> upload4(@PartMap Map<String, MultipartBody.Part> map);
////////使用//////////
//上传多张图片1
//图片集合
List<File> files = new ArrayList<>(); Map<String, RequestBody> map = new HashMap<>(); for (int i = 0; i < files.size(); i++) {
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), files.get(i));
map.put("file" + i + "\";filename=\"" + files.get(i).getName(), requestBody);
}
wanAndroidApi.upload3(map).execute();
//上传多张图片2
Map<String, MultipartBody.Part> map1 = new HashMap<>();
File file1 = new File("");
RequestBody requestBody1 = RequestBody.create(MediaType.parse("image/png"), file1); MultipartBody.Part part1 = MultipartBody.Part.createFormData("上传的key1", file1.getName(), requestBody1);
map1.put("上传的key1", part1);
File file2 = new File("");
RequestBody requestBody2 = RequestBody.create(MediaType.parse("image/png"), file2); MultipartBody.Part part2 = MultipartBody.Part.createFormData("上传的key2", file2.getName(), requestBody2);
map1.put("上传的key2", part2);
wanAndroidApi.upload4(map1).execute();
//////图文混传///// 
/**
* @param params
     * @param files
     * @return
     */
    @Multipart
    @POST("upload/upload")
    Call<ProjectBean> upload5(@FieldMap() Map<String, String> params,
                              @PartMap() Map<String, RequestBody> files);
/**
* Part 后面支持三种类型,{@link RequestBody}、{@link
okhttp3.MultipartBody.Part} 、任意类型; 
     * @param userName
     * @param passWord
     * @param file
     * @return
*/
    @Multipart
    @POST("project/xxx")
    Call<ProjectBean> upload6(@Part("username") RequestBody userName,
@Part("password") RequestBody passWord, @Part MultipartBody.Part file);
//////使用///////
MediaType textType = MediaType.parse("text/plain");
RequestBody name = RequestBody.create(textType, "zero"); RequestBody password = RequestBody.create(textType, "123456");
        File file = new File("");
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("上传的 key", file.getName(), requestBody);
wanAndroidApi
.upload6(name, password, part)
.enqueue(new Callback<ProjectBean>() { @Override
                    public void onResponse(Call<ProjectBean> call,
Response<ProjectBean> response) {
Throwable t) {
}
@Override
    public void onFailure(Call<ProjectBean> call,
} });

Streaming

未使用该注解,默认会把数据全部载入内存,之后通过流获取数据也是读取内存中数据,所以返回数据 较大时,需要使用该注解

/**
* 12.Streaming注解:表示响应体的数据用流的方式返回,适用于返回的数据比较大,该注解在
在下载大文件的特别有用
*/
    @Streaming
    @GET
    Call<ProjectBean> downloadFile(@Url String fileUrl);

参数类

分类 名称 说明
作用于方法 Headers 用于添加固定请求头,可以同时添加多个。通过该注解添加的请求 头不会相互覆盖,而是共同存在
作用于方 法参数(形 参) Header 作为方法的参数传入,用于添加不固定值的Header,该注解会更 新已有的请求头
请求参数 Body 多用于post请求发送非表单数据,比如想要以post方式传递json格 式数据
请求参数 Field 多用于post请求中表单字段,Filed和FieldMap需要 FormUrlEncoded结合使用
请求参数 FieldMap 表单字段,与 Field、FormUrlEncoded 配合;接受 Map< String,String>类型,非 String 类型会调用 toString() 方法
请求参数 Part 用于表单字段,Part和PartMap与Multipart注解结合使用,适合文件 上传的情况
请求参数 PartMap 表单字段,与 Part 配合,适合文件上传情况;默认接受 Map< String, RequestBody> 类型,非 RequestBody 会通过 Converter 转换
请求参数 HeaderMap 用于URL,添加请求头
请求参数 Path 用于url中的占位符
请求参数 Query 用于Get中指定参数
请求参数 QueryMap 和Query使用类似
请求参数 Url 指定请求路径

注意:

  • Map 用来组合复杂的参数;
  • Query、QueryMap 与 Field、FieldMap 功能一样,生成的数据形式一样; Query、QueryMap 的数据体现在 Url 上; Field、FieldMap 的数据是请求体;
  • {占位符}和 PATH 尽量只用在URL的 path 部分,url 中的参数使用 Query、QueryMap 代替,保 证接口的简洁;
  • Query、Field、Part 支持数组和实现了 Iterable 接口的类型, 如 List、Set等,方便向后台传递数组,示例如下:

Headers

使用 注解设置固定的请求头,所有请求头不会相互覆盖,即使名字相同。

@Headers("Cache-Control: max-age=640000") @GET("project/list")
Call<ProjectBean> getMsg1();
@Headers({ "Accept: application/vnd.github.v3.full+json","User-Agent: Retrofit-Sample-App"})
@GET("project/{username}")
Call<ProjectBean> getMsg2(@Path("username") String username);

Header

使用 @Header 注解动态更新请求头,匹配的参数必须提供给 @Header ,若参数值为 null ,这个头会 被省略,否则,会使用参数值的 toString 方法的返回值。

 @GET("project") 
Call<ProjectBean>getProject3(@Header("Authorization")Stringauthorization);

Body

使用 @Body 注解,指定一个对象作为 request body 。

@POST("project/new")
 Call<ProjectBean>createProject(@Body ProjectBean user);

Field

  • 作用于方法的参数
  • 用于发送一个表单请求
  • 用String.valueOf()把参数值转换为String,然后进行URL编码,当参数值为null值时,会自动忽略,如果 传入的是一个List或array,则为每一个非空的item拼接一个键值对,每一个键值对中的键是相同的,值 就是非空item的值,【如:name=张三&name=李四&name=王五】,另外,如果item的值有空格,在拼接时 会自动忽略,例如某个item的值为:张三,则拼接后为name=张三.
//固定或可变数组
@FormUrlEncoded
@POST("/list")
Call<ResponseBody> example(@Field("name") String... names);

FieldMap

  • 作用于方法的参数
  • 用于发送一个表单请求
  • map中每一项的键和值都不能为空,否则抛出IllegalArgumentException异常
FormUrlEncoded
@POST("/examples")
Call<ResponseBody> example(@FieldMap Map<String, String> fields);

Part

  • 作用于方法的参数,用于定义Multipart请求的每个part
  • 使用该注解定义的参数,参数值可以为空,为空时,则忽略
  • 使用该注解定义的参数类型有以下3种方式可选:
    • 如果类型是okhttp3.MultipartBody.Part,内容将被直接使用。省略part中的名称,即 @Part MultipartBody.Part part
    • 如果类型是RequestBody,那么该值将直接与其内容类型一起使用。在注释中提供part名称 (例如,@Part(“foo”)RequestBody foo)
    • 其他对象类型将通过使用转换器转换为适当的格式。 在注释中提供part名称(例如, @Part(“foo”)Image photo)

PartMap

  • 作用于方法的参数,以map的方式定义Multipart请求的每个part map中每一项的键和值都不能为空,否则抛出IllegalArgumentException异常
  • 使用该注解定义的参数类型有以下2种方式可选:
    • 如果类型是RequestBody,那么该值将直接与其内容类型一起使用
    • 其他对象类型将通过使用转换器转换为适当的格式
@Multipart
@POST("upload/upload")
Call<ProjectBean> upload5(@FieldMap() Map<String, String> params,
                              @PartMap() Map<String, RequestBody> files,
                              @Part("file") RequestBody file,
                              @PartMap Map<String,RequestBody> maps);

HeaderMap

  • 作用于方法的参数,用于添加请求头
  • 以map的方式添加多个请求头,map中的key为请求头的名称,value为请求头的值,且value使用 String.valueOf()统一转换为String类型
  • map中每一项的键和值都不能为空,否则抛出IllegalArgumentException异常
@GET("/example1")
Call<ProjectBean> example1(@HeaderMap Map<String, String> headers); /////使用///////
Map<String,String> headers = new HashMap<>(); headers.put("Accept","text/plain");
headers.put("Accept-Charset", "utf-8");
wanAndroidApi.example1(headers)
.enqueue(new Callback<ProjectBean>() {
@Override
                    public void onResponse(Call<ProjectBean> call,
Response<ProjectBean> response) { }
t) { }
@Override
    public void onFailure(Call<ProjectBean> call, Throwable
});

Path

请求 URL 可以替换模块来动态改变,替换模块是 {}包含的字母数字字符串,替换的参数必须使用 @Path 注解的相同字符串

@GET("example5/{id}")
 Call<ResponseBody>example5(@Path("id")intid);

Query

  • 作用于方法的参数
  • 用于添加查询参数,即请求参数
  • 参数值通过String.valueOf()转换为String并进行URL编码
  • 使用该注解定义的参数,参数值可以为空,为空时,忽略该值,当传入一个List或array时,为每个非空 item拼接请求键值对,所有的键是统一的,如:
    name=张三&name=李四&name=王五.
 @GET("release/news")
    Observable<NewsListBean> getNewsList(@Query("channelId") String channelId,
                                         @Query("channelName") String channelName,
                                         @Query("page") String page);

QueryMap

复杂的查询参数

@GET("example3/{id}")
Call<ResponseBody> example3(@Path("id") int id, @QueryMap Map<String,
String> options);

Url

  • 作用于方法参数
  • 用于添加请求的接口地址
@GET
Call<ResponseBody>example4(@UrlStringurl);

相关文章

  • Android Retrofit 2 + Retrofit 2

    实现MVC基础框架实现MVP基础框架(一)Android Retrofit 2 + Retrofit 2 封装(二...

  • 实习笔记2

    retrofit 参考 -- Retrofit + RxJava + OkHttp 让网络请求变的简单-基础篇[h...

  • Java Retrofit2使用--自定义转换器

    Java Retrofit2使用--自定义转换器 Retrofit2的基础使用请参考Java Retrofit2使...

  • Retrofit 基础

    Retrofit是什么 官网介绍是A type-safe HTTP client for Android and ...

  • Retrofit注解简介

    一.注解简介 Retrofit是square组织开发维护的一款网络框架,Retrofit是在okhttp基础之上进...

  • Retrofit网络请求参数注解

    1.Retrofit介绍 retrofit是在okhttp的基础上进行封装的,网络请求是通过okhttp实现的。 ...

  • Retrofit使用

    Retrofit与okhttp都是Square公司出品,retrofit就是在okhttp的基础上做了一层封装。网...

  • Retrofit 基础篇

    一、Retrofit 网络请求接口的注解类型:网络请求方法、标记类、网络请求参数 (1)网络请求方法 (2)标记类...

  • Retrofit 基础实现

    Retrofit, 其实是对okhttp一个封闭,它本身不做网络请求,只是生成请求的对象。 retrofit 扩展...

  • Retrofit基础用法

    在Android开发中,网络请求非常的常用而且重要。在Android网络请求库中,Retrofit是当下最热门的一...

网友评论

    本文标题:Retrofit 基础

    本文链接:https://www.haomeiwen.com/subject/tsxyuktx.html