Retrofit 2 : send files with json object - android

I'm sending object in request body, something like that :
{
"title":"test",
"description":"test",
"images":[]
}
#POST("create-data")
Call<JsonObject> publishData(#Body MyObject object);
and it's work fine without the images. From the docs I can find how to upload file to server using MultipartBody.Part, my questions is :
How can I upload multiple images at the same time?
Is it possible to send the images inside the object, or I need to send it separately and how ?
thank you very much.

request success just now with server
I reference the article:
https://futurestud.io/blog/retrofit-2-how-to-upload-files-to-server
#Multipart
#POST("uploadHeadPic")
Call<UploadHeadPicResponseModel> uploadHeadPic(#Part MultipartBody.Part file, #Part("json") RequestBody json);
public void doUploadHeadPic(#NonNull String filePath) {
if (!MNetworkUtil.isNetworkAvailable()) {
MToastUtil.show("网络不能连接");
return;
}
File file = new File(filePath);
String json = new Gson().toJson(new UploadHeadPicRequestModel());
if (!file.exists()) {
MToastUtil.show("文件不存在");
return;
}
progressDialog.show();
avatarSimpleDraweeView.setEnabled(false);
MApiManager.getService().uploadHeadPic(
MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file)),
RequestBody.create(MediaType.parse("multipart/form-data"), json))
.enqueue(new OnRetrofitCallbackListener<UploadHeadPicResponseModel>(mActivity) {
#Override
public void onSuccess(UploadHeadPicResponseModel responseModel) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
if (responseModel != null) {
String serverAvatarUrl = responseModel.data.headPicPath;
if (!TextUtils.isEmpty(serverAvatarUrl)) {
UserModel userModel = MUserManager.getInstance().getUser();
if (userModel != null) {
userModel.setAvatarUrl(serverAvatarUrl);
MUserManager.getInstance().updateOrInsertUserInfo(userModel);
MToastUtil.show("上传头像成功");
}
}
}
}
#Override
public void onFailure(int status, String failureMsg) {
progressDialog.dismiss();
avatarSimpleDraweeView.setEnabled(true);
MToastUtil.show((TextUtils.isEmpty(failureMsg) ? "上传失败" : failureMsg) + " : " + status);
}
});
}
update for multi files
may be this could help , I did not try
#Multipart
#POST("uploadHeadPic")
Call<UploadHeadPicResponseModel> uploadHeadPic(#Part MultipartBody.Part file0, #Part MultipartBody.Part file1, #Part("json") RequestBody json);
public void doUploadHeadPic(#NonNull String filePath) {
MApiManager.getService().uploadHeadPic(
MultipartBody.Part.createFormData("file0", file0.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file0)),
MultipartBody.Part.createFormData("file1", file1.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file1)),
RequestBody.create(MediaType.parse("multipart/form-data"), json))
.enqueue(new OnRetrofitCallbackListener<UploadHeadPicResponseModel>(mActivity) {
#Override
public void onSuccess(UploadHeadPicResponseModel responseModel) {
}
#Override
public void onFailure(int status, String failureMsg) {
}
});
}

In my case (uploading to server built with Spring) I needed to change MediaType for RequestBody:
RequestBody.create(MediaType.parse("application/json"), json)
RequestBody.create(MediaType.parse("image/jpg"), file)

Related

Android Image Uploading on Localhost but not on online server

