1

I'm trying to upload image on server using retrofit2 beta 3. In response i'm getting success but image is not getting uploaded on server. I dont know where's i'm making mistake. and

Header Type is Content-Type: application/x-www-form-urlencoded

My Interface

@Multipart
@POST("/uploadFile")
Call<ResponseBody> upload(@PartMap Map<String, RequestBody> params);

and the method i used for uploading is

Method for uploading Image and data

 private void uploadFile() {

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(Constants.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
   ApiInterface service =
            retrofit.create(ApiInterface.class);

    File file = new File(fileUri.getPath());
    Log.e(TAG, "uploadFile: " + file.toString());
    String fileName = "uploadFile\"; filename=\"" + file.getName();
    final RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
    final RequestBody empsno = RequestBody.create(MediaType.parse("text/plain"), strEmpsno);
    final RequestBody storsno = RequestBody.create(MediaType.parse("text/plain"), strStoreSno);
    final RequestBody strlr = RequestBody.create(MediaType.parse("text/plain"), strLrno);
    final RequestBody strtecq = RequestBody.create(MediaType.parse("text/plain"), strRecqty);
    final RequestBody strtecv = RequestBody.create(MediaType.parse("text/plain"), strRecvol);
    final RequestBody strtecw = RequestBody.create(MediaType.parse("text/plain"), strRecwgt);
    final RequestBody strdmg = RequestBody.create(MediaType.parse("text/plain"), strDamageqty);
    final RequestBody strlus = RequestBody.create(MediaType.parse("text/plain"), strLooseqty);
    final RequestBody strdd = RequestBody.create(MediaType.parse("text/plain"), strDeliverydate);
    final RequestBody strdt = RequestBody.create(MediaType.parse("text/plain"), strDeliverytime);
    final RequestBody strrem = RequestBody.create(MediaType.parse("text/plain"), strRemarks);
    final RequestBody strrec = RequestBody.create(MediaType.parse("text/plain"), strReceivedby);
    final RequestBody strip = RequestBody.create(MediaType.parse("text/plain"), strIpaddress);

    Map<String, RequestBody> oJSONObject = new HashMap<>();

    oJSONObject.put("empsno", empsno);
    oJSONObject.put("storesno", storsno);
    oJSONObject.put("lrSno", strlr);
    oJSONObject.put("recQty", strtecq);
    oJSONObject.put("recVol", strtecv);
    oJSONObject.put("recWgt", strtecw);
    oJSONObject.put("damageQty", strdmg);
    oJSONObject.put("looseQty", strlus);
    oJSONObject.put("deliveryDate", strdd);
    oJSONObject.put("deliveryTime", strdt);
    oJSONObject.put("remarks", strrem);
    oJSONObject.put("receivedBy", strrec);
    oJSONObject.put("ipAddress", strip);

    Call<ResponseBody> call = service.upload(oJSONObject);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.e(TAG, "onResponse: " + response.isSuccessful());
            if (response.isSuccessful()) {
                Log.e(TAG, "onResponse: " + response.body());
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Log.e(TAG, "onFailure: " + t.getLocalizedMessage());
        }
    });

}

in response response.isSuccessful()=true. My response is getting successful then where is my problem. Please help me to find the solution.

Other way i also tried but not getting success, same result in another way also

@Multipart
@POST("/uploadFile")
Call<Response> getDetails(@Part("empsno") RequestBody empsno,
                                @Part("storesno")RequestBody  storesno,
                                @Part("lrSno")RequestBody  lrSno,
                                @Part("recQty")RequestBody  recQty,
                                @Part("recVol")RequestBody  recVol,
                                @Part("recWgt")RequestBody  recWgt,
                                @Part("damageQty")RequestBody  damageQty,
                                @Part("looseQty")RequestBody  looseQty,
                                @Part("deliveryDate")RequestBody  deliveryDate,
                                @Part("deliveryTime")RequestBody  deliveryTime,
                                @Part("uploadFile\"; filename=\"abc.jpg\" ") RequestBody part,
                                @Part("remarks")RequestBody  remarks,
                                @Part("receivedBy")RequestBody  receivedBy,
                                @Part("ipAddress") RequestBody ipAddress

and method i used here is

File file = new File(fileUri.getPath());
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part.createFormData("uploadFile", file.getName(), requestFile);
        RequestBody empsno = RequestBody.create(MediaType.parse("text/plain"), strEmpsno);
        RequestBody storsno = RequestBody.create(MediaType.parse("text/plain"), strStoreSno);
        RequestBody strlr = RequestBody.create(MediaType.parse("text/plain"), strLrno);
        RequestBody strtecq = RequestBody.create(MediaType.parse("text/plain"), strRecqty);
        RequestBody strtecv = RequestBody.create(MediaType.parse("text/plain"), strRecvol);
        RequestBody strtecw = RequestBody.create(MediaType.parse("text/plain"), strRecwgt);
        RequestBody strdmg = RequestBody.create(MediaType.parse("text/plain"), strDamageqty);
        RequestBody strlus = RequestBody.create(MediaType.parse("text/plain"), strLooseqty);
        RequestBody strdd = RequestBody.create(MediaType.parse("text/plain"), strDeliverydate);
        RequestBody strdt = RequestBody.create(MediaType.parse("text/plain"), strDeliverytime);
        RequestBody strrem = RequestBody.create(MediaType.parse("text/plain"), strRemarks);
        RequestBody strrec = RequestBody.create(MediaType.parse("text/plain"), strReceivedby);
        RequestBody strip = RequestBody.create(MediaType.parse("text/plain"), strIpaddress);


        ApixInterface xInterface = retrofit.create(AudexInterface.class);
        Call<Response> podResponsecall = xInterface.getDetails(empsno, storsno, strlr, strtecq,
                strtecv, strtecw, strdmg, strlus, strdd, strdt,
                requestFile, strrem, strrec, strip);


        podResponsecall.enqueue(new Callback<Response>() {
            @Override
            public void onResponse(Call<Response> call, Response<Response> response) {
                Log.e(TAG, "onResponse: " + response.isSuccessful());
                if (response.isSuccessful()) {
                    Toast.makeText(getApplicationContext(), "Successfully saved!!!", Toast.LENGTH_LONG);
                    Log.e(TAG, "onResponse: " + response.body().getResult());
                    uploadFile();
                }
            }

            @Override
            public void onFailure(Call<Response> call, Throwable t) {
                Log.e(TAG, "onFailure: " + t.getLocalizedMessage());
            }
        });

By using this method also response is successful but image not getting upload on server.

Thanks in advance

AMAN SINGH
  • 3,491
  • 6
  • 28
  • 44

3 Answers3

0

my solution is that:

first step.

@Multipart
@POST("Work/SendPic.ashx")
Observable<ImgBean> uploadImg(@Part MultipartBody.Part file);

second step.

  RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),file);
                    MultipartBody.Part body =
                            MultipartBody.Part.createFormData("img", file.getName(), requestBody);

                    UploadImg uploadImg = BaseRetrofit.getInstance().create(UploadImg.class);

and then, it is working.

Chauncey
  • 11
  • 1
0

What i have observed is there is some bug in Okhttp which does not upload image. Handle it like this:

@Multipart
@POST("api/chats/upload_chat_image")
Call<UploadChatItemResponse> getImageLink(
        @Header("Authorization") String token,
        @Part("productid") RequestBody productid,
        @Part("touserid") RequestBody touserid,
        @Part("image\";filename=\"image.*\" ") RequestBody image);

Notice the last part. You can create @PartMap for remaining items. But don't do it for files. Also, the first image in last part should be the key server is expecting while last image should be as it is.

