android上传多个文件夹,Android在一个请求中上传多个文件

我正在通过多部分/表单数据请求将内容发布到服务器.

并且我发布的数据包含多个参数,包括文件数组参数(files []).

使用postman,我将参数和文件设置为:

first-parameter=text content

second-parameter=text content

files[0]={first selected file}

files[1]={second selected file}

向邮递员提交此请求总是成功的,并且文件已成功上传.

当我在邮递员上生成代码片段时,结果如下:

POST /api/*******/new HTTP/1.1

Host: ***.***.***.*** ip-address

Authorization: {authorization header}

Cache-Control: no-cache

Postman-Token: d15f13f1-4a65-81d1-bf91-f5accd1b1dd0

Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW

Content-Disposition: form-data; name="first-parameter"

first-parameter-value

------WebKitFormBoundary7MA4YWxkTrZu0gW

Content-Disposition: form-data; name="second-parameter"

second-parameter-value

------WebKitFormBoundary7MA4YWxkTrZu0gW

Content-Disposition: form-data; name="files[0]"; filename=""

Content-Type:

------WebKitFormBoundary7MA4YWxkTrZu0gW

Content-Disposition: form-data; name="files[1]"; filename=""

Content-Type:

------WebKitFormBoundary7MA4YWxkTrZu0gW--

在Android上,我将Retrofit与HttpLoggingInterceptor库一起使用,并在发布请求时使用@PartMap批注:

// API定义:

interface ApiDefinitions {

@Multipart

@POST("*******/new")

Call submitNew(@Header("Authorization") String authHeader,

@PartMap Map params);

}

//准备并发送请求代码:

public void postContent() {

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();

interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient client = new OkHttpClient

.Builder()

.addInterceptor(interceptor)

.build();

Retrofit retrofit = new Retrofit

.Builder()

.baseUrl(API_URL)

.client(client)

.addConverterFactory(GsonConverterFactory.create(new Gson()))

.build();

ApiDefinitions api = retrofit.create(ApiDefinitions.class);

MediaType mediaType = MediaType.parse("multipart/form-data");

Map params = new HashMap<>();

params.put("first-parameter", MultipartBody.create(mediaType, "first-parameter-value"));

params.put("second-parameter", MultipartBody.create(mediaType, "second-parameter-value"));

params.put("files[0]", MultipartBody.create(mediaType, new File("First file path")));

params.put("files[1]", MultipartBody.create(mediaType, new File("Second file path")));

Call call = api.submitNew("Auth Token", params);

enqueue.enqueue(new Callback() {

@Override

public void onResponse(Call call, Response response) {

}

@Override

public void onFailure(Call call, Throwable t) {

}

});

}

提交此请求没有任何错误,http响应为200,但文件未上传!

由于我使用的是HttpLoggingInterceptor,因此我尝试将改造日志与邮递员代码段进行比较,这是改造日志:

D/OkHttp: --> POST http://{api_address}/api/*****/new http/1.1

D/OkHttp: Content-Type: multipart/form-data; boundary=64360751-a7f4-44c4-a008-f5de764c7298

D/OkHttp: Content-Length: 119325

D/OkHttp: Authorization: {Authorization-Token}

D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298

D/OkHttp: Content-Disposition: form-data; name="first-parameter"

D/OkHttp: Content-Transfer-Encoding: binary

D/OkHttp: Content-Type: multipart/form-data; charset=utf-8

D/OkHttp: Content-Length: 10

D/OkHttp: first-parameter-value

D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298

D/OkHttp: Content-Disposition: form-data; name="second-parameter"

D/OkHttp: Content-Transfer-Encoding: binary

D/OkHttp: Content-Type: multipart/form-data; charset=utf-8

D/OkHttp: Content-Length: 10

D/OkHttp: second-parameter-value

D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298

D/OkHttp: Content-Disposition: form-data; name="files[0]"

D/OkHttp: Content-Transfer-Encoding: binary

D/OkHttp: Content-Type: multipart/form-data;

