I used to send POST request to server with Retrofit2:
#POST("goals")
Call<Void> postGoal(#Body Goal goal);
where Goal was object with some String/Integer fields.
Now I need to add a photo file there.
I know I need to switch to use Multipart:
#Multipart
#POST("goals")
Call<Void> postGoal(
#Part("picture") RequestBody picture
);
//...
//Instantaining picture
RequestBody.create(MediaType.parse("image/*"), path)
But how am I supposed to add previous fields ? In particular is there a way to add whole Goal object without dividing it for fields ?
for sending json and file you can follow something like this.
#Multipart
#POST("goals")
Call<JsonModel> postGoal(#Part MultipartBody.Part file, #Part("json") RequestBody json);
Now convert your Object which you want to send as a json into json using Gson.
like this.
String json = new Gson().toJson(new Goal());
File file = new File(path);
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", file.getName(), requestFile);
// add another part within the multipart request
RequestBody jsonBody=
RequestBody.create(
MediaType.parse("multipart/form-data"), json);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RestApi api = retrofit.create(RestApi.class);
Call<ResponseBody> call = api.upload(jsonBody, body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.d("onResponse: ", "success");
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("onFailure: ", t.getLocalizedMessage());
}
});
You can add #Part with you goal like this
#Multipart
#POST("goals")
Call<Void> postGoal(
#Part("picture") RequestBody picture,
#Part("goal") RequestBody goal
);
//...
//Instantaining picture
RequestBody.create(MediaType.parse("image/*"), path)
You can find more details : retrofit-2-how-to-upload-files-to-server
Related
Regards, I have to upload this data.
postman
And I have this code.
Customer Creation
public BeeMappingClient(String url){
retrofit= new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
conexion=retrofit.create(Conexion.class);
}
Interface
#Multipart
#POST("task")
Call<ResponsetTask> API_Task(#Header("Authorization") String key,
#Part MultipartBody.Part multipartImage,
#Part("message") RequestBody message ,
#Part("filecomment") RequestBody filecomment,
#Part("api_token") RequestBody api_token,
#Part("user_id") RequestBody user_id);
And call
File file=new File(path);
MultipartBody.Part[] multipartImageList = new MultipartBody.Part[1];
RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file);
multipartImageList[0] = MultipartBody.Part.createFormData("image", "image.jpg", surveyBody);
RequestBody message = RequestBody.create(MediaType.parse("message"), Constantes.MESSAGE);
RequestBody filecomment = RequestBody.create(MediaType.parse("filecomment"), Constantes.FILECOMMENT);
RequestBody api_token = RequestBody.create(MediaType.parse("api_token"),Constantes.api_token);
RequestBody user_id = RequestBody.create(MediaType.parse("user_id"), Integer.toString(Constantes.id));
Call<ResponsetTask> call = conexion.API_Task(Constantes.AUTH,multipartImageList[0],message,filecomment,api_token,user_id);
call.enqueue(new Callback<ResponsetTask>() {
#Override
public void onResponse(Call<ResponsetTask> call, Response<ResponsetTask> response) {
Constantes.api_task=response.body().getTaskId();
}
#Override
public void onFailure(Call<ResponsetTask> call, Throwable t) {
}
});
The problem is that it does nothing, if I do a debug all seems to be going well until it reaches the call.enqueu ... there I should enter OnResques or OnFailure but it does not just go to the end of the method as if it did not exist .
What should I do ?, this is the best method to upload this data ?.
I thank you in advance for any help or guidance you can give me.
Try this - for multipart request
In interface
#Multipart
#POST("task")
Call<ResponseBody> submitRegistration(#Part MultipartBody.Part body,
#Part("message") RequestBody message)
Pass values -
File file = new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
RequestBody message = RequestBody.create(MediaType.parse("text/plain"), Constantes.MESSAGE);
Call -
Call<ResponseBody> call = service.callApi(body,message);
RequestBody surveyBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
Replace "image/*" with "multipart/form-data"
#Multipart
#POST("/api/add-deal/")
public void addDeal(#Body Deal deal, #Part("image")TypedFile image,Callback<Response> callback);
I want to send only the image as multipart and the rest as is.Is there any possible way ? Even I tried to add TypedFile inside my Deal model but unable to annotate with #part
Yes, it is possible with Partmap annotation using hash map. For example-
#Multipart
#POST("/api/add-deal/")
Call<Response> addDeal(#PartMap
HashMap<String, RequestBody> hashMap);
In hashMap you can add no of url parameters as key and set your values using RequestBody class type. see how to convert String and Image to RequestBody.
public static RequestBody ImageToRequestBody(File file) { //for image file to request body
return RequestBody.create(MediaType.parse("image/*"),file);
}
public static RequestBody StringToRequestBody(String string){ // for string to request body
return RequestBody.create(MediaType.parse("text/plain"),string);
}
add params to hashmap-
hashMap.put("photo",ImageToRequestBody(imageFile)); //your imageFile to Request body.
hashMap.put("user_id",StringToRequestBody("113"));
//calling addDeal method
apiInterface.addDeal(hashMap);
Hope this helpful.
It seems that you can send your #Body as TypedString.
For example, convert your "#Body Deal deal" into JSON String, and send it as TypedString.
Details: How to send multipart/form-data with Retrofit?
#Multipart
#POST("/api/v1/articles/")
Observable<Response> uploadFile(#Part("author") TypedString authorString,
#Part("photo") TypedFile photoFile);
This worked for me: POST Multipart Form Data using Retrofit 2.0 including image
public interface ApiInterface {
#Multipart
#POST("/api/Accounts/editaccount")
Call<User> editUser (#Header("Authorization") String authorization, #Part("file\"; filename=\"pp.png\" ") RequestBody file , #Part("FirstName") RequestBody fname, #Part("Id") RequestBody id);
}
File file = new File(imageUri.getPath());
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), firstNameField.getText().toString());
RequestBody id = RequestBody.create(MediaType.parse("text/plain"), AZUtils.getUserId(this));
Call<User> call = client.editUser(AZUtils.getToken(this), fbody, name, id);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(retrofit.Response<User> response, Retrofit retrofit) {
AZUtils.printObject(response.body());
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
I'm trying to upload an image to the server using Retrofit2, but am very unsure on how to do so.
The documentation left me a bit confused and I have tried the solution mentioned here, but it did not work for me.
Here is the code snippet I'm currently using, which doesn't send anything to the server:
// Service
#Multipart
#POST("0.1/gallery/{galleryId}/addImage/")
Call<ResponseBody> addImage(#Path("galleryId") String galleryId, #Part MultipartBody.Part image);
//Call
MultipartBody.Part imagePart = MultipartBody.Part.createFormData("image", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
Call<ResponseBody> call = service. addImage("1234567890", imagePart);
However, I'm able to do it just fine using Retrofit 1.9 with a TypedFile.
Am I doing something wrong or Retrofit2 has some issue with this sort of thing?
I've struggled for a while with this to, I ended up with this solution to finally make it work... Hopes it helps:
Map<String, RequestBody> map = new HashMap<>();
map.put("Id",Utils.toRequestBody("0"));
map.put("Name",Utils.toRequestBody("example"));
String types = path.substring((path.length() - 3), (path.length()));
File file = new File(pathOfYourFile);
RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpg"), file);
map.put("file\"; filename=\"cobalt." + types + "\"", fileBody);
Call<ResponseBody> call = greenServices.upload(map);
In the greenServices interface:
#Multipart
#POST(Constants.URL_UPLOAD)
Observable<Response<ResponseBody>> uploadNew(#PartMap Map<String, RequestBody> params);
hi please check how we can send image in retrofit2.In form of part you need to send image and other data as well.
public interface ApiInterface {
#Multipart
#POST("0.1/gallery/{galleryId}/addImage/")
Call<User> checkapi (#Part("file\"; filename=\"pp.png\" ") RequestBody file , #Part("FirstName") RequestBody fname, #Part("Id") RequestBody id);
}
File file = new File(imageUri.getPath());
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), firstNameField.getText().toString());
RequestBody id = RequestBody.create(MediaType.parse("text/plain"), AZUtils.getUserId(this));
Call<User> call = client.editUser(AZUtils.getToken(this), fbody, name, id);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(retrofit.Response<User> response, Retrofit retrofit) {
AZUtils.printObject(response.body());
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
Thanks hope this will help you.
I'm trying to upload a file (picture) to the server using Retrofit 2. I'm following that tutorial which seems pretty easy at first, but didn't work in my case...
When I call the API function, i'm always getting this error:
W/System.err: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
W/System.err: at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:190)
W/System.err: at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166)
W/System.err: at retrofit2.Retrofit$1.invoke(Retrofit.java:145)
W/System.err: at java.lang.reflect.Proxy.invoke(Proxy.java:393)
W/System.err: at com.plante.android.cobalt.fragment.FragmentIncidentPlan.uploadFile(FragmentIncidentPlan.java:575)
Here is my API call:
#Multipart
#POST(Constants.URL_UPLOAD)
Call<ResponseBody> upload(#Part RequestBody description,
#Part MultipartBody.Part file);
Here is the method I use to upload a file:
private void uploadFile(String path) {
// create upload service client
// use the FileUtils to get the actual file by uri
File file = new File(path);
Log.e(TAG, file.getAbsolutePath());
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", file.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);
// finally, execute the request
Call<ResponseBody> call = cobaltServices.upload(description, body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
Log.v("Upload", "success");
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
}
The Exceptions says that the first #Part doesn't needs a name in the annotation.
#Multipart
#POST(Constants.URL_UPLOAD)
Call<ResponseBody> upload(#Part RequestBody description,
#Part MultipartBody.Part file);
I fix my issue using this link : https://github.com/square/retrofit/issues/1063#issuecomment-145920568
This is the solution of the problem:
#Multipart
#POST ("/api/Events/editevent")
Call<Event> editEvent (#PartMap Map<String, RequestBody> params);
I call it by following way.
Map<String, RequestBody> map = new HashMap<>();
map.put("Id", AZUtils.toRequestBody(eventId));
map.put("Name", AZUtils.toRequestBody(titleView.getValue()));
if (imageUri != null) {
File file = new File(imageUri.getPath());
RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);
map.put("file\"; filename=\"pp.png\"", fileBody);
}
Call<Event> call = api.editEvent(map);
call.enqueue(new Callback<Event>() { }
The method toRequestBody just converts String into RequestBody
public static RequestBody toRequestBody (String value) {
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), value);
return body ;
}
I'm trying to upload an image along with a pojo model with username and password, but how do i use the multipart to add both, here is my code but isn't working:
EndpointInterface loginService = ServiceAuthGenerator.createService(EndpointInterface.class);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
Call<String> call = loginService.singup(requestBody,us);
call.enqueue(new Callback<String>() {#Override
public void onResponse(Response<String> response, Retrofit retrofit) {
}
#Override
public void onFailure(Throwable t) {
}
});
us is my pojo model and it contains the user and the password.
this is the API interface:
#Multipart
#POST("reg/")
Call<String> singup(
#Part("myfile\"; filename=\"image.png\" ") RequestBody file,
#Part("User") User user);
can anyone explain what im doing wrong and how to fix it please?
Should you use MediaType.parse("image/*") instead MediaType.parse("multipart/form-data")? It is because you upload image later.
You might be better off using the multipart builder for the request body than the #Multipart annotation.
RequestBody body = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("myFile", "image.png", RequestBody.create(MediaType.parse("image/jpg"), new File(picture.getLocalPath())))
.addFormDataPart("user", gson.toJson(user))
.build();
#POST("reg/")
Call<String> singup(#Body RequestBody image);