Retrofit和RxJava系列博客:
使用Retrofit上传文件
使用Gson解析Retrofit返回结果
Retrofit和RxJava结合使用
使用Retrofit和RxJava进行轮询操作
Retrofit是Square公司开发的网络请求框架,其底层封装了okhttp进行实际的网络请求操作。关于其基础用法,强烈推荐腾讯bugly社区的博文《深入浅出 Retrofit》:
本文将以使用Multipart方式上传图片为例,总结一下Retrofit的使用方法。
添加依赖
在build.gradle中加入依赖
compile 'com.squareup.retrofit2:retrofit:2.1.0'
定义Multipart请求接口
Multipart在http中常常用于上传文件。首先需要使用注解@Multipart
,表明该接口使用Multipart方式进行请求。在接口的upload
方法中,使用@Part
注解定义上传的内容,这里的第一个@Part
表示一个键为UserId
、值为description
的参数;第二个@Part
表示该参数为一个MultipartBody.Part
类型的文件file
。
public interface FileUploadService {
@Multipart
@POST("EntranceGuardes/app/appOpen_pushdDataToApp.action")
Call<ResponseBody> upload(@Part("userId") RequestBody description,
@Part MultipartBody.Part file);
}
传入文件
首先,需要构造一个FileUploadService
对象service
:
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://172.18.81.155:8080/").build();
FileUploadService service = retrofit.create(FileUploadService.class);
接下来需要调用service
的upload
方法。upload
方法的第一个参数是@Part("userId") RequestBody description
,使用RequestBody.create
方法就可以将字符串s
变为RequestBody
类型。值得注意的是MediaType.parse("text/plain")
中使用MIME来说明上传数据的类型。
String s = "1006";
RequestBody description = RequestBody.create(MediaType.parse("text/plain"), s);
如果加入要上传的图片呢?首先需要打开图片文件,随后使用RequestBody.create
创建一个RequestBody
对象,然后调用MultipartBody.Part.createFormData
将RequestBody
对象转变为MultipartBody.Part
对象。注意到这里的MIME
指定为image/*
,表明这部分数据是图片类型的文件。
File file = new File("/storage/sdcard/Desert.jpg");
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
异步调用
定义完成请求以后就需要调用了,retrofit和okhttp一样提供了同步调用和异步调用两种方式,常用的就是异步调用方式。异步调用只需要在enqueue
方法中传入回调对象就可以了。在回调的接口中,需要实现两个方法onResponse
和onFailure
,分别对应中请求成功响应和请求失败两种情况。
Call<ResponseBody> call = service.upload(description, body);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.d("main", response.body().string());
Log.d("main",Thread.currentThread().getName());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
完整代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File file = new File("/storage/sdcard/Desert.jpg");
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://172.18.81.155:8080/").build();
FileUploadService service = retrofit.create(FileUploadService.class);
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
String s = "1006";
RequestBody description = RequestBody.create(MediaType.parse("text/plain"), s);
Call<ResponseBody> call = service.upload(description, body);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.d("main", response.body().string());
Log.d("main",Thread.currentThread().getName());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
public interface FileUploadService {
@Multipart
@POST("EntranceGuardes/app/appOpen_pushdDataToApp.action")
Call<ResponseBody> upload(@Part("userId") RequestBody description,
@Part MultipartBody.Part file);
}
}
代码地址
https://github.com/flyingzhao/JavaExperiment/tree/master/androidapp/RetrofitTest