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

时间:2016-09-07 08:06:59

标签: android retrofit multipartform-data retrofit2

我尝试使用retrofit2 beta 3在服务器上上传图片。在响应中我获得了成功,但图片未上传到服务器上。我不知道我在哪里弄错了。 和

标题类型 Content-Type: application/x-www-form-urlencoded

我的界面

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

我用于上传的方法是

上传图片和数据的方法

 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());
        }
    });

}

响应 response.isSuccessful()= true 。我的回答是成功的然后我的问题在哪里。请帮我找到解决方案。

其他方式我也试过但没有获得成功,同样的结果也是另一种方式

@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

和我在这里使用的方法是

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());
            }
        });

通过使用此方法,响应成功但图像无法在服务器上上传。

提前致谢

3 个答案:

答案 0 :(得分:0)

我的解决方案是:

第一步。

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

  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);

然后,它正在运作。

答案 1 :(得分:0)

我观察到的是Okhttp中存在一些不上传图像的错误。像这样处理:

@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);

注意最后一部分。您可以为剩余项目创建@PartMap。但是不要为文件做这件事。此外,最后一部分中的第一个图像应该是关键服务器期望的,而最后一个图像应该是原样。

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();
        }
    });

注意我在为图像创建RequestBody时使用的类型。

编辑:

这是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;
}

}

答案 2 :(得分:0)

只需删除标题类型

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