Reboot @body with @multipart having a problem

Multiplayer Image in an object of type class.

case 1. (What I did)

Service Parameters:

{"id":"1","name":"vishal","image/file":""} 

At this 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 a 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'm trying to make 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 do not know why, but it returns an error, for example:

"@ Body parameters cannot be used with form or multi-part encoding"

Any help would be appreciated.

+8
android annotations retrofit2
source share
7 answers

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 query 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); 

If you do not want to use PartMap, you can simply pass them as parameters. Check my answer fooobar.com/questions/838187 / ... to find out how to send the image file with the request.

+9
source share

As an easy way, I did like this:

I checked by changing

 Call<Result> resultCall = service.uploadImage(body); 

in

Call<Result> resultCall = service.uploadImage(body, result); where is the result

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 the created object, like:

 Result result = new Result(); result.setResult("success"); result.setValue("my value"); 

You can change your class to suit your needs, and then pass the object when sending the request. So your ApiService class will look like this:

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 this:

 <?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 this helps you. Thanks.

+9
source share

You can also use Map with RequestBody as a value and a string as keys to add parameters, and you can send this using Multipart and PartMap .

Check out the following code, hope it helps:

 @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()))); 
+3
source share

We can add all request parameters to multipart body builder with the specified type, as shown below in a single image file. I set the parsing type multipart/form-data , and the other parameter I set is the markup of the text/plain file type. This builder will build to make a Multipart Body and can send using body annotations in a 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(); 
+2
source share

Just follow the instructions that make your web browser. They put nested keys in "[]" and also give a key to the images.

 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); 
0
source share
 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 ...

0
source share

https://www.linkedin.com/pulse/retrofit-2-how-upload-multiple-files-server-mahesh-gawale

I think the best answer to this question can be found here. This worked great for me.

This is an example of loading an array of files using retrofit in Android.

This is how the service will look

 public interface ApiService { @POST("/event/store") Call<ResModel> event_store(@Body RequestBody file); } 

This is what the Client class looks 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); } } 

Download like this in an exercise or fragment or wherever 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() - Arraylist from Paths Images. I hope this post will be useful to you. Please share your opinion as a comment here.

0
source share

All Articles