Retrofit - Error 400 - android

I'm having issues trying to upload images and other details to my server using the below code:
public static final String APP_JSON = "Content-Type: application/json";
#Multipart
#Headers({ApiClient.APP_JSON})
#POST("relatorio/{token}")
Call<JsonObject> uploadJson(#Path("token") String token, #Part("json") JsonObject auditoria, #Part List<MultipartBody.Part> files);
It always return error 400 due to SyntaxError: Unexpected token <br>;
However, if I send only the details as RequestBody it works.
I need to construct an array of images to upload as defined in my server; thus, I'm using it:
private List<MultipartBody.Part> prepare(){
Set<String> keys = JsonFormFragmentPresenter.imagesList.keySet();
List<MultipartBody.Part> parts = new ArrayList<>();
for(String k : keys){
for(String path : JsonFormFragmentPresenter.imagesList.get(k)){
if(!path.equals(null) && !path.equals("")){
File image = new File(path);
RequestBody requestFile = RequestBody.create(
MediaType.parse("multipart/form-data"), image
);
Log.e("Test", (requestFile == null) + "");
parts.add(MultipartBody.Part.createFormData("imagens", image.getName(), requestFile));
}
}
}
JsonFormFragmentPresenter.imagesList.clear();
return parts;
}
After that I make the call that is always returning 400:
Call<JsonObject> call = ApiClient.get().uploadJson(details.get(KEY_TOKEN), json, prepare());
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
Log.e("Status", new Gson().toJson(response));
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e("Status", "Faild");
Log.e("UPDATErr", new Gson().toJson(t));
}
});
Any hint on why it is not working?
Thank you,

You are using #Header annotation with Content-Type: application/json, but you need multipart POST request which uses different content type. Try to remove #Header annotation and replace it with #Multipart.

Related

Retrofit - Upload Image to S3 using presigned URL

I am getting the presigned URL from Lambda, but not sure why when I make a PUT request to that generated URL, my image is not being uploaded to S3.
I've followed these two answers exactly, but it's still not working for me
https://stackoverflow.com/a/46177449/11110509
https://stackoverflow.com/a/46579224/11110509
Could someone point out what I'm doing wrong?
public interface IUploadImages{
#PUT
Call<String> listRepos(#Url String url, #Body RequestBody image);
}
And my call to upload the image:
//Already checked to make sure mImageUri is not null
File file = new File(StringUtils.getPath(this, mImageUri));
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file);
RetrofitInterfaces.IUploadImages service = RetrofitClientInstance.getRetrofitInstance()
.create(RetrofitInterfaces.IUploadImages.class);
//Also checked to make sure mGeneraredUrl is also not null
Call<String> call = service.listRepos(mGeneratedUrl, requestFile);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful()){
Log.d(TAG, "onResponse: Success?");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d(TAG, "onFailure: Failed: " + t);
}
});
I've made the bucket public. The call is not failing, but in onResponse I'm getting a response code of 403.
Finally figured it out.. your presigned url function needs to have the same content type as
RequestBody.create(MediaType.parse("image/jpeg"), file);
So in my params
var params = {
Bucket: 'my-bucket-name',
Key: 'test-key',
Expires: signedUrlExpireSeconds,
ContentType: "image/jpeg"
};
Content type needs to be the same client side and in function side otherwise you get a 403 error...

how can I pass header using #Part in retrofit?

My interface is like this
#Multipart
#NonNull
#FormUrlEncoded
#POST("upload")
Call<GeneralResponse> uploadImage(#Header("Authorization") MultipartBody.Part token, #Part("image") MultipartBody.Part image, #Part("kilometer") MultipartBody.Part distance);
method for uploading image and data
public void upload(final String token,final String distance, final File image) {
InternetConnection internetConnection = new InternetConnection(TimeCard.this);
if (internetConnection.isConnectingToInternet()) {
showProgressDialog();
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
MultipartBody.Part bodykm;
RequestBody kilometer;
kilometer= RequestBody.create(MediaType.parse("text/plain"), distance);
bodykm =MultipartBody.Part.createFormData("kilometer", distance, kilometer);
Call<GeneralResponse> call = apiService.uploadImage(token,bodyImage,bodykm);
call.enqueue(new Callback<GeneralResponse>() {
#Override
public void onResponse(Call<GeneralResponse> call, final Response<GeneralResponse> response) {
try {
if(response.body().getStatus()){
meterImage = "";
distanceKm = "";
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}else {
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}
}catch (Exception e){
progressDialog.dismiss();
e.printStackTrace();
Toast.makeText(TimeCard.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<GeneralResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(TimeCard.this,"Server error please try again later",Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(TimeCard.this,"Please check your internet connection",Toast.LENGTH_LONG).show();
}
}
it gives error because only one type of annotation is allowed.so i change #Header to #Part
#Multipart
#NonNull
#FormUrlEncoded
#POST("upload")
Call<GeneralResponse> uploadImage(#Part("Authorization") MultipartBody.Part token, #Part("image") MultipartBody.Part image, #Part("kilometer") MultipartBody.Part distance);
now how can I pass header? (how to convert header to MultipartBody.Part?)
I'll start with answering your question
it gives error because only one type of annotation is allowed
Yes, it's intended behavior of Retrofit. You can not use multiple annotations at once. So, just remove #FormUrlEncoded annotation from uploadImage() method.
Now, you want post distance along with the image. For that you should use like below inside uploadImage() method (in service class).
#Part("kilometer") RequestBody distance // note: use RequestBody instead of MultipartBody.Part
And inside upload() function (in your Activity) do the changes.
RequestBody kilometer = RequestBody.create(MediaType.parse("text/plain"), distance);
Now come to the question
how can I pass header using #Part in retrofit?
I assume that you've dynamic authorization key (by looking into the sample code in question).
If you have dynamic Authorization key to be set to header at runtime, you could use Retrofit's #HeaderMap annotation.
Just do the below changes in uploadImage() method.
#HeaderMap Map<String, String> token
Inside Activity prepare header maps like below.
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
If you want set other header parameters, set it in the same headers hash map.
Then pass this header map to your uploadImage() method.
So, the final changes in your code goes like this.
Your service interface
#Multipart
#NonNull
#POST("upload")
Call<GeneralResponse> uploadImage(#HeaderMap Map<String, String> token, #Part("image") MultipartBody.Part image, #Part("kilometer") RequestBody distance);
and in Activity
public void upload(final String token,final String distance, final File image) {
InternetConnection internetConnection = new InternetConnection(TimeCard.this);
if (internetConnection.isConnectingToInternet()) {
showProgressDialog();
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
// prepare distance body
RequestBody kilometer = RequestBody.create(MediaType.parse("text/plain"), distance);
// prepare headers
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
Call<GeneralResponse> call = apiService.uploadImage(headers, bodyImage, kilometer);
call.enqueue(new Callback<GeneralResponse>() {
#Override
public void onResponse(Call<GeneralResponse> call, final Response<GeneralResponse> response) {
try {
if(response.body().getStatus()){
meterImage = "";
distanceKm = "";
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}else {
Toast.makeText(TimeCard.this,response.body().getMessage(),Toast.LENGTH_LONG).show();
}
}catch (Exception e){
progressDialog.dismiss();
e.printStackTrace();
Toast.makeText(TimeCard.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<GeneralResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(TimeCard.this,"Server error please try again later",Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(TimeCard.this,"Please check your internet connection",Toast.LENGTH_LONG).show();
}
}
Extra
If you've static token (token that never changes per user or API key), you don't need to use header map pattern here. Just skip #HeaderMap annotation/parameter. Make the changes like below.
#Headers("Authorization: your_token_key_here")
#Multipart
#NonNull
#POST("upload")
Call<GeneralResponse> uploadImage(#Part("image") MultipartBody.Part image, #Part("kilometer") RequestBody distance);
Again if you've more than one headers, enclose header parameters inside {} braces.
#Headers({
"Authorization: your_token_key_here",
"Content-Type: application/json", // just an example
"some other header here"
})
#Multipart
#NonNull
#POST("upload")
Call<GeneralResponse> uploadImage(#Part("image") MultipartBody.Part image, #Part("kilometer") RequestBody distance);

Upload video using retrofit2

I am trying to upload a video from android device to server using Retrofit2 and end up getting error '400 Bad Request'. Below is the implementation. Could somebody help to fix the error?
public interface RetrofitService {
/**
* Upload Videos to Server
*/
#Multipart
#POST("store/S3")
Call<ResponseBody> uploadToServer(#Query("key") String ServerAPI,
#Query("mimetype") String videoMimeType,
#Query("path") String path,
#Query("container") String container,
#Query("policy") String policy,
#Query("signature") String signature,
#Part MultipartBody.Part video,
#Part("type") String videoType,
#Part("name") String videoName );
}
Client implemetation in helper.java
private void uploadVideos(String videUri, String policy, String signature){
String BASE_URL = "https://www.example.com/api/";
String EXAMPLE_API_KEY = "xebfc";
String mimeType = "video/mp4";
String path = "mezzanine_videos/";
String container = S3_BUCKET;
// use the FileUtils to get the actual file by uri
File videoFile = new File(videoUri);
// create RequestBody instance from file
RequestBody videoBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
// MultipartBody.Part is used to send the actual file
MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody);
String videoType = "video/mp4";
String videoName = "video.mp4";
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
RetrofitService service = retrofit.create(RetrofitService.class);
Call<ResponseBody> call = service.uploadToServer( EXAMPLE_API_KEY, mimeType, path, container, policy, signature, vFile, videoType, videoName);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.d("Response", "Successful Response");
}
#Override
public void onFailure(Call call, Throwable t) {
Log.d("Response", "Failure Response");
}
}); }
Server implementation works fine because I get a valid response by doing a curl post like below.
curl -X POST -F fileUpload=#animation.mov "https://www.example.com/api/store/S3?key= xebfc&mimetype=video%2Fmp4&path=mezzanine_videos/&container= S3_BUCKET&policy=ppppp&signature=ssss
After some debugging on MultipartBody.Part.createFormData, figured out that the name was not matching with my backend implementation. Below code fixed the issue.
MultipartBody.Part vFile = MultipartBody.Part.createFormData("fileUpload", videoFile.getName(), fileBody);
Rest of the code is same as mentioned above.

Retrofit #body with #multipart having Issue

Image Multipart in class type object.
case 1. (Which I had done)
Service params:
{"id":"1","name":"vishal","image/file":""}
At that time my API of Retrofit
#Multipart
#POST("webservice")
Call<SignUpResp> loadSignupMultipart(#Part("description") RequestBody description, #Part MultipartBody.Part file, #QueryMap HashMap<String, String> params);
case 2. (Where I have Problem) with #Body class<UploadwithImage>
{
"methodName":"submitLevel1Part2Icon",
"userid":"150",
"headerData":{
"fiction":{
"icon_type":"1",
"icon_id":"3"},
"nonfiction":{
"icon_type":"2",
"icon_id":"4"},
"relation":{
"icon_type":"3",
"icon_id":"0",
"name":"Ronak",
"relative_image":"<File>",
"relation_id":"3"},
"self":{
"icon_type":"4",
"icon_id":"0"}
}
}
I am trying this API
#Multipart
#POST("webservice")
Call<SubmitLevel1Part2IconResp> loadLevel1halfIconswithImage(#Part("description") RequestBody description, #Part MultipartBody.Part file, #Body UploadwithImage uploadImage);
Java side
/**
* code for multipart
*/
// create RequestBody instance from file
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), fileUpload);
// MultipartBody.Part is used to send also the actual filename
MultipartBody.Part body = MultipartBody.Part.createFormData("methodName[headerData][relation][relative_image]", fileUpload.getName(), requestFile);
// add another part within the multipart request
String descriptionString = "hello, this is description speaking";
RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString);
call = service.loadLevel1halfIconswithImage(description, body, levelOneHalfIcons);
I don't know why but it returns error like:
"#Body parameters cannot be used with form or multi-part encoding"
Any Help would Be Appreciated.
Change your method to
#Multipart
#POST("users/{id}/user_photos")
Call<models.UploadResponse> uploadPhoto(#Path("id") int userId, #PartMap Map<String, RequestBody> params);
Now to create your request parameters,
//All the String parameters, you have to put like
Map<String, RequestBody> map = new HashMap<>();
map.put("methodName", toRequestBody(methodName));
map.put("userid", toRequestBody(userId));
map.put("relation", toRequestBody(relation));
map.put("icon_type", toRequestBody(iconType));
map.put("icon_id", toRequestBody(iconId));
map.put("name", toRequestBody(name));
map.put("relation_id", toRequestBody(relationId));
//To put your image file you have to do
File file = new File("file_name");
RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);
map.put("relative_image\"; filename=\"some_file_name.png\"", fileBody);
// This method converts String to RequestBody
public static RequestBody toRequestBody (String value) {
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), value);
return body ;
}
//To send your request
call = service.loadLevel1halfIconswithImage(description, params);
In case you do not want to use PartMap, you can simply pass them as parameters. Check my answer https://stackoverflow.com/a/37052548/1320616 to get some clue on sending image file with request.
As simple way, I have done like this:
I have tested by changing
Call<Result> resultCall = service.uploadImage(body);
to
Call<Result> resultCall = service.uploadImage(body, result); where result is
Result.java class (Response) of my API:
public class Result {
#SerializedName("result")
#Expose
private String result;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#SerializedName("value")
#Expose
private String value;
/**
* #return The result
*/
public String getResult() {
return result;
}
/**
* #param result The result
*/
public void setResult(String result) {
this.result = result;
}
}
and created object like:
Result result = new Result();
result.setResult("success");
result.setValue("my value");
You can change your class as per your need then pass object when you send request. So your ApiService class will be like:
ApiService.java
/**
* #author Pratik Butani on 23/4/16.
*/
public interface ApiService {
/*
Retrofit get annotation with our URL
And our method that will return us the List of Contacts
*/
#Multipart
#POST("upload.php")
Call<Result> uploadImage(#Part MultipartBody.Part file, #Part("result") Result result);
}
and My PHP code is:
<?php
$file_path = "";
$var = $_POST['result']; //here I m getting JSON
$file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) {
$result = array("result" => "success", "value" => $var);
} else{
$result = array("result" => "error");
}
echo json_encode($result);
?>
Hope it will helps you. Thank you.
You can also use a Map with RequestBody as value and string as keys to add parameters and you can send this using Multipart and PartMap.
Check the following code, hope it will help :
#Multipart
#POST("/add")
Call<ResponseBody> addDocument(#PartMap Map<String,RequestBody> params);
Map<String, RequestBody> map = new HashMap<>();
map.put("user_id", RequestBody.create(MediaType.parse("multipart/form-data"), SessionManager.getInstance().getCurrentUserId()));
map.put("doc_name", RequestBody.create(MediaType.parse("multipart/form-data"), CommonUtils.removeExtension(textFile.getName())));
map.put("doc_category", RequestBody.create(MediaType.parse("multipart/form-data"), category));
map.put("doc_image_file", RequestBody.create(MediaType.parse("multipart/form-data"), imageFile));
map.put("doc_text_content", RequestBody.create(MediaType.parse("multipart/form-data"), body));
map.put("doc_update_time", RequestBody.create(MediaType.parse("multipart/form-data"), "" + new Date(textFile.lastModified())));
We can add all request parameter in multipart body builder with specified type like in below one image file. I have set media type parse multipart/form-data and some other parameter I have set media type parse text/plain. This builder will build to make Multipart Body and can send by using body annotation in multipart body.
#Multipart
#POST("user/update")
Call<ResponseBody> addDocument(##Part MultipartBody file);
final MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
requestBodyBuilder.addFormDataPart("doc_image_file", imageFile.getName(),
RequestBody.create(MediaType.parse("multipart/form-data"), imageFile));
requestBodyBuilder.addFormDataPart("user_id", null, RequestBody.create(MediaType.parse("text/plain"),"12"));
requestBodyBuilder.addFormDataPart("doc_name", null, RequestBody.create(MediaType.parse("text/plain"),"myfile"));
requestBodyBuilder.addFormDataPart("doc_category", null, RequestBody.create(MediaType.parse("text/plain"),category));
requestBodyBuilder.addFormDataPart("doc_image_file", imageFile.getName(),RequestBody.create(MediaType.parse("multipart/form-data"),imageFile));
requestBodyBuilder.addFormDataPart("doc_text_content", null, RequestBody.create(MediaType.parse("text/plain"),body));
RequestBody multipartBody = requestBodyBuilder.build();
Here is my json request format is :
{
"task":{
"category_id":"1",
"price":"10",
"description":"1",
"task_videos_attributes":[
{
"link":"video file goes here",
"size":"100x100"
}
]
}
}
// my request becomes
HashMap<String, RequestBody> task = new HashMap();
task.put("task[category_id]", createPartFromString(categoryId));
task.put("task[price]", createPartFromString("" + etPrice.getText().toString()));
task.put("task[description]", createPartFromString("" + etDescription.getText().toString()));
// for videos file list
final List<MultipartBody.Part> body = new ArrayList<>();
for (int i = 0; i < videos.size(); i++) {
task.put("task[task_videos_attributes][" + i+ "][size]", createPartFromString("100x100"));
File videoFile = new File(videos.get(i));
RequestBody requestBody = RequestBody.create(MediaType.parse("video/mp4"), videoFile);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("task[task_videos_attributes][" + i + "][link]", videoFile.getName(), requestBody);
body.add(fileToUpload);
}
// here is a final call
new RestClient(this).getInstance().get().postTask(body, task).enqueue(callback);
// This function converts my string to request body
#NonNull
private RequestBody createPartFromString(String descriptionString) {
if (descriptionString == null)
return RequestBody.create(MultipartBody.FORM, "");
return RequestBody.create(
MultipartBody.FORM, descriptionString);
}
Hope this helps you...
Just follow how the web browser is doing multipart. They put nested keys in "[]" and give key to the images too.
Call<SubmitLevel1Part2IconResp> loadLevel1halfIconswithImage(#Part("headerdata[relation][icon_type]") RequestBody icon_type, #Part("headerdata[relation][name]") RequestBody name, #Part MultipartBody.Part file);
And then in java
// MultipartBody.Part is used to send also the actual filename
MultipartBody.Part body = MultipartBody.Part.createFormData("headerdata[relation][relative_image]", fileUpload.getName(), requestFile);
call = service.loadLevel1halfIconswithImage(icon_type, name, body);
https://www.linkedin.com/pulse/retrofit-2-how-upload-multiple-files-server-mahesh-gawale
I guess the best answer to this question can be found here. It worked perfectly for me.
This is the example of uploading an array of files using retrofit in Android.
This is how the service will look like
public interface ApiService {
#POST("/event/store")
Call<ResModel> event_store(#Body RequestBody file);
}
This is how the Client class look like
public class ApiClient {
public static final String API_BASE_URL = "api base url";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder = new Retrofit.Builder().baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create());
public static ApiService createService(Class<ApiService> serviceClass)
{
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}
Upload like this in activity or fragment or where you want
ApiService service = ApiClient.createService(ApiService.class);
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("event_name", "xyz");
builder.addFormDataPart("desc", "Lorem ipsum");
// Single Image
builder.addFormDataPart("files",file1.getName(),RequestBody.create(MediaType.parse("image/*"), file1));
// Multiple Images
for (int i = 0; i <filePaths.size() ; i++) {
File file = new File(filePaths.get(i));
RequestBody requestImage = RequestBody.create(MediaType.parse("multipart/form-data"), file);
builder.addFormDataPart("event_images[]", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file));
}
MultipartBody requestBody = builder.build();
Call<ResModel> call = service.event_store(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Toast.makeText(getBaseContext(),"All fine",Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
Note: filePaths.size() is a Arraylist of pickup Images Paths.
I hope this post is useful to you. kindly share your feedback as a comment here.
this works for me.
What I did was add every additional params using:
MultipartBody.Part Partname = MultipartBody.Part.createFormData("ParamName", "Value");
Mabe you don't need to create another body, but just add others params apart from the file or whatever you are sending. finally at the interface I put as a params every bodypart that I need.
#Multipart
#POST("api/service/uploadVideo")
Call<ResponseBody> uploadVideoToServer(
#Part MultipartBody.Part video,
#Part MultipartBody.Part param2,
#Part MultipartBody.Part param3 ....
);

Multipart Retrofit 2.0 image upload

I am trying to upload image by POST multipart request which should have structure like this :
-----------------------------219391268715340
Content-Disposition: form-data; name="photos[]"; filename="DSCF0157-Laptop.JPG"
Content-Type: image/jpeg
(byte-data)
My code :
MediaType mediaType = MediaType.parse("image/jpeg");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
RequestBody file=RequestBody.create(mediaType, byteArray);
map.put("form-data; name=\"photos[]\"; filename=\""+filename+".jpg",file);
I use map because of #PartMap annotation - I want to upload multiple files. My server returns http code 200 - but no files are uploaded. Api call has been tested - it works correctly if used by our web application. Any idea what I am doing wrong
If you want to upload many files in a request using Retrofit 2, you can refer to my answer at the question below
Retrofit - Multipart request: Required MultipartFile parameter 'file' is not present
With some modifications:
WebAPIService.java:
#Multipart
#POST("/api/fileupload")
Call<ResponseBody> postFiles(#Part List<MultipartBody.Part> fileList);
FileActivity.java:
...
List<MultipartBody.Part> fileList = new ArrayList<>();
for (int i = 0; i < 2; i++){
fileList.add(body);
}
Call<ResponseBody> call = service.postFiles(fileList);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
Log.i(LOG_TAG, "success");
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(LOG_TAG, t.getMessage());
}
});
Of course, with the above code, in fact, the same file (body) will be uploaded as 2 parts in the request. As a result, in web server, you will have 2 files with the same content, you can customize the fileList with many different files :)
Hope it helps!
Maybe you can do that like this.
YourAPIService
#Multipart
#POST("api/image/upload")
Call<ImageUploadResponse> uploadImage(#Part("photos") List<RequestBody> imageFiles);
YourActivity
//prepare request body
List<RequestBody> images = new ArrayList<>();
for (int i = 0; i < filePath.size(); i++){
RequestBody file = RequestBody.create(MediaType.parse("image/*"), filePath.get(i);
images.add(file);
}
//call api
Call<ImageUploadResponse> call = imageUploadService.uploadImage(images);
call.enqueue(new Callback<ImageUploadResponse>() {
#Override
public void onResponse(Call<ImageUploadResponse> call,
Response<ImageUploadResponse> response) {
}
#Override
public void onFailure(Call<ImageUploadResponse> call, Throwable t) {
}
});

Categories

Resources