場景
Retrofit2
Retrofit 是對 OkHttp 的封裝,是主流的網絡框架。
適用於Android 和 Java 的類型安全的HTTP客戶端,由Square提供的。
Retrofit是一種HTTP客戶端框架,使用它,我們可以完成有關HTTP的工作。
Retrofit Github 主頁:
https://github.com/square/Retrofit
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。
實現
導入依賴
在build.gradle中添加依賴
//Retrofit(網絡請求框架) implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
添加位置

然后點擊右上角的Sync now
注意:這里不能導入OkHttp與Gson,Retrofit內部已經包含這兩個框架,否則會導致版本沖突。
打卡網絡權限
在AndroidManifest中添加網絡權限。
<uses-permission android:name="android.permission.INTERNET" />
搭建Http客戶端
為了在調用接口時方便我們新建一個單例模式的類WebClient去構造Retrofit的實例
在src下包路徑下新建web包,包下新建webclient類
package com.badao.badaoimclient.web; import android.util.Log; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class WebClient { private static ApiService INSTANCE; private static final String BASE_URL = "http://你的后台服務的ip:8000/"; public static ApiService getInstance() { if (INSTANCE == null) { synchronized (ApiService.class) { if (INSTANCE == null) { INSTANCE = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build().create(ApiService.class); Log.i("INSTANCE",BASE_URL); } } } return INSTANCE; } }
這里指定的BASE_RUL就是你后台服務地址的ip+端口號,最后要帶一個斜杠。
然后客戶端需要返回一個接口類ApiService,這個接口類是自定義的。
新建接口類ApiService
package com.badao.badaoimclient.web; import com.badao.badaoimclient.bean.ImUserBean; import com.badao.badaoimclient.bean.UploadBean; import okhttp3.MultipartBody; import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Multipart; import retrofit2.http.POST; import retrofit2.http.Part; public interface ApiService { /*無參GET請求 */ //沒有數據就填 '.' 或者 '/' //獲取通訊錄接口 @GET("system/imuser/listForApp") Call<ImUserBean> getImUserList(); //文件上傳接口 @Multipart @POST("/common/upload") Call<UploadBean> upload(@Part MultipartBody.Part file); }
這里接口類中有兩個方法,一個是get方法請求數據,一個是post方法上傳文件。
先看這里的get請求的接口,接口的返回值ImUserBean是根據服務接口返回的Json數據生成的bean。

怎樣根據Json數據生成實體Bean參考如下:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/110426851
生成的實體ImUserBean如下
package com.badao.badaoimclient.bean; import com.google.gson.annotations.SerializedName; import java.util.List; public class ImUserBean { private int total; private int code; private Object msg; private List<RowsBean> rows; public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public Object getMsg() { return msg; } public void setMsg(Object msg) { this.msg = msg; } public List<RowsBean> getRows() { return rows; } public void setRows(List<RowsBean> rows) { this.rows = rows; } public static class RowsBean { @SerializedName("id") private int idX; @SerializedName("imNum") private String imNumX; @SerializedName("canOnline") private int canOnlineX; public int getIdX() { return idX; } public void setIdX(int idX) { this.idX = idX; } public String getImNumX() { return imNumX; } public void setImNumX(String imNumX) { this.imNumX = imNumX; } public int getCanOnlineX() { return canOnlineX; } public void setCanOnlineX(int canOnlineX) { this.canOnlineX = canOnlineX; } } }
然后真正調用的接口的url就是
上面配置的BASE_URL加上你的接口方法中配置的url
Get接口調用
在需要調用get接口請求數據的地方
//異步請求通訊錄 WebClient.getInstance().getImUserList().enqueue(new Callback<ImUserBean>() { @Override public void onResponse(Call<ImUserBean> call, Response<ImUserBean> response) { Log.i("response",response.toString()); if(response.code()==200) { //獲取請求的數據並進行后續操作 ImUserBean userBean = response.body(); rowsBeanList = userBean.getRows(); myAdapter = new MyAdapter(rowsBeanList); listView.setAdapter(myAdapter); } } @Override public void onFailure(Call<ImUserBean> call, Throwable t) { Log.i("onFailure",t.toString()); } }); }
通過它的回調方法來獲取響應碼和響應體。
此后台接口是用SpringBoot寫成,后台get接口部分實現
@GetMapping("/listForApp") @ResponseBody public TableDataInfo listGet(ImUser imUser) { startPage(); List<ImUser> list = imUserService.selectImUserList(imUser); return getDataTable(list); }
其中在getDataTable中最終返回

調用一下此接口可以看到其響應碼為200

響應體就是上面的json數據

然后可以將get請求的數據通過適配器顯示在ListView上

關於適配器的使用參照如下:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/111240545
POST請求上傳文件
首先在ApiService中添加接口聲明
//文件上傳接口 @Multipart @POST("/common/upload") Call<UploadBean> upload(@Part MultipartBody.Part file);
然后在需要用到進行文件上傳的地方
//上傳語音文件到服務器 RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody); WebClient.getInstance().upload(part).enqueue(new Callback<UploadBean>() { @Override public void onResponse(Call<UploadBean> call, Response<UploadBean> response) { if(response.code()==200) { //對服務器地址進行賦值 chatItem.setRemoteContent(response.body().getFileName()); } else { Toast.makeText(App.context,"服務器返回"+response.code(),Toast.LENGTH_SHORT).show(); return; } } @Override public void onFailure(Call<UploadBean> call, Throwable t) { Toast.makeText(App.context,t.toString(),Toast.LENGTH_SHORT).show(); } });
其中file就是需要進行上傳的文件,需要構造出一個part對象,然后下面是兩個回調方法
觸發post方法后,構造part對象成功

后台使用sprinboot寫的post接口
/** * 通用上傳請求 */ @PostMapping("/common/upload") @ResponseBody public AjaxResult uploadFile(MultipartFile file) throws Exception { try { // 上傳文件路徑 String filePath = RuoYiConfig.getUploadPath(); // 上傳並返回新文件名稱 String fileName = FileUploadUtils.upload(filePath, file); String url = serverConfig.getUrl() + fileName; AjaxResult ajax = AjaxResult.success(); ajax.put("fileName", fileName); ajax.put("url", url); return ajax; } catch (Exception e) { return AjaxResult.error(e.getMessage()); } }
后台接收到請求后

后台返回給Android后

