I have been struggling to figure out how to pass a file via the body of a post request. I tried a couple of things online, but nothing quite matches my use case. Here's the postman screen shot for my server code:
So, as you can see "photo" is in the body section as a key (file) and the value is an image file. This is a post request on the whole and returns no response when the query is successful.(just shows the status as created, as you can see from the screenshot)[also note:it requires auth token as header param and userid as path param) The endpoint code :
static final String ENDPOINT_UPLOAD_PROFILE_PHOTO= BuildConfig.BASE_URL
+ "/service-profile/v1/member/photo/{userId}";
Now, I am using the following code block for uploading photo :
@Override
public Single<JSONObject> doUploadPhoto(String userId, File filepath) {
Rx2ANRequest.MultiPartBuilder post = Rx2AndroidNetworking.upload(ApiEndPoint.ENDPOINT_UPLOAD_PROFILE_PHOTO)
.addMultipartFile("photo",filepath)
.addHeaders("Authorization", mApiHeader.getFormattedProtectedApiHeader())
.addHeaders("content-type", "multipart/form-data")
.setPriority(Priority.HIGH)
.addMultipartParameter("photo",filepath.getAbsolutePath())
.addPathParameter("userId",userId);
return post.build()
.getObjectSingle(JSONObject.class);
}
Now I reference this in my presenter as follows:
File file = new File(AppPreferencesHelper.getInstance().getPhotoFile());
//preferences has the path of the file , something like : /storage/emulated/0/DCIM/1566415330315.jpg
getCompositeDisposable().add(getDataManager().updateCurrentUserPhotoUploadApiCall(file)
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(response -> {
Log.d("fileupload", "it is successful" + response);
if (!isViewAttached()) {
return;
}
}, throwable -> {
if (!isViewAttached()) {
return;
}
Log.d("fileupload", "error: ");
getMvpView().hideLoading();
// handle the profile retrieval error here
//getMvpView().showDialog(R.string.unknown_error, R.string.unknown_error_message);
if (throwable instanceof ANError) {
ANError anError = (ANError) throwable;
Log.d("fileupload", "error: " + anError.getErrorCode());
handleApiError(anError);
}
}));
here's my api call :
@Override
public Single<JSONObject> updateCurrentUserPhotoUploadApiCall(File file) {
return mApiHelper.doUploadPhoto(mPreferencesHelper.getCurrentUserId(), file);
}
Upon trying to upload the image, i get the response : fileupload: error: 400 while filepath and everything seems to be correct. (filepath is : /storage/emulated/0/DCIM/1566415330315.jpg)
Any idea what I am doing wrong? I also, tried post request(without multipart and just passing filepath instead as a body param such that :
Rx2ANRequest.PostRequestBuilder post = Rx2AndroidNetworking.post(processUrl(ApiEndPoint.ENDPOINT_UPLOAD_PROFILE_PHOTO)) // Please note : processUrl(ApiEndPoint.ENDPOINT_UPLOAD_PROFILE_PHOTO)) = https://myapps.com/service-profile/v1/member/photo/{userId}
.addHeaders("Authorization", mApiHeader.getFormattedProtectedApiHeader())
.addPathParameter("userId", userId)
.addBodyParameter("photo",filepath.getAbsolutePath());
but didn't have any luck. it doesn't even show me success or error for the post request when I pass file as a body param. Any idea what I could be missing?
postman works as expected and it recommends the following okhttp client code for java:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZ\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"1ab6ef77b355e9acd7cc9b82b5c8ec4f.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
Request request = new Request.Builder()
.url("https://myapps.com/api/service-profile/v1/member/photo/9ea899b8-b271-486b-ae64-443a17f06a39")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Authorization", "Bearer eyJraWQiOiJXZ3NucHRZekZYMnZsRTJ2TEJlUFpjSlJ4TU93SFRqcGkydDZAwdW03bzU5d2xRTFkxUU1HMGg3Iiwic2NwIjpbIm9mZmxpbmVfYWNjZXNzIiwicHJvZmlsZSIsIm9wZW5pZCIsIm1lbWJlciIsImVtYWlsIl0sInN1YiI6InZhcmFuaGErd3BkZXZsYUBjbnZ3cC5jb20iLCJtZW1iZXIucmVhZCI6dHJ1ZSwibWVtYmVyLndyaXRlIjp0cnVlfQ.LQhea6roQyQNIRnb3XWVuQZjoid2yn7TT-cgbdDeUnbMCUtFnOiHKPOLo_zpRr0bB429-yuLeSLdLjj_mF-PESbr0SfvNj01N-AWtYvyn9gEvcqS3hHHzPI44RDYkU8CtenByxwDBLUTlrdAGW7Xmi-UtGdd2_kaM8zkZoVWRS8dbymCVfZyoYr7DeR9hFZtD8RCtYRMRJrgQGZoMv7_1oCJyo8lAWuMpUmZfsEscOOw44hFoNADv221l70mbTIb-XwA")
.addHeader("User-Agent", "PostmanRuntime/7.15.2")
.addHeader("Accept", "*/*")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "3f81374d-d895-4a55-9122-297,3ff3b3f8-7149-46b9-887e-db1b4")
.addHeader("Host", "myapps.com")
.addHeader("Cookie", "AWSALB=HKdluG7WMh8PQmgNrYwRK+fpDEAE3DKnRQXIWOngg7Tn9kzEy5lQWhSsU45P7aLxk7Y")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("Content-Length", "17805")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
I am just wondering how to make sense of this "post(body) content to upload selected jpg image from my device? Also, it would be great if anyone can modify my existing androidnetworking (rx2) code to work as per postman recommendations.
Try this.I made it based on your postman request query, pretty sure it will work.