I am building a Laravel-based API. In the project, I want to upload image using post method to the API server
the image file is uploading on localhost database but when I try to upload the image on online server which is namecheap there image error code is 405.
I wasted 2 days but I don't now what is the error.
Please anyone can help me.
Thanks in advance
Here is android code
#Multipart
#POST("update-client")
Call<CustomerModel> update_user(#Part("id") RequestBody id,
#Part("name") RequestBody name, #Part("address") RequestBody address,
#Part("user_op_phone") RequestBody city,
#Part MultipartBody.Part file,
#Part("avatar") RequestBody image);
public void update_user_info(String name,String address,String no){
progressDialog.show();
RequestBody requestFile = null;
MultipartBody.Part body = null;
if(file!=null && file.length()>0) {
requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
body =
MultipartBody.Part.createFormData("avatar", file.getName(), requestFile);
}
RequestBody p_id = RequestBody.create(MediaType.parse("text/plain"),appSessionManager.getUserId());
RequestBody p_name = RequestBody.create(MediaType.parse("text/plain"),name);
RequestBody p_address = RequestBody.create(MediaType.parse("text/plain"),address);
RequestBody p_no = RequestBody.create(MediaType.parse("text/plain"),no);
Call<CustomerModel> call1 = apiPHP.update_user(body,requestFile);
call1.enqueue(new Callback<CustomerModel>() {
#Override
public void onResponse(Call<CustomerModel> call, Response<CustomerModel> response) {
progressDialog.dismiss();
// VendorModel user1 = response.body();
if(response.errorBody()==null){
// if(response.code()==201) {
Toast.makeText(getApplicationContext(), response.body().message, Toast.LENGTH_LONG).show();
// }
}
}
#Override
public void onFailure(Call<CustomerModel> call, Throwable t) {
Toast.makeText(getApplicationContext(),t.getMessage() , Toast.LENGTH_SHORT).show();
call.cancel();
}
});
}
Laravel Api routes is
Route::post("update-client", "Client\ClientController#updateClient");

File upload using retrofit android?

I am trying to upload a video file using multipart by retrofit and I get the following error in response
Response{protocol=http/1.1, code=405, message=Method Not Allowed, url=serverurl/Upload/Videos/}
This is my code for file upload
void uploadVideo(String videoPath) {
dialog.show();
File videoFile = new File(videoPath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), videoPath);
MultipartBody.Part vFile = MultipartBody.Part.createFormData("file", videoFile.getName(), requestFile);
apiCall.uploadVideoToServer(presenter.getUserInfo().getUploadVideoPath(), vFile).enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
dialog.dismiss();
}
#Override
public void onFailure(Call<String> call, Throwable t) {
dialog.dismiss();
}
});
}
This is the path I am uploading the file to
http://serverurl.com/Upload/Videos/
Can someone tell me whats wrong with my code?
Retrofir API interface
#Multipart
#POST
Call<String> uploadVideoToServer(#Url String url, #Part MultipartBody.Part video);
in your api service interface :
#Multipart
#POST("Upload/Videos") // *** DONT FORGET UR END POINT HERE ***
Call<urmodel> uploadVideoToServer(#PartMap Map<String, RequestBody> map);
and write a method to upload ur video file like this :
private void uploadVideoToServer(String path) {
File videoFile = new File(path);
if (videoFile.exists()) {
//create request body
Map<String, RequestBody> map = new HashMap<>();
RequestBody requestBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
map.put("video\"; filename=\"" + videoFile.getName() + "\"", requestBody);
//make call
Call<urmodel> call = mTService.uploadVideoToServer(map);
call.enqueue(new Callback<urmodel>() {
#Override
public void onResponse(Call<urmodel> call, Response<urmodel> response) {
if (response.isSuccess()) {
// DO SOMETHING
} else {
// DO SOMETHING
}
}
#Override
public void onFailure(Call<urmodel> call, Throwable t) {
//occur when fail to deserialize || no network connection || server unavailable
Toast.makeText(getBaseContext(), "Fail it >> " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(getBaseContext(), "can not upload file since the file is not exist :|", Toast.LENGTH_SHORT).show();
}
}

Bad request while sending multpart image through retrofit 2.1.0

private void saveImageToServer(final String savedpath) {
showLoader();
NetworkUtil.checkInternetConnection(DetailActiveSRActivity.this, new NetworkUtil.NetworkStatusListener() {
#Override
public void onNetworkAvailable() {
File file = new File(savedpath);
// RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), savedpath);
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
Log.e(TAG, "onNetworkAvailable: requestFIle " + savedpath+"\n"+" file "+file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
Log.e(TAG, "onNetworkAvailable: body " + body);
RequestBody reqUserId = RequestBody.create(MediaType.parse("text/plain"), userId);
//RequestBody reqImageType =RequestBody.create(MediaType.parse("text/plain"), "1");
Call<SaveImageResponseModel> responseCall = mService.saveImages(body, reqUserId);
responseCall.enqueue(new Callback<SaveImageResponseModel>() {
#Override
public void onResponse(Call<SaveImageResponseModel> call, retrofit2.Response<SaveImageResponseModel> response) {
hideLoader();
if (response != null) {
SaveImageResponseModel apiResponse = response.body();
if (apiResponse != null && apiResponse.getStatus()) {
Log.e(TAG, "onRequestSuccess: " + apiResponse);
} else {
Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noDataError), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noDataError), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<SaveImageResponseModel> call, Throwable t) {
hideLoader();
}
});
}
#Override
public void onNetworkNotAvailable() {
Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noNetworkMessage), Toast.LENGTH_SHORT).show();
hideLoader();
}
});
}
#Headers({
"authkey: ABCD#123"
})
#Multipart
#POST(UrlUtils.POST_IMAGES)
Call<SaveImageResponseModel> saveImages(#Part MultipartBody.Part file, #Part("userId") RequestBody userId);
First of all, no description, please add a little bit more.
Second:
show what is the content of mService.saveImages(body, reqUserId);
is the HTTP call of POST type?
is the endpoint really working? You should for example try to make call through Postman and you'll see, if it is going through

Upload file with application/x-www-form-urlencoded use retrofit

how to config retrofit work like image below
this is my code:
// interface ImageUploadService
#Multipart
#POST("/api=upl_img_version_2&token={token}&img_cat=3&sum={sum}")
Observable<ServerResponse> uploadAvatar(#Path("token") String token, #Path("sum") String sum, #Part MultipartBody.Part file);
===========================================
//File creating from selected URL
File file = new File(path);
// create RequestBody instance from file
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
// body part send to server
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
view.showLoadingDialog();
imageUploadService.uploadAvatar(token, sum, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ServerResponse>() {
#Override
public void onCompleted() {
view.hideLoadingDialog();
}
#Override
public void onError(Throwable e) {
e.printStackTrace();
view.hideLoadingDialog();
}
#Override
public void onNext(ServerResponse serverResponse) {
Log.d("aaaaa", serverResponse.toString());
}
})
then use burp suite to capture request and it's different with ios (working), i don't have any idea or keyword about that. Thanks
i've just found a solution and want to help someone face same issue instead of delete this question.
here is working code:
interface ImageUploadService {
//#Multipart
#POST("/api=upl_img_version_2&token={token}&img_cat=3&sum={sum}")
Observable<ServerResponse> uploadAvatar(#Path("token") String token, #Path("sum") String sum, #Body RequestBody file); // #Part => #Body
}
///////////////////////////////
File file = new File(path);
// MediaType.parse("multipart/form-data")
RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
imageUploadService.uploadAvatar(token, sum, requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ServerResponse>() {
#Override
public void onCompleted() {
view.hideLoadingDialog();
}
#Override
public void onError(Throwable e) {
e.printStackTrace();
view.hideLoadingDialog();
}
#Override
public void onNext(ServerResponse serverResponse) {
Log.d("aaaaa", serverResponse.toString());
}
})

Rxphoto: How .requestUri(context, TypeRequest.GALLERY) whit RxJava?

Rxphoto: How can i use .requestUri(context, TypeRequest.GALLERY) whit RxJava?
Link ti library: https://android-arsenal.com/details/1/3870#!description
And how then upload this file using Retrofit2? Some examples?
Thanks!
Use this this
RxPhoto.requestUri(context, TypeRequest.GALLERY)
flatMap(new Func1<Uri, Observable<Response>>() {
#Override
public Observable<Response> call(Uri uri) {
File file = new File(uriString);
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test");
return service.postImage(body, name);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Response>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(Response response) {
}
});
The Retrofit call service
interface Service {
#Multipart
#POST("/")
Observable<Response> postImage(#Part MultipartBody.Part image,#Part("name") RequestBody name);
}
Note: Service should be multipart request compulsory in Server Side

Categories

Resources