RequestBody uploadImage = RequestBody.create(MediaType.parse("image/png"), compressed_image);
    RequestBody productId = RequestBody.create(MediaType.parse("text/plain"), product.getProductid() + "");
    RequestBody userId = RequestBody.create(MediaType.parse("text/plain"), otherUserInfo.getUserid() + "");
    Call<UploadChatItemResponse> uploadChatImage = RestClient.getInstance(getApplicationContext()).getRestService()
            .getImageLink(PrefUtils.getToken(ChatActivity.this), productId, userId, uploadImage);
    uploadChatImage.enqueue(new Callback<UploadChatItemResponse>() {
        @Override
        public void onResponse(Call<UploadChatItemResponse> call, Response<UploadChatItemResponse> response) {
            if (response.body() != null && response.body().imageLink != null) {
                sendMessage(response.body().imageLink, new ChatItem.ChatType(false, ChatItem.ChatType.CHAT_TYPE_IMAGE, ChatItem.ChatType.CHAT_SUBTYPE_NO_SUBTYPE));
                sweetAlertDialog.dismiss();
                compressed_image.delete();
            } else {
                Toast.makeText(ChatActivity.this, "An error has occurred", Toast.LENGTH_SHORT).show();
                sweetAlertDialog.dismiss();
                compressed_image.delete();
            }
        }

        @Override
        public void onFailure(Call<UploadChatItemResponse> call, Throwable t) {
            Toast.makeText(ChatActivity.this, "An error has occurred", Toast.LENGTH_SHORT).show();
            sweetAlertDialog.dismiss();
            compressed_image.delete();
        }
    });

Notice the type I have used while creating RequestBody for image.

Edit:

This is RestClient.java.

public class RestClient extends ContextWrapper {

private static final String BASE_URL = "https://www.restapi.in";
private APIService apiService;
private static RestClient restClient;
private static OkHttpClient okHttpClient;
private static final int READ_TIMEOUT = 100 * 1000;
private static final int CONNECTION_TIMEOUT = 100 * 1000;
private static final int CACHE_SIZE = 4;
private static final String CERTIFICATE_DOMAIN = "www.restclient.in";
private static final String[] CERTIFICATE_SHA = {"sha256/dkjabkjabcbakjbakjsbcabcahkcbakcbakcbakh=",
                                                 "sha256/ckjdcndkjcnjcnajcnajskcnakjcnakjcnaksjcna=",
                                                 "sha256/cjkacakjcbajcbasjkcbacjcbakcbcbakjbcjkacb="};

private RestClient(Context context) {
    super(context);
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(getOkHttpClient(context))
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    apiService = retrofit.create(APIService.class);
}

public static RestClient getInstance(Context context){
    if(restClient==null)
        restClient = new RestClient(context.getApplicationContext());
    return restClient;
}

private static OkHttpClient getOkHttpClient(Context context){
    if (okHttpClient == null) {
        HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
        logger.setLevel(BuildConfig.DEBUG?HttpLoggingInterceptor.Level.HEADERS:HttpLoggingInterceptor.Level.NONE);
        CertificatePinner.Builder certificatePinnerBuilder = new CertificatePinner.Builder();
        for(String sha : CERTIFICATE_SHA)
            certificatePinnerBuilder.add(CERTIFICATE_DOMAIN, sha);
        okHttpClient = new OkHttpClient.Builder()
                .cache(setCache(context))
                .certificatePinner(certificatePinnerBuilder.build())
                .retryOnConnectionFailure(false)
                .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
                .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request original = chain.request();

                        Request request = original.newBuilder()
                                .header("Content-type", "application/json")
                                .header("Accept", "application/json")
                                .method(original.method(), original.body())
                                .build();

                        return chain.proceed(request);
                    }
                })
                .addInterceptor(logger)
                .build();
    }
    return okHttpClient;
}

private static Cache setCache(Context context) {
    int cacheSize = CACHE_SIZE * 1024 * 1024;
    return new Cache(new File(context.getCacheDir(), "http"), cacheSize);
}

public APIService getRestService(){
    return apiService;
}

}

Embydextrous
  • 1,611
  • 1
  • 12
  • 20
  • In my case Authorization is passed as 'Authorization Header', as evident from first code snippet, but you may tweak RestClient.java as per your need. – Embydextrous Sep 07 '16 at 10:47
  • @Embydextrous can we use both the annotation(@Part and @Header) simultaneously? i got java.lang.IllegalArgumentException: Only one encoding annotation is allowed. – ben10 Aug 07 '18 at 16:42
  • Are you using both `@Multipart` and `@FormUrlEncoded` annotations. – Embydextrous Aug 07 '18 at 16:53
  • @Embydextrous sorry,my mistake.thank you for the clarification – ben10 Aug 07 '18 at 17:40
0

Just remove Header Type

@headers({Content-Type: application/x-www-form-urlencoded})
Hitesh Kushwah
  • 1,351
  • 13
  • 23