Reputation: 1105
I am trying to post images to the server. Here are my php variable names on the server side provided to me by scriptor:
$value1 = $_POST["value1"]; // string value
$value2 = $_POST["value2"]; // string value
$img_1 = $_FILES["fileToUpload1"]["name"]; // image file
$img_2 = $_FILES["fileToUpload2"]["name"]; // image file
and here is my code for posting the values -
RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), path.toString());
RequestBody fileBody1 = RequestBody.create(MediaType.parse("image/png"), path.toString());
Call<uploadResponseModel> call = adapter.uploadValues("test1","test2",fileBody1,fileBody);
call.enqueue(new Callback<uploadResponseModel>() {
@Override
public void onResponse(Response<uploadResponseModel> response, Retrofit retrofit) {
Log.i("TAG", "retro onResponse :" + response.body().getResponse().getStatus());
}
@Override
public void onFailure(Throwable t) {
Log.i("TAG", "retro onFailure :" + t.getCause());
}
});
adapter class:
public interface RetrofitAdapter {
@Multipart
@POST("/TestApp/img_upload.php")
Call<uploadResponseModel> uploadValues(@Part("value1")String value1,@Part("value2")String value2,@Part("fileToUpload1") RequestBody file1,@Part("fileToUpload2") RequestBody file2);
}
Both string values are getting posted on the server, but not the images. Please correct me if i am wrong anywhere in posting image files. I am new to retrofit.
Upvotes: 2
Views: 1541
Reputation: 76
As per your question, the variable that your server expects as the two images(files) are fileToUpload1
and fileToUpload2
. The reason why the images are'nt getting uploaded are because of the syntax you have specified in your RetrofitAdapter
.
You will have to change your RetrofitAdapter
to:
public interface RetrofitAdapter {
@Multipart
@POST("/TestApp/img_upload.php")
Call<uploadResponseModel> uploadValues(@Part("value1")String value1,@Part("value2")String value2,@Part("fileToUpload1\"; filename=\"image\" ") RequestBody file1,@Part("fileToUpload2\"; filename=\"image\" ") RequestBody file2);
}
@Part("fileToUpload1\"; filename=\"image\" ") RequestBody file1
The server expects the file with the variable name fileToUpload1
and fileToUpload2
which has to be posted along with a file name in the above format. You could refer the solution here as well click here
Do this and you are good to go :)
Upvotes: 6
Reputation: 1
There are some issues with multipart file upload with retrofit @Multipart
tag.
Solved the issue using the @POST
tag, with custom multipart builder in request body.
@POST ("userwebservices/app_upload_pic")
Call<APIRespone> uploadUserImages ( @Body RequestBody file );
Code for multipart upload by passing image file path getting from android app.
File file = new File(filePath);
MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data;name=\"uploaded_file\";filename=\"" + filePath + "\""),
RequestBody.create(MEDIA_TYPE_IMAGE, file))
.build();
Here uploaded_file
is the checking string in the PHP script.
Upvotes: -1
Reputation: 1006
This is my service method for multipart file upload:
@Multipart
@POST("http://....")
Call<UploadResponse> uploadPicture(@PartMap Map<String,RequestBody> pic1, @PartMap Map<String, RequestBody> pic2);
And how to call it:
public void uploadPicture(File pic1, File pic2) {
Map<String, RequestBody> pic1Map = new HashMap<>();
Map<String, RequestBody> pic2Map = new HashMap<>();
RequestBody rb1 = RequestBody.create(MediaType.parse("image/*"), pic1);
RequestBody rb2 = RequestBody.create(MediaType.parse("image/*"), pic2);
pic1Map.put("file\"; filename=\"" + pic1.getName(), rb1);
pic2Map.put("file\"; filename=\"" + pic2.getName(), rb2);
Call<UploadResponse> call = apiClient.getAPIService().uploadPicture(pic1Map, pic2Map);
call.enqueue...
}
Some backends require the filename header parameter, that's why i use @PartMap
this way. OkHttp's multipart builder does not set it.
Upvotes: 2
Reputation: 11112
I think the method to sent normal string and file is different.
you should use
@Part("file\"; filename=\"fileToUpload1.png\"") RequestBody file1
instead of
@Part("fileToUpload1") RequestBody file1
or if you want to be specific
@Part("image\"; filename=\"fileToUpload1.png\"") RequestBody file1
Upvotes: 0
Reputation: 32016
You are calling the wrong create
method of RequestBody
. You are passing a string, which uses the string as the content. You need to be passing a File
. It is not clear what type your path
variable is. If it is already a File
, use it. Otherwise, create a file and pass that to create
--
File image = new File(path.toString());
RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), image);
do the same for fileBody1
.
Upvotes: 0
Reputation: 4853
Instead of RequestBody just use RequestBody. Fix method uploadValues
in Retrofit interface:
public interface RetrofitAdapter {
@Multipart
@POST("/TestApp/img_upload.php")
Call<uploadResponseModel> uploadValues(@Part("value1")String value1,@Part("value2")String value2,@Part("fileToUpload1") TypedFile file1,@Part("fileToUpload2") TypedFile file2);
}
And fix your request service:
TypedFile file1 = new TypedFile("application/octet-stream", new File(path1));
TypedFile file2 = new TypedFile("application/octet-stream", new File(path2));
Call<uploadResponseModel> call = adapter.uploadValues("test1","test2",file1,file2);
call.enqueue(new Callback<uploadResponseModel>() {
@Override
public void onResponse(Response<uploadResponseModel> response, Retrofit retrofit) {
Log.i("TAG", "retro onResponse :" + response.body().getResponse().getStatus());
}
@Override
public void onFailure(Throwable t) {
Log.i("TAG", "retro onFailure :" + t.getCause());
}
});
Upvotes: 0