Reputation: 77
I'm making an app in which I have to send image from gallery to server.
These should be headers (according to apiary).
Content-Type:image/jpeg
X-Filename:photo.jpg
But in logs in interceptor, there is only X-Filename, even though I tried multiple ways and I'm running out of ideas.
Server responds with 200 but the next call (commit image) returns 500 with error at the end of post.
These are the methods:
@Multipart
@POST("uploads")
Observable<String> uploadImage(
@Header("Content-Type") String contentType,
@Header("X-Filename") String fileName,
@Header("Authorization") String token,
@Part MultipartBody.Part file
);
@GET("uploads/{fileId}/commit")
Observable<String> commitFile(
@Header("Content-Type") String type,
@Header("Authorization") String token,
@Path("fileId") String fileId
);
OkHttp client:
private OkHttpClient createApiClient(Context context) {
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(context.getCacheDir(), cacheSize);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().build();
request.newBuilder().addHeader("Content-Type", "application/json");
Timber.d("Request: [%s] %s", request.method(), request.url());
Timber.d("Request: %s", request.headers().toString());
if (request.body() != null) {
Timber.d("Request: %s", request.body().toString());
}
return chain.proceed(request);
});
builder.cache(cache);
return builder.build();
}
Resulting logs:
D/NetModule: Request: [POST] https://winged-guild-133523.appspot.com/api/v1/uploads
D/NetModule: Request: X-Filename: asura.png
Authorization: HAYVi3clcqjug53IPS6AYMgzCPGnDE3Si
D/NetModule: Request: retrofit2.RequestBuilder$ContentTypeOverridingRequestBody@7c37f46
Same thing happens with Postman - Postman screenshot
Commit fails with this error: (sorry for ugly formatting)
{
"errorCode": "ImagesServiceFailureException",
"errorParam": "",
"errorMessage":"com.google.appengine.api.images.ImagesServiceFailureException: "
}
As I said I'm running out of ideas and would greatly appreciate any help with this upload problem.
(edit) PS: by omitting @Header("Content-Type") String contentType in app and using application/x-www-form-urlencoded in Postman, image upload and commit are both successful, but Image at returned url has no metadata and therefore can't be displayed.
Upvotes: 2
Views: 2004
Reputation: 64
Do not use @Multipart
. Instead, use something like this:
@POST("upload/image")
Observable<ResponseBody> uploadImage(@Body RequestBody body);
File imageFile = new File(path);
RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"),imageFile);
api.uploadImage(body);
Upvotes: 2
Reputation: 120
This is my code using retrofit
@Multipart
@POST(ServiceConfig.API_CREATE_DEPENDENT_ACCOUNT)
@Headers({
"Accept: application/json",
"Accept-Encoding: gzip"
})
Call<DataResponse<CreateDependentAccountResponse>> createDependentAccount(@Query(JioConstants.ParamQuery.TOKEN) String token,
@Query(JioConstants.ParamQuery.USER_ID) long userID,
@Query(JioConstants.ParamQuery.FIRST_NAME) String firstName,
@Query(JioConstants.ParamQuery.LAST_NAME) String lastName,
@Query(JioConstants.ParamQuery.GENDER) String gender,
@Query(JioConstants.ParamQuery.DOB) String dob,
@Query(JioConstants.ParamQuery.RELATIONSHIP_ID) long relationshipID,
@Query(JioConstants.ParamQuery.DISPLAY_UNIT) String displayUnit,
@Part("avatar\"; filename=\"picture.jpg\" ") RequestBody file);
and
RequestBody file = null;
if (mFileTemp != null) {
file = RequestBody.create(MediaType.parse("image/*"), mFileTemp);
} else {
file = RequestBody.create(MediaType.parse("image/*"), "");
}
manageCall(ServiceManager.INSTANCE2().
createDependentAccount(token, userID, firstName, lastName, gender, dob, relationshipID, displayUnit, file))
.enqueue(new SimplifiedCallback<CreateDependentAccountResponse>() {
@Override
public void success(CreateDependentAccountResponse data, String message) {
hideLoading();
Upvotes: 1