一、 说明
1.文件上传一般用post请求
2.文件上传的API接口中不能带@FormUrlEncoded参数
3.一般要携带@Multipart(上传文件的标志)
4.接口范例:
@Multipart
@POST("UploadServlet")
Call<String> uploadFile(@PartMap Map<String, RequestBody> params);
或
@Multipart
@POST("UploadServlet")
Call<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file);
二、实现单文件上传
1.AP接口
@Multipart @POST("UploadServlet") Call<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file);
2.具体实现请求代码:
Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl("http://192.168.12.101:8080/happy/") .build(); UploadFileService service = retrofit.create(UploadFileService.class); File file = new File("/sdcard/Pictures/myPicture/index.jpg");//访问手机端的文件资源,保证手机端sdcdrd中必须有这个文件 RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); MultipartBody.Part body = MultipartBody.Part.createFormData("aFile", file.getName(), requestFile); String descriptionString = "This is a description"; RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString); Call<ResponseBody> call = service.upload(description, body); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { System.out.println("success"); } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { t.printStackTrace(); } });
multipart/form-data表示将数据以二进制的形式传入服务端中的request中,
MultipartBody.Part.createFormData("aFile", file.getName(), requestFile);
中第一个参数是数组名,第二个参数是文件名;将每条数据都必须封住到RequestBody中。如果你以一下方式创建上传文件:
String filePath = Environment.getExternalStorageDirectory()+File.separator+"love.txt"; File file = new File(filePath);
记得一定得配置用户权限,低级错误,咋就少犯点:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
三、实现多文件上传
1接口
@Multipart @POST("UploadServlet") Call<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file, @Part MultipartBody.Part file2);
2.然后请求代码中也多了一行
File file = new File("/sdcard/Pictures/myPicture/index.jpg"); File file1 = new File("/sdcard/Picuures/myPicture/me.txt"); RequestBody requestFile = RequestBody.create(MediaType.parse("applicaiton/otcet-stream"), file); RequestBody requestFile1 = RequestBody.create(MediaType.parse("applicaiton/otcet-stream"), file1); MultipartBody.Part body1 = MultipartBody.Part.createFormData("aFile", file.getName(), requestFile); MultipartBody.Part body2 = MultipartBody.Part.createFormData("aFile", file.getName(), requestFile1); String descriptionString = "This is a description"; RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString); Call<ResponseBody> call = service.upload(description, body1,body2);
3.或者以@PartMap的形式实现多文件上传
①API
@Multipart @POST("UploadServlet") Call<String> uploadFile(@PartMap Map<String, RequestBody> params);
②请求代码:
Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl("http://192.168.12.101:8080/happy/") .build(); UploadFileService service = retrofit.create(UploadFileService.class); File file = new File("/sdcard/Pictures/myPicture/index.jpg"); File file1 = new File("/sdcard/Picuures/myPicture/me.txt");
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); RequestBody requestBody1 = RequestBody.create(MediaType.parse("multipart/form-data"), file1); Map<String, RequestBody> params = new HashMap<>(); params.put("file\"; filename=\""+ file.getName(), requestBody); params.put("file\"; filename=\""+ file1.getName(), requestBody1); Call<String> model = service.uploadFile(params); model.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { Log.i("MainActivity",response.body().toString()); } @Override public void onFailure(Call<String> call, Throwable t) { Log.i("错误信息:",t.getMessage()); } });
四、图片文件混合上传
@Multipart
@POST(NRConfig.UPDATE_FILES)
Call<Result<UpdateFilesEntity>> updateOneFile(@PartMap Map<String,RequestBody> data,@Part("pic") RequestBody description,@Part MultipartBody.Part file);
使用@Multipart注解,参数通过@PartMap形式上传,注意,这里一定要用Map<String,RequestBody>这样的格式,
也只能用RequestBody形式,本身retrofit是仅支持两种形式的String类型,这里的不在其中,故此不支持直接使用
String类型,必须转成RequestBody形式,附上转型方法
public static RequestBody toRequestBody(String value) {
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), value);
return requestBody;
}
完整代码
/**
* @param callback
* @return
*/
public static Call updateOneFile(Map<String,RequestBody> type, File file, final ResultCallback<Result<UpdateFilesEntity>> callback) {
if (callback == null) throw new NullPointerException("callback == null");
NRService mService = ServiceFactory.createNewService(NRService.class);
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), reqFile);
String descriptionString = "image";
RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString);
Call<Result<UpdateFilesEntity>> call = mService.updateOneFile(type, description, body);
Callback<Result<UpdateFilesEntity>> cbk = new Callback<Result<UpdateFilesEntity>>() {
@Override
public void onResponse(Call<Result<UpdateFilesEntity>> call, Response<Result<UpdateFilesEntity>> response) {
Result.onResponse(response, callback);
}
@Override
public void onFailure(Call<Result<UpdateFilesEntity>> call, Throwable t) {
Result.onFailure(t, callback);
}
};
call.enqueue(cbk);
return call;
}