後臺地址:https://github.com/TrillGates/SOBAndroidMiniWeb
教學視頻:https://www.bilibili.com/video/BV19J411p7pY?p=3
使用單例模式
public class RetrofitManager {
private static Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://10.0.2.2:9102")
.addConverterFactory(GsonConverterFactory.create())
.build();
public static Retrofit getRetrofit(){
return retrofit;
}
}
API接口,其中<>裏面的都是用GsonFormat依據返回格式自動生成的Bean類
public interface API {
@GET("get/text")
Call<GetTextItem> getJson();
@GET("get/text")
Call<ResponseBody> getJson1();
@GET("/get/param")
Call<GetParamsItem> getWithParams(@Query("keyword")String keyword,@Query("page")String page
,@Query("order")String order);
}
1.使用Gson來解析json
GetTextItem是使用GsonFormat規範化出來的class類
public void getRequest(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Call<ResponseBody> call = api.getJson1();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e(TAG, "onResponse: " + response.code());
if (response.code() == 200) {
String jsonstr = response.body().string();
Gson gson = new Gson();
GetTextItem getTextItem = gson.fromJson(jsonstr, GetTextItem.class);
updateUI(getTextItem);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.toString());
}
});
}
2.轉換器方式(可以直接轉換爲對象,很方便)
implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
public void converter(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Call<GetTextItem> call = api.getJson();
call.enqueue(new Callback<GetTextItem>() {
@Override
public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
Log.e(TAG, "onResponse: "+response.code() );
GetTextItem getTextItem = response.body();
updateUI(getTextItem);
}
@Override
public void onFailure(Call<GetTextItem> call, Throwable t) {
Log.e(TAG, "onFailure: "+t.toString() );
}
});
}
get請求帶參數
public void getWithParams(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Call<GetParamsItem> withParams = api.getWithParams("key", "12", "0");
withParams.enqueue(new Callback<GetParamsItem>() {
@Override
public void onResponse(Call<GetParamsItem> call, Response<GetParamsItem> response) {
Log.e(TAG, "onResponse: " + response.code());
GetParamsItem getParamsItem = response.body();
Log.e(TAG, "onResponse: " + getParamsItem.toString());
}
@Override
public void onFailure(Call<GetParamsItem> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.toString());
}
});
}
如果參數過多可以使用一個QueryMap來寫參數
@GET("/get/param")
Call<GetParamsItem> getWithParams(@QueryMap Map<String,Object> map);
public void getWithParamsMap(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Map<String,Object> map = new HashMap<>();
map.put("keyword","key");
map.put("page",12);
map.put("order","1");
Call<GetParamsItem> withParams = api.getWithParams(map);
withParams.enqueue(new Callback<GetParamsItem>() {
@Override
public void onResponse(Call<GetParamsItem> call, Response<GetParamsItem> response) {
Log.e(TAG, "onResponse: " + response.code());
GetParamsItem getParamsItem = response.body();
Log.e(TAG, "onResponse: " + getParamsItem.toString());
}
@Override
public void onFailure(Call<GetParamsItem> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.toString());
}
});
}
4.post請求一個字符串
@POST("/post/string")
Call<PostParamsItem> postWithParams(@Query("string") String content);
public void postWithParams(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Call<PostParamsItem> task = api.postWithParams("string");
task.enqueue(new Callback<PostParamsItem>() {
@Override
public void onResponse(Call<PostParamsItem> call, Response<PostParamsItem> response) {
Log.e(TAG, "onResponse: "+response.code());
PostParamsItem body = response.body();
Log.e(TAG, "onResponse: "+body.toString() );
}
@Override
public void onFailure(Call<PostParamsItem> call, Throwable t) {
}
});
}
5.提交字符串
使用url註解實現4
@POST
Call<PostParamsItem> postWithUrl(@Url String url);
public void postWithUrl(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Call<PostParamsItem> task = api.postWithUrl("/post/string?string=123");
task.enqueue(new Callback<PostParamsItem>() {
@Override
public void onResponse(Call<PostParamsItem> call, Response<PostParamsItem> response) {
Log.e(TAG, "onResponse: "+response.code());
PostParamsItem body = response.body();
Log.e(TAG, "onResponse: "+body.toString() );
}
@Override
public void onFailure(Call<PostParamsItem> call, Throwable t) {
}
});
}
6.提交評論
@Body註解
把要提交的數據寫成一個bean類,用gsonFormat快速生成
@POST("/post/comment")
Call<PostParamsItem> postWithBody(@Body CommandItem commandItem);
public void postWithBody(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
CommandItem commandItem = new CommandItem("123","1231456");
Call<PostParamsItem> task = api.postWithBody(commandItem);
task.enqueue(new Callback<PostParamsItem>() {
@Override
public void onResponse(Call<PostParamsItem> call, Response<PostParamsItem> response) {
Log.e(TAG, "onResponse: "+response.code());
PostParamsItem body = response.body();
Log.e(TAG, "onResponse: "+body.toString() );
}
@Override
public void onFailure(Call<PostParamsItem> call, Throwable t) {
}
});
}
7.上傳單文件
@Part註解和@Multipart註解
@Multipart
@POST("/file/upload")
Call<PostFileItem> postWithFile(@Part MultipartBody.Part part);//進去Part源碼可以看到接收什麼參數
代碼可以倒着寫,需要什麼就補充什麼,從api.postWithFile()倒着往回寫
還需要申請讀取外部存儲的權限
public void postWithPart(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
File file = new File("/storage/self/primary/Download/u=2604811881,2055398559&fm=173&app=49&f=JPEG (1).jpg");
RequestBody body = RequestBody.create(file,MediaType.parse("image/jpeg"));
MultipartBody.Part part = MultipartBody.Part.createFormData("file",file.getName(),body);
Call<PostFileItem> task = api.postWithFile(part);
task.enqueue(new Callback<PostFileItem>() {
@Override
public void onResponse(Call<PostFileItem> call, Response<PostFileItem> response) {
Log.e(TAG, "onResponse: "+response.code());
Log.e(TAG, "onResponse: "+response.body() );
}
@Override
public void onFailure(Call<PostFileItem> call, Throwable t) {
Log.e(TAG, "onFailure: "+t.toString() );
}
});
}
8.上傳多文件
@Multipart
@POST("/files/upload")
Call<PostFileItem> postWithFiles(@Part List<MultipartBody.Part> parts);
private MultipartBody.Part ReturnPart(String path,String key){
File file = new File(path);
RequestBody body = RequestBody.create(file,MediaType.parse("image/jpeg"));
MultipartBody.Part part = MultipartBody.Part.createFormData(key,file.getName(),body);
return part;
}
public void postWithFiles(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
List<MultipartBody.Part> parts = new ArrayList<>();
String path1 = "/storage/self/primary/Download/u=2604811881,2055398559&fm=173&app=49&f=JPEG (1).jpg";
String path2 = "/storage/self/primary/Download/u=2604811881,2055398559&fm=173&app=49&f=JPEG.jpg";
String path3 = "/storage/self/primary/Download/u=3340390700,4267772580&fm=173&app=49&f=JPEG.jpg";
parts.add(ReturnPart(path1,"files"));
parts.add(ReturnPart(path2,"files"));
parts.add(ReturnPart(path3,"files"));
Call<PostFileItem> task = api.postWithFiles(parts);
task.enqueue(new Callback<PostFileItem>() {
@Override
public void onResponse(Call<PostFileItem> call, Response<PostFileItem> response) {
Log.e(TAG, "onResponse: "+response.code());
}
@Override
public void onFailure(Call<PostFileItem> call, Throwable t) {
Log.e(TAG, "onFailure: "+t.toString() );
}
});
}
9上傳文件並提交信息
@Multipart
@POST("/file/params/upload")
Call<PostFileItem> postFileWithParams(@Part MultipartBody.Part part,
@PartMap Map<String,String> params);
public void postFileWithParams(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
String path = "/storage/self/primary/Download/u=2604811881,2055398559&fm=173&app=49&f=JPEG (1).jpg";
MultipartBody.Part part = ReturnPart(path, "file");
Map<String,String> map = new HashMap<>();
map.put("description","4567");
map.put("isFree","false");
Call<PostFileItem> task = api.postFileWithParams(part,map);
task.enqueue(new Callback<PostFileItem>() {
@Override
public void onResponse(Call<PostFileItem> call, Response<PostFileItem> response) {
Log.e(TAG, "onResponse: "+response.code() );
Log.e(TAG, "onResponse: "+response.body().toString() );
}
@Override
public void onFailure(Call<PostFileItem> call, Throwable t) {
Log.e(TAG, "onFailure: "+t.toString() );
}
});
}
10.表單提交
@FormUrlEncoded
@POST("/login")
Call<LoginItem> postLoginWithForm(@Field("userName") String userName,@Field("password") String password);
public void postLogin(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Call<LoginItem> task = api.postLoginWithForm("123", "123");
task.enqueue(new Callback<LoginItem>() {
@Override
public void onResponse(Call<LoginItem> call, Response<LoginItem> response) {
Log.e(TAG, "onResponse: "+response.code());
Log.e(TAG, "onResponse: "+response.body().toString() );
}
@Override
public void onFailure(Call<LoginItem> call, Throwable t) {
Log.e(TAG, "onFailure: "+t.toString() );
}
});
}
也可以改爲一個FiledMap
@FormUrlEncoded
@POST("/login")
Call<LoginItem> postLoginWithForms(@FieldMap Map<String,String> map);
public void postLogin(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Map<String,String> map = new HashMap<>();
map.put("userName","123");
map.put("password","456");
Call<LoginItem> task = api.postLoginWithForms(map);
task.enqueue(new Callback<LoginItem>() {
@Override
public void onResponse(Call<LoginItem> call, Response<LoginItem> response) {
Log.e(TAG, "onResponse: "+response.code());
Log.e(TAG, "onResponse: "+response.body().toString() );
}
@Override
public void onFailure(Call<LoginItem> call, Throwable t) {
Log.e(TAG, "onFailure: "+t.toString() );
}
});
}
11.文件下載
@Streaming
@GET
Call<ResponseBody> downLoad(@Url String url);
public void downLoad(View view) {
API api = RetrofitManager.getRetrofit().create(API.class);
Call<ResponseBody> call = api.downLoad("/download/1");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.e(TAG, "onResponse: " + response.code());
Headers headers = response.headers();
// for (int i = 0; i < headers.size(); i++) {
// String value = headers.value(i);
// String name = headers.name(i);
// Log.e(TAG, name+" ---->" +value);
// }
String fileName = "未命名.png";
String filenameheader = headers.get("Content-disposition");
if (filenameheader != null) {
fileName = filenameheader.replace("attachment; filename=", "");
Log.e(TAG, "onResponse: " + fileName);
}
writeStringDisk(response, fileName);
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
private void writeStringDisk(Response<ResponseBody> response, String fileName) {
new Thread(new Runnable() {
@Override
public void run() {
InputStream inputStream = response.body().byteStream();
File baseOutFile = getExternalFilesDir(DIRECTORY_PICTURES);
Log.e(TAG, "run: " + baseOutFile);
File outfile = new File(baseOutFile, fileName);
try {
FileOutputStream fos = new FileOutputStream(outfile);
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
12.傳輸Token消息
@Header
@Multipart
@POST("/file/upload")
Call<PostFileItem> postWithFile(@Part MultipartBody.Part part, @Header("token") String token);
@Headers
@Headers({"token:123456asd","client:android","version:1.0"})
@Multipart
@POST("/files/upload")
Call<PostFileItem> postWithFiles(@Part List<MultipartBody.Part> parts);
@HeaderMap
@Multipart
@POST("/file/params/upload")
Call<PostFileItem> postFileWithParams(@Part MultipartBody.Part part,
@PartMap Map<String,String> params,
@HeaderMap Map<String,String> headermap
);