D/OkHttp: Content-Length: 44205

D/OkHttp: �PNG

D/OkHttp:

D/OkHttp: ������IHDR��������������������r�B�������sBIT��O����� ��IDATx�4�˳mYv��}c�9���so�|W���R��2z�T%�8B�X�

D/OkHttp: &�D$��B��r�D��w�!@��������{��H���[�!,�@ �4h�P����>�A��&� ����B�[�,�fD�Mi�d�5)���5�{��-�MQt��ٗ&

D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298

D/OkHttp: Content-Disposition: form-data; name="files[1]"

D/OkHttp: Content-Transfer-Encoding: binary

D/OkHttp: Content-Type: multipart/form-data;

D/OkHttp: Content-Length: 44205

D/OkHttp: �PNG

D/OkHttp:

D/OkHttp: ������IHDR��������������������r�B�������sBIT��O����� ��IDATx�4�˳mYv��}c�9���so�|W���R��2z�T%�8B�X�

D/OkHttp: &�D$��B��r�D��w�!@��������{��H���[�!,�@ �4h�P����>�A��&� ����B�[�,�fD�Mi�d�5)���5�{��-�MQt��ٗ&

D/OkHttp: --64360751-a7f4-44c4-a008-f5de764c7298--

D/OkHttp: --> END POST (119325-byte body)

D/OkHttp:

我试图通过比较邮递员和改版的两个日志来查找请求中的问题,但是我找不到它!

随机边界字符串是不同的,这很正常,邮递员使用webkit,而改造不使用!我认为这根本不是问题.

我尝试使用@Part List< MultipartBody.Part而不是@PartMap Map< String,RequestBody>建议的文件为here,但它也无法正常工作.

上传文件该怎么办?

解决方法:

首先,我做错了一件事情,那就是使用@PartMap Map< String,RequestBody>在ApiDefinitions界面中.

如果您要执行具有多个参数和多个文件的发布请求,请始终确保在定义api方法时将RequestBody用于非文件参数,并将MultipartBody.Part用于文件参数.

就我而言,我需要发送一个文件数组,因此对我有用的参数是MultipartBody.Part [].

这是新的api定义:

@Multipart

@POST("*******/new")

Call submitNew(@Header("Authorization") String authHeader,

@Part("first-parameter") RequestBody firstParameter,

@Part("first-parameter") RequestBody secondParameter,

@Part MultipartBody.Part[] files);

我犯的第二个错误是没有注意到这一点:

PostMan Log: Content-Disposition: form-data; name=”files[0]”; filename=””

Retrofit Log: Content-Disposition: form-data; name=”files[0]”

我没有制作api,并且我没有任何php背景,所以请不要判断我.

据我所知,我已经成功地将文件发送到服务api,但是api不知道如何保存这些文件!

因此,在发送请求时:

List files; //These are the uris for the files to be uploaded

MediaType mediaType = MediaType.parse("");//Based on the Postman logs,it's not specifying Content-Type, this is why I've made this empty content/mediaType

MultipartBody.Part[] fileParts = new MultipartBody.Part[files.size()];

for (int i = 0; i < files.size(); i++) {

File file = new File(files.get(i).getPath());

RequestBody fileBody = RequestBody.create(mediaType, file);

//Setting the file name as an empty string here causes the same issue, which is sending the request successfully without saving the files in the backend, so don't neglect the file name parameter.

fileParts[i] = MultipartBody.Part.createFormData(String.format(Locale.ENGLISH, "files[%d]", i), file.getName(), fileBody);

}

Call call = api.submitNew("Auth Token", MultipartBody.create(mediaType, "first_parameter_values"), MultipartBody.create(mediaType, "second_parameter_values"), fileParts);

call.enqueue(new Callback() {

@Override

public void onResponse(Call call, Response response) {

}

@Override

public void onFailure(Call call, Throwable t) {

}

});

标签:android,retrofit2,multipartform-data

来源: https://codeday.me/bug/20191013/1907036.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值