upload an image using retrofit with multipart - android

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

Related

Why can't I upload an image and data with retrofit2?

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"

Android - Retrofit - File Uploaded to AWS S3 with pre-signed url is corrupt

In my application, I need to upload images directly to AWS S3. For this my server generates a pre-signed url and mobile client use that url to PUT file on. Though getting 200 in upload call, the file is not uploaded correctly i.e. it's corrupt and never loads back.
Following is the code being used to upload file to S3.
public static interface FileUploadService {
#PUT("/")
void upload(#Body() RequestBody body,
Callback<Object> callback);
}
ServiceGenerator.getUploadService(url).upload(
RequestBody.create(MediaType.parse("image/jpeg"), image),
new Callback<Object>() { });
I'm using Retrofit 1.8.
Hello Try this if it helps but I used Retrofit 2,
Gradle
compile 'com.squareup.retrofit2:retrofit:2.0.2'
The Interface
public static interface FileUploadService {
#Multipart
#POST(HttpConstants.FILEUPLOADJSON1)
Call<Result> uploadImage(#Part MultipartBody.Part file, #Part("stdID") int stdID);
}
The Call
RaytaApi service= RaytaServiceClass.getApiService();
File file = new File(imagePath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("uploaded_file", file.getName(), requestFile);
Call<Result> resultCall=service.uploadImage(body,INT_STDID);
final Result[] result = {new Result()};
resultCall.enqueue(new Callback<Result>() {
#Override
public void onResponse(Call<Result> call, Response<Result> response) {
Log.v("###WWE","Respnse");
}
}
#Override
public void onFailure(Call<Result> call, Throwable t) {
Log.v("###WWE","Failure ");
Log.v("###WWE","MEssage "+t.getMessage());
}
});
For complete example referance please visit
https://github.com/pratikvyas1991/NetworkingExample-master
Fixed as following;
When using RequestBody, the Content-Length header was not carrying the correct info neither I was able to override it. So, I used TypedInput instead of RequestBody. My service interface looks like following.
public static interface FileUploadService {
#PUT("/")
void upload(#Body TypedInput body, Callback<Object> callback);
}
And image is uploaded as;
ServiceGenerator.getUploadService(url).upload(new TypedFile("image/*", file),
new Callback<Object>() { });

is it possible to pass a single item as multipart using retrofit?

#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();
}
});

Send image with Retrofit2

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.

Send json and file with Retrofit2

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

Categories

Resources