简体   繁体   English

Retrofit2 - 如何在multipart中使用改造上传图像?

[英]Retrofit2 - How to upload image using retrofit in multipart?

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. 我正在尝试使用retrofit2 beta 3在服务器上上传图像。作为回应我获得了成功,但图像没有上传到服务器上。 I dont know where's i'm making mistake. 我不知道我在哪里弄错了。 and

Header Type is Content-Type: application/x-www-form-urlencoded 标题类型是 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 . 在响应中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 提前致谢

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. 然后,它正在工作。

What i have observed is there is some bug in Okhttp which does not upload image. 我所观察到的是Okhttp中存在一些不上传图像的错误。 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. 您可以为剩余项目创建@PartMap 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. 注意我在为图像创建RequestBody时使用的类型。

Edit: 编辑:

This is RestClient.java . 这是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;
}

} }

只需删除标题类型

@headers({Content-Type: application/x-www-form-urlencoded})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM