当前位置:   article > 正文

Retrofit基础讲解(上)_call

call

一.简介

Retrofit是Square 公司开发的一款正对Android 网络请求的框架。底层基于OkHttp 实现。

Retrofit官网地址:Retrofit

RetrofitGItHub地址GitHub - square/retrofit: A type-safe HTTP client for Android and the JVM

二.注解详解

Retrofit的一大特点就是注解,下面讲解常用的注解

1.和请求方法相关的注解

<1> get

  1. @GET("openapi.dokeyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue")
  2. Call<ResponseBody> getFanYiData();

<2> post

  1. @FormUrlEncoded
  2. @POST("openapi.do")
  3. Call<ResponseBody> login(@Field("keyfrom") String param1, @Field("key") String params2, @Field("type") String param3, @Field("doctype") String param4, @Field("version") String param5, @Field("q") String param6);

<3> head

<4> put

<5> delete

<6> patch

2.和参数相关的注解

<1> Path

用于替换请求地址,作用于方法参数。

  1. @GET("{public}")
  2. Call<BaseResult<List<User>>> getUser(@Path("public") String path);

<2> Field

用于表单字段参数,(需要配合FormUrlEncoded使用)作用于方法参数。

  1. @FormUrlEncoded
  2. @POST("public")
  3. Call<BaseResult> addUser(@Field("userName") String userName);

<3> Multipart

指请求体是一个支持文件上传的Form表单,Content-Type=multipart/form-data,需要和参数类注解@Part,@PartMap搭配使用。

  1. @Multipart
  2. @POST("public")
  3. Call<BaseResult> uploadFile(@Part MultipartBody.Part file);
  4. @Multipart
  5. @POST("users/image")
  6. Call<BaseResponse<String>> uploadFilesWithParts(@Part() List<MultipartBody.Part> parts);
  7. @POST("users/image")
  8. Call<BaseResponse<String>> uploadFileWithRequestBody(@Body MultipartBody multipartBody);

注意:

使用@Multipart注解方法,并用@Part注解方法参数,类型是List< okhttp3.MultipartBody.Part>。
不使用@Multipart注解方法,直接使用@Body注解方法参数,类型是okhttp3.MultipartBody。

<4> FormUrlEncoded

指请求体是一个Form表单,Content-Type=application/x-www-form-urlencoded,需要和参数类注解@Field,@FieldMap搭配使用。

  1. @FormUrlEncoded
  2. @POST("login")
  3. Flowable<HttpResult<UserInfoData>> login(@FieldMap Map<String, String> map);
  4. @FormUrlEncoded
  5. @POST("public")
  6. Call<BaseResult> addUser(@Field("userName") String userName);

<5> Streaming

指响应体的数据以流的形式返回,如果不使用默认会把数据全部加载到内存,所以下载文件时需要加上这个注解。

  1. @Streaming
  2. @GET("download")
  3. Call<ResponseBody> downloadFile();

<6> FieldMap

用于表单字段参数,接收Map实现多个参数,(需要配合FormUrlEncoded使用)作用于方法参数。

  1. @FormUrlEncoded
  2. @POST("public")
  3. Call<BaseResult> addUser(@FieldMap Map<String,String> fieldMap);

<7> Part

用于表单字段参数,适用于文件上传,(需要配合Multipart使用)作用于方法参数。

  1. @Multipart
  2. @POST("public")
  3. Call<BaseResult> uploadFile(@Part MultipartBody.Part file);

<8> PartMap

用于表单字段参数,适用于文件上传,(需要配合Multipart使用)作用于方法参数。

  1. @Multipart
  2. @POST("public")
  3. Call<BaseResult> uploadFile(@PartMap Map<String,RequestBody> RequestBodyMap);

<9> Query

用于条件字段参数,作用于方法参数(主要在GET中使用)。

  1. @GET("public")
  2. Call<BaseResult<List<User>>> getUser(@Query("userId") String userId);

<10> QueryMap

用于条件字段参数,作用于方法参数(主要在GET中使用)。

  1. @GET("public")
  2. Call<BaseResult<List<User>>> getUser(@QueryMap Map<String,String> map);

<11> Body

作用于方法参数。

  1. @POST("public")
  2. Call<BaseResult<List<User>>> getUser(@Body( User user);

注意:

<1> 使用Post请求方式

(1) 表单提交:建议使用Field或FieldMap+FormUrlEncoded,以键值对上传到服务器。

(2) JSON提交:建议使用@Body,大部分都是实体类,最后将实体类转换为JSON,上传服务器。



<2> 使用GET请求方式

(1) 建议使用Query或QueryMap都是将参数拼接在url后面的。

三.代码实现

1.Gradle依赖

implementation 'com.squareup.retrofit2:retrofit:2.7.0'

2.接口

  1. package com.wjn.rxdemo.retrofit.only;
  2. import java.util.Map;
  3. import okhttp3.ResponseBody;
  4. import retrofit2.Call;
  5. import retrofit2.http.Field;
  6. import retrofit2.http.FieldMap;
  7. import retrofit2.http.FormUrlEncoded;
  8. import retrofit2.http.GET;
  9. import retrofit2.http.POST;
  10. /**
  11. * 翻译接口
  12. */
  13. public interface FanYiService {
  14. /**
  15. * 翻译模块Get请求
  16. */
  17. @GET("openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue")
  18. Call<ResponseBody> getFanYiByGet();
  19. /**
  20. * 翻译模块Post请求 Field方式 单个参数逐一传参
  21. */
  22. @FormUrlEncoded
  23. @POST("openapi.do")
  24. Call<ResponseBody> getFanYiByPost(@Field("keyfrom") String param1, @Field("key") String params2, @Field("type") String param3, @Field("doctype") String param4, @Field("version") String param5, @Field("q") String param6);
  25. /**
  26. * 翻译模块Post请求 FieldMap 集合传参
  27. */
  28. @FormUrlEncoded
  29. @POST("openapi.do")
  30. Call<ResponseBody> getFanYiByPost(@FieldMap Map<String, String> map);
  31. }

3.测试页面

  1. package com.wjn.networkdemo.retrofit.only;
  2. import android.os.Bundle;
  3. import android.util.Log;
  4. import android.view.View;
  5. import androidx.appcompat.app.AppCompatActivity;
  6. import com.wjn.networkdemo.R;
  7. import java.io.IOException;
  8. import java.util.HashMap;
  9. import okhttp3.HttpUrl;
  10. import okhttp3.Request;
  11. import okhttp3.ResponseBody;
  12. import retrofit2.Call;
  13. import retrofit2.Callback;
  14. import retrofit2.Response;
  15. import retrofit2.Retrofit;
  16. public class RetrofitActivity extends AppCompatActivity {
  17. private Retrofit mRetrofit;
  18. private FanYiService mFanYiService;
  19. private String mBaseUrl = "http://fanyi.youdao.com/";
  20. @Override
  21. protected void onCreate(Bundle savedInstanceState) {
  22. super.onCreate(savedInstanceState);
  23. setContentView(R.layout.activity_retrofit);
  24. //获取Retrofit对象
  25. mRetrofit = new Retrofit.Builder()
  26. .baseUrl(mBaseUrl)//设置BaseUrl 必须以'/'结尾
  27. .build();
  28. //Get请求
  29. findViewById(R.id.activity_retrofit_textview1).setOnClickListener(new View.OnClickListener() {
  30. @Override
  31. public void onClick(View v) {
  32. getData();
  33. }
  34. });
  35. //Post请求 单一参数
  36. findViewById(R.id.activity_retrofit_textview2).setOnClickListener(new View.OnClickListener() {
  37. @Override
  38. public void onClick(View v) {
  39. postData();
  40. }
  41. });
  42. //Post请求 集合参数
  43. findViewById(R.id.activity_retrofit_textview3).setOnClickListener(new View.OnClickListener() {
  44. @Override
  45. public void onClick(View v) {
  46. postMapData();
  47. }
  48. });
  49. }
  50. /**
  51. * Retrofit Get请求
  52. */
  53. private void getData() {
  54. if (null != mRetrofit) {
  55. mFanYiService = mRetrofit.create(FanYiService.class);
  56. Call<ResponseBody> getCall = mFanYiService.getFanYiByGet();
  57. getCall.enqueue(new Callback<ResponseBody>() {
  58. @Override
  59. public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
  60. if (null == call || null == response) return;
  61. //参数call信息打印
  62. boolean canceled = call.isCanceled();
  63. Request request = call.request();
  64. HttpUrl url = request.url();
  65. String method = request.method();
  66. Log.d("RetrofitActivity", "Get请求onResponse方法canceled----:" + canceled);
  67. Log.d("RetrofitActivity", "Get请求onResponse方法url.toString()----:" + url.toString());
  68. Log.d("RetrofitActivity", "Get请求onResponse方法method----:" + method);
  69. //参数response信息打印
  70. String result = null;//报文 获取报文必须判断响应是否成功
  71. if (response.isSuccessful()) {
  72. try {
  73. result = response.body().string();
  74. } catch (IOException e) {
  75. e.printStackTrace();
  76. }
  77. String msg = response.toString();
  78. int code = response.code();
  79. boolean isSuccess = response.isSuccessful();
  80. Log.d("RetrofitActivity", "Get请求onResponse方法result----:" + result);
  81. Log.d("RetrofitActivity", "Get请求onResponse方法msg----:" + msg);
  82. Log.d("RetrofitActivity", "Get请求onResponse方法code----:" + code);
  83. Log.d("RetrofitActivity", "Get请求onResponse方法isSuccess----:" + isSuccess);
  84. } else {
  85. Log.d("RetrofitActivity", "Get请求onResponse方法isSuccess----:" + false);
  86. }
  87. }
  88. @Override
  89. public void onFailure(Call<ResponseBody> call, Throwable t) {
  90. Log.d("RetrofitActivity", "Get请求onFailure方法result2----:" + t.getMessage());
  91. }
  92. });
  93. }
  94. }
  95. /**
  96. * Retrofit Post请求 单一参数
  97. */
  98. private void postData() {
  99. if (null != mRetrofit) {
  100. mFanYiService = mRetrofit.create(FanYiService.class);
  101. Call<ResponseBody> postCall = mFanYiService.getFanYiByPost("imoocdict123456", "324273592", "data", "json", "1.1", "red");
  102. postCall.enqueue(new Callback<ResponseBody>() {
  103. @Override
  104. public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
  105. if (null == call || null == response) return;
  106. //参数call信息打印
  107. boolean canceled = call.isCanceled();
  108. Request request = call.request();
  109. HttpUrl url = request.url();
  110. String method = request.method();
  111. Log.d("RetrofitActivity", "Post请求onResponse方法canceled----:" + canceled);
  112. Log.d("RetrofitActivity", "Post请求onResponse方法url.toString()----:" + url.toString());
  113. Log.d("RetrofitActivity", "Post请求onResponse方法method----:" + method);
  114. //参数response信息打印
  115. String result = null;//报文 获取报文必须判断响应是否成功
  116. if (response.isSuccessful()) {
  117. try {
  118. result = response.body().string();
  119. } catch (IOException e) {
  120. e.printStackTrace();
  121. }
  122. String msg = response.toString();
  123. int code = response.code();
  124. boolean isSuccess = response.isSuccessful();
  125. Log.d("RetrofitActivity", "Post请求onResponse方法result----:" + result);
  126. Log.d("RetrofitActivity", "Post请求onResponse方法msg----:" + msg);
  127. Log.d("RetrofitActivity", "Post请求onResponse方法code----:" + code);
  128. Log.d("RetrofitActivity", "Post请求onResponse方法isSuccess----:" + isSuccess);
  129. } else {
  130. Log.d("RetrofitActivity", "Post请求onResponse方法isSuccess----:" + false);
  131. }
  132. }
  133. @Override
  134. public void onFailure(Call<ResponseBody> call, Throwable t) {
  135. Log.d("RetrofitActivity", "Post请求onFailure方法result2----:" + t.getMessage());
  136. }
  137. });
  138. }
  139. }
  140. /**
  141. * Retrofit Post请求 集合参数
  142. */
  143. private void postMapData() {
  144. if (null != mRetrofit) {
  145. mFanYiService = mRetrofit.create(FanYiService.class);
  146. HashMap<String, String> map = new HashMap<>();
  147. map.put("keyfrom", "imoocdict123456");
  148. map.put("key", "324273592");
  149. map.put("type", "data");
  150. map.put("doctype", "json");
  151. map.put("version", "1.1");
  152. map.put("q", "red");
  153. Call<ResponseBody> postCall = mFanYiService.getFanYiByPost(map);
  154. postCall.enqueue(new Callback<ResponseBody>() {
  155. @Override
  156. public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
  157. if (null == call || null == response) return;
  158. //参数call信息打印
  159. boolean canceled = call.isCanceled();
  160. Request request = call.request();
  161. HttpUrl url = request.url();
  162. String method = request.method();
  163. Log.d("RetrofitActivity", "Post Map 请求onResponse方法canceled----:" + canceled);
  164. Log.d("RetrofitActivity", "Post Map 请求onResponse方法url.toString()----:" + url.toString());
  165. Log.d("RetrofitActivity", "Post Map 请求onResponse方法method----:" + method);
  166. //参数response信息打印
  167. String result = null;//报文 获取报文必须判断响应是否成功
  168. if (response.isSuccessful()) {
  169. try {
  170. result = response.body().string();
  171. } catch (IOException e) {
  172. e.printStackTrace();
  173. }
  174. String msg = response.toString();
  175. int code = response.code();
  176. boolean isSuccess = response.isSuccessful();
  177. Log.d("RetrofitActivity", "Post Map 请求onResponse方法result----:" + result);
  178. Log.d("RetrofitActivity", "Post Map 请求onResponse方法msg----:" + msg);
  179. Log.d("RetrofitActivity", "Post Map 请求onResponse方法code----:" + code);
  180. Log.d("RetrofitActivity", "Post Map 请求onResponse方法isSuccess----:" + isSuccess);
  181. } else {
  182. Log.d("RetrofitActivity", "Post Map 请求onResponse方法isSuccess----:" + false);
  183. }
  184. }
  185. @Override
  186. public void onFailure(Call<ResponseBody> call, Throwable t) {
  187. Log.d("RetrofitActivity", "Post Map 请求onFailure方法result2----:" + t.getMessage());
  188. }
  189. });
  190. }
  191. }
  192. }

4.结果

<1> Get请求

  1. D/RetrofitActivity: Get请求onResponse方法canceled----:false
  2. D/RetrofitActivity: Get请求onResponse方法url.toString()----:http://fanyi.youdao.com/openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue
  3. D/RetrofitActivity: Get请求onResponse方法method----:GET
  4. D/RetrofitActivity: Get请求onResponse方法result----:{"translation":["蓝色的"],"basic":{"us-phonetic":"bluː","phonetic":"bluː","uk-phonetic":"bluː","explains":["adj. 蓝色的;忧郁的,悲观的;(由于冷或呼吸困难)发青的,青紫的;(电影、玩笑或故事)色情的,黄色的;(肉)未熟的;(政治上)保守的","n. 蓝色;蓝色物品;(牛津或剑桥大学的运动员)蓝色荣誉者;失误;红发人;打架","vt. (使)变成蓝色;把......染成蓝色;给\u2026\u2026上蓝色漂白剂;挥霍(钱财)","n. (Blue) (英、美、加、澳、新)布卢(人名)"]},"query":"blue","errorCode":0,"web":[{"value":["蓝色的","刀枪不入","蓝色橙味糖浆"],"key":"blue"},{"value":["蓝月","蓝月亮","千载难逢的时机"],"key":"Blue Moon"},{"value":["青尼罗省","青尼罗河","蓝色尼罗河"],"key":"Blue Nile"}]}
  5. D/RetrofitActivity: Get请求onResponse方法msg----:Response{protocol=http/1.1, code=200, message=OK, url=http://fanyi.youdao.com/openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue}
  6. D/RetrofitActivity: Get请求onResponse方法code----:200
  7. D/RetrofitActivity: Get请求onResponse方法isSuccess----:true

<2> Post请求 单个参数逐一传参

  1. D/RetrofitActivity: Post请求onResponse方法canceled----:false
  2. D/RetrofitActivity: Post请求onResponse方法url.toString()----:http://fanyi.youdao.com/openapi.do
  3. D/RetrofitActivity: Post请求onResponse方法method----:POST
  4. D/RetrofitActivity: Post请求onResponse方法result----:{"translation":["红色的"],"basic":{"us-phonetic":"red","phonetic":"red","uk-phonetic":"red","explains":["adj. 红的,红色的;(毛发)红褐色的;(脸)涨红的;(眼睛)红肿的;革命的,激进的;(人)红种的;(纸牌中)红桃的,红方块的;(葡萄酒)红的;(表示停止)红(灯),红(旗);被禁止的,危险的;(滑雪道上用红色标志指示)第二高难度的;(物理)表示夸克三种颜色之一的红色;赤色的(尤指冷战期间用于指前苏联);沾有鲜血的;(古或诗\/文)流血的;(科萨人)来自传统部落文化的","n. 红色,红颜料;红衣;红葡萄酒;红色物(或人);赤字,亏空;激进分子","n. (Red) 雷德(人名)"]},"query":"red","errorCode":0,"web":[{"value":["红","红色","赤焰战场"],"key":"RED"},{"value":["红线","台北捷运红线","红线机油"],"key":"Red Line"},{"value":["红旗","红旗演习","危险信号"],"key":"red flag"}]}
  5. D/RetrofitActivity: Post请求onResponse方法msg----:Response{protocol=http/1.1, code=200, message=OK, url=http://fanyi.youdao.com/openapi.do}
  6. D/RetrofitActivity: Post请求onResponse方法code----:200
  7. D/RetrofitActivity: Post请求onResponse方法isSuccess----:true

<3> 集合方式传参

  1. D/RetrofitActivity: Post Map 请求onResponse方法canceled----:false
  2. D/RetrofitActivity: Post Map 请求onResponse方法url.toString()----:http://fanyi.youdao.com/openapi.do
  3. D/RetrofitActivity: Post Map 请求onResponse方法method----:POST
  4. D/RetrofitActivity: Post Map 请求onResponse方法result----:{"translation":["红色的"],"basic":{"us-phonetic":"red","phonetic":"red","uk-phonetic":"red","explains":["adj. 红的,红色的;(毛发)红褐色的;(脸)涨红的;(眼睛)红肿的;革命的,激进的;(人)红种的;(纸牌中)红桃的,红方块的;(葡萄酒)红的;(表示停止)红(灯),红(旗);被禁止的,危险的;(滑雪道上用红色标志指示)第二高难度的;(物理)表示夸克三种颜色之一的红色;赤色的(尤指冷战期间用于指前苏联);沾有鲜血的;(古或诗\/文)流血的;(科萨人)来自传统部落文化的","n. 红色,红颜料;红衣;红葡萄酒;红色物(或人);赤字,亏空;激进分子","n. (Red) 雷德(人名)"]},"query":"red","errorCode":0,"web":[{"value":["红","红色","赤焰战场"],"key":"RED"},{"value":["红线","台北捷运红线","红线机油"],"key":"Red Line"},{"value":["红旗","红旗演习","危险信号"],"key":"red flag"}]}
  5. D/RetrofitActivity: Post Map 请求onResponse方法msg----:Response{protocol=http/1.1, code=200, message=OK, url=http://fanyi.youdao.com/openapi.do}
  6. D/RetrofitActivity: Post Map 请求onResponse方法code----:200
  7. D/RetrofitActivity: Post Map 请求onResponse方法isSuccess----:true

5.总结

<1> Retrofit的BaseUrl必须以"/"结尾  否则报错

<2> Retrofit的Post请求须加注释  否则报错

<3> Call方法发起请求可以用两种方式一种enqueue异步 一种execute()同步大多数请求会用异步

<4> onResponse回调(即请求成功的回调)中,除了可以拿到请求的报文,还可以拿到很多其他的信息,比如请求码200,比如请求方法,比如请求Url等等。都是很有用的信息。且 获取报文必须判断响应是否成功

<5> 单独使用Retrofit时,如果不配置CONVERTERS 即合成器 (详解见官网) 报文格式只能是  ResponseBody

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/45604
推荐阅读
相关标签
  

闽ICP备14008679号