Retrofit2是什麼
使用項目的原話:Android和Java中類型安全的HTTP用戶端
項目位址:https://github.com/square/retrofit
Retrofit2的導入
這裡Retrofit還需要導入它的Gson依賴庫,因為傳回的資料需要Gson來處理
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
Retrofit2的基本使用
1、Get請求
2、Post請求
3、單、多檔案上傳
Retrofit2工具類的示範
示範提供的接口(該接口不支援post方式)
http://japi.juhe.cn/joke/content/list.from?key=488c65f3230c0280757b50686d1f1cd5&&sort=asc&&time=1418816972
get請求(支援普通請求)
/*
* Get請求
* 參數已經封裝在工具類的Url中
*/
Call<Info> call = RetrofitUtils.getInstance().get();
call.enqueue(new Callback<Info>() {
@Override
public void onResponse(Call<Info> call, Response<Info> response) {
}
@Override
public void onFailure(Call<Info> call, Throwable t) {
}
});
get請求(支援鍵值對參數)
//根據接口需求建立鍵值對
Map<String,String> map = new HashMap<>();
map.put("key","488c65f3230c0280757b50686d1f1cd5");
map.put("sort","asc");
map.put("time","1418816972");
/*
* Get請求
* @param map 為get參數
*/
Call<Info> call = RetrofitUtils.getInstance().get(map);
call.enqueue(new Callback<Info>() {
@Override
public void onResponse(Call<Info> call, Response<Info> response) {
}
@Override
public void onFailure(Call<Info> call, Throwable t) {
}
});
Post請求(支援鍵值對參數)
//根據接口需求建立鍵值對
Map<String,String> map = new HashMap<>();
map.put("key","488c65f3230c0280757b50686d1f1cd5");
map.put("sort","asc");
map.put("time","1418816972");
/*
* Post請求
* @param map 為Post參數
*/
Call<Info> call = RetrofitUtils.getInstance().post(map);
call.enqueue(new Callback<Info>() {
@Override
public void onResponse(Call<Info> call, Response<Info> response) {
}
@Override
public void onFailure(Call<Info> call, Throwable t) {
}
});
Post請求(支援擷取傳回的字元串)
//根據接口需求建立鍵值對
Map<String,String> map = new HashMap<>();
map.put("key","488c65f3230c0280757b50686d1f1cd5");
map.put("sort","asc");
map.put("time","1418816972");
/*
* Post請求
* @param map 為Post參數
*/
Call<ResponseBody> call = RetrofitUtils.getInstance().post(map);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//這裡采用Retrofit2自帶的ResponseBody可以傳回對應的字元串資料,get請求同理
String body = response.body().string().toString();
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
Post請求(上傳檔案和參數)
//檔案的封裝
List<MultipartBody.Part> parts = null;
parts = RetrofitUtils.filesToMultipartBodyParts("imgs[]", photo_list);
//參數的封裝
Map<String, RequestBody> params = new HashMap<>();
params.put("token", RetrofitUtils.convertToRequestBody("abcdefg"));
params.put("username", RetrofitUtils.convertToRequestBody("hensen"));
params.put("password", RetrofitUtils.convertToRequestBody("123456"));
//上傳檔案和參數
Call<Object> call = RetrofitUtils.getInstance().register(params, parts);
call.enqueue(new Callback<Object>() {
@Override
public void onResponse(Call<Object> call, Response<Object> response) {
}
@Override
public void onFailure(Call<Object> call, Throwable t) {
}
});
Retrofit2工具類的封裝
Retrofit的請求是以REST請求方式發送請求的,是以工具的封裝需要做兩件事
- 對REST請求的API進行封裝
- Retrofit自身的封裝
由于我們接口傳回的JSON資料如下
{
"error_code": 0,
"reason": "Success",
"result": {
"data":[
{
"content":"學校論壇上有人問:“為啥明明用了除蟑螂的藥,蟑螂卻越來越多了。”某個學生回帖:“如果你家人不見了,你不出來找嗎?你會不着急麼?”",
"hashId":"8196907ee902f3508b9be6ea59d2191c",
"unixtime":1478598830,
"updatetime":"2016-11-08 17:53:50"
}
]
}
}
是以這裡需要對我們需要解析的資料進行Bean對象的封裝
public class Info {
@Override
public String toString() {
return "Info{" +
"error_code=" + error_code +
", reason='" + reason + '\'' +
", result=" + result +
'}';
}
private int error_code;
private String reason;
private ResultBean result;
public static class ResultBean {
@Override
public String toString() {
return "ResultBean{" +
"data=" + data +
'}';
}
private List<DataBean> data;
public static class DataBean {
private String content;
private String hashId;
private int unixtime;
private String updatetime;
@Override
public String toString() {
return "DataBean{" +
"content='" + content + '\'' +
", hashId='" + hashId + '\'' +
", unixtime=" + unixtime +
", updatetime='" + updatetime + '\'' +
'}';
}
}
}
}
對REST請求的API進行封裝
Retrofit使用注解的方式來聲明GET請求、POST請求、請求參數、請求頭等進行的網絡通路,下面是各個注解的表示的意思
- Get請求相關
- @Get:發送Get請求
- @Query:Get請求參數
- @QueryMap:Get請求Map參數
- Post請求相關
- @Post:發送Post請求
- @FormUrlEncoded:采用表單的方式,一般與@Post共用
- @Field:Post請求參數
- @FieldMap:Post請求Map參數
- Header請求相關
- @Headers:發送Header資訊
- @Header:Header資訊參數
- @HeaderMap:Header資訊的Map參數
- Path請求相關
- @Path:通路路徑,最終通路[email protected]裡面的内容
了解完意思之後,編寫REST的API,其實就是請求接口,具體看下面的代碼
public interface IRetrofitServer {
String getUrl = "list.from";
String postUrl = "list.from";
/**
* 傳遞參數的Get請求
* @param key
* @param sort
* @param time
* @return
*/
@GET(getUrl)
Call<Info> get(@Query("key") String key, @Query("sort") String sort, @Query("time") String time);
/**
* 封裝好Url的Get的請求
* @return
*/
@GET(getUrl + "?key=488c65f3230c0280757b50686d1f1cd5&&sort=asc&&time=1418816972")
Call<Info> get();
/**
* 傳遞Map鍵值對的Get請求
* @param params
* @return
*/
@GET(getUrl)
Call<Info> get(@QueryMap Map<String, String> params);
/**
* 傳遞參數的Post請求
* @param key
* @param sort
* @param time
* @return
*/
@FormUrlEncoded
@POST(postUrl)
Call<Info> post(@Field("key") String key, @Field("sort") String sort, @Field("time") String time);
/**
* 傳遞Map鍵值對的Post請求
* @param map
* @return
*/
@FormUrlEncoded
@POST(postUrl)
Call<Info> post(@FieldMap Map<String, String> map);
/**
* 傳遞Map鍵值對的Post請求
* @param map
* @return 對應的字元串資料
*/
@FormUrlEncoded
@POST(postUrl)
Call<ResponseBody> post(@FieldMap Map<String, String> map);
/**
* 傳遞Map鍵值對和Header的Post請求
* @param key
* @param sort
* @param time
* @return
*/
@Headers({"os:Android", "version:2.0"})
@FormUrlEncoded
@POST(postUrl)
Call<Info> postWithHeader(@Field("key") String key, @Field("sort") String sort, @Field("time") String time);
/**
* 傳遞Map鍵值對和Header的Post請求
* @param os
* @param key
* @param sort
* @param time
* @return
*/
@FormUrlEncoded
@POST(postUrl)
Call<Info> postWithHeader(@Header("os") String os, @Field("key") String key, @Field("sort") String sort, @Field("time") String time);
/**
* 傳遞Map鍵值對和Header的Post請求
* @param map
* @param key
* @param sort
* @param time
* @return
*/
@FormUrlEncoded
@POST(postUrl)
Call<Info> postWithHeader(@HeaderMap Map<String, String> map, @Field("key") String key, @Field("sort") String sort, @Field("time") String time);
/**
* 傳遞通路路徑和鍵值對的Post請求
* @param path
* @param key
* @param sort
* @param time
* @return
*/
@FormUrlEncoded
@POST("{path}")
Call<Info> post(@Path("path") String path, @Field("key") String key, @Field("sort") String sort, @Field("time") String time);
}
Retrofit自身的封裝
Retrofit和okHttp一樣,采用構造者模式建立,采用單例模式防止使用多個對象
private static final String baseUrl = "http://japi.juhe.cn/joke/content/";
private static Retrofit retrofit = null;
private static IRetrofitServer iServer;
public static IRetrofitServer getInstance() {
if (retrofit == null) {
synchronized (RetrofitUtils.class) {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
iServer = retrofit.create(IRetrofitServer.class);
}
}
}
return iServer;
}
上面代碼做了三件事
- 綁定請求URL
- 采用GSON來處理傳回的JSON資料
- 建立并傳回REST請求API接口iServer
下面就可以直接使用工具類拿到這個iServer,調用提供的接口方法
Call<Info> call = RetrofitUtils.getInstance().get();
call.enqueue(...);
單、雙檔案的上傳
API接口的建立,比如說注冊功能,需要上傳兩張身份證照片,這是我自己伺服器的接口
public interface IRetrofitServer {
@Multipart
@POST("app/register")
Call<Object> register(@PartMap Map<String, RequestBody> map, @Part List<MultipartBody.Part> parts);
}
- @PartMap:表示參數的上傳
- @Part:表示檔案清單
建立兩個方法輔助PartMap和Part的建立
//這裡的key則是背景伺服器的字段名,即使H5中input的name的名字
//如果是單檔案,filePaths的大小就為1
public static List<MultipartBody.Part> filesToMultipartBodyParts(String key, List<String> filePaths) {
List<MultipartBody.Part> parts = new ArrayList<>(filePaths.size());
for (String filePath : filePaths) {
File file = new File(filePath);
//這裡的image/*表示上傳的是相片的所有格式,你可以替換成你需要的格式
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData(key, file.getName(), requestBody);
parts.add(part);
}
return parts;
}
public static RequestBody convertToRequestBody(String param) {
//這裡的text/plain表示參數都是文本
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), param);
return requestBody;
}
到這裡,你就可以回過頭去看下文章開頭的示範部分,那裡就是RetrofitUtils的使用
工具類下載下傳:RetrofitUtils
由于檔案上傳是我在做項目的時候用上的,工具類缺少檔案上傳的内容,大家可以自行去拷貝代碼