我需要在Retrofit中使用@POST提交大量数据(嵌套的json对象)以及多个图像/文件。
一种简单/ hacky方式是将图像转换为base64字符串&amp;放入RequestBody&amp;不使用@Multipart就发送它。另一种方法是使用@PartMap() Map<String, RequestBody>
。附加一些数据和图像。如果数据较少,则此方法有效。但是我有一个巨大的嵌套RequestBody:
{
"id": "id12",
"bar": {
"id": "id1",
"name": "asd"
}
} .....
但是如何使用@Multipart将身体与图像一起发送。
@Multipart
@POST("api/upload")
Observable<SubmitResponse> submitData(@Body Foo foo, @Part MultipartBody.Part[] files);
class Foo {
@SerializedName("book_id")
@Expose
private String book_id;
@SerializedName("bar")
@Expose
private Bar anotherBodyinsideFoo;
}
上述方法会抛出错误:@Body参数不能与表单或多部分编码一起使用。
在改造中提出如何上传多个文件以及请求正文(@Body Foo)的建议。
答案 0 :(得分:1)
请使用改造
检查以下代码以上传多张图片@POST(UPLOAD_EVENT)
Call<EventResponse> uploadEvent(@Header("Authorization") String auth, @Body RequestBody body);
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("event_name", eventName);
builder.addFormDataPart("location", loacation);
builder.addFormDataPart("longitude", longitude);
builder.addFormDataPart("latitude", latitude);
builder.addFormDataPart("is_private", isPublic);
builder.addFormDataPart("caption", caption);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), coverImage);
builder.addFormDataPart("cover_image", coverImage.getName(), requestBody);
RequestBody requestBody1 = null;
for (int i = 0, size = eventFiles.size(); i < size; i++) {
requestBody1 = RequestBody.create(MediaType.parse("multipart/form-data"), eventFiles.get(i));
builder.addFormDataPart("album_images" + "[" + i + "]", eventFiles.get(i).getName(), requestBody1);
}
RequestBody finalRequestBody = builder.build();
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RestClient.ROOT)
.addConverterFactory(GsonConverterFactory.create())
.build();
RestClient.NetworkCall networkCall = retrofit.create(RestClient.NetworkCall.class);
Call<EventResponse> response = networkCall.uploadEvent(Prefs.getAuth(App.getContext()), finalRequestBody);
response.enqueue(new Callback<EventResponse>() {
@Override
public void onResponse(Call<EventResponse> call, Response<EventResponse> response) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(MY_NOTIFICATION_ID);
if (response.code() == Constant.SUCCESS_STATUS) {
if (response.body() != null) {
sendBroadcast(new Intent(Constant.REFRESH_FEEDS));
Log.e("Success", "Success");
}
} else {
Converter<ResponseBody, EventResponse> converter =
retrofit.responseBodyConverter(EventResponse.class, new Annotation[0]);
try {
if (response.errorBody() != null) {
EventResponse errorResponse = converter.convert(response.errorBody());
Log.e("Failure", "Failure");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<EventResponse> call, Throwable t) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(MY_NOTIFICATION_ID);
Log.e("Failure", "Failure");
}
});