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

Android在一个请求中上传多个文件,第1张

概述我正在通过多部分/表单数据请求将内容发布到服务器.并且我发布的数据包含多个参数,包括文件数组参数(files[]).使用postman,我将参数和文件设置为:first-parameter=textcontentsecond-parameter=textcontentfiles[0]={firstselectedfile}files[1]={secondselectedfile

我正在通过多部分/表单数据请求将内容发布到服务器.
并且我发布的数据包含多个参数,包括文件数组参数(files []).

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

first-parameter=text contentsecond-parameter=text contentfiles[0]={first selected file}files[1]={second selected file}

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

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

POST /API/*******/new http/1.1Host: ***.***.***.*** ip-addressAuthorization: {authorization header}Cache-Control: no-cachePostman-Token: d15f13f1-4a65-81d1-bf91-f5accd1b1dd0Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW------WebKitFormBoundary7MA4YWxkTrZu0gWContent-disposition: form-data; name="first-parameter"first-parameter-value------WebKitFormBoundary7MA4YWxkTrZu0gWContent-disposition: form-data; name="second-parameter"second-parameter-value------WebKitFormBoundary7MA4YWxkTrZu0gWContent-disposition: form-data; name="files[0]"; filename=""Content-Type: ------WebKitFormBoundary7MA4YWxkTrZu0gWContent-disposition: form-data; name="files[1]"; filename=""Content-Type: ------WebKitFormBoundary7MA4YWxkTrZu0gW--

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

// API定义:

interface APIDeFinitions {@Multipart@POST("*******/new")Call<APIResponse> submitNew(@header("Authorization") String authheader,                                      @PartMap Map<String, Requestbody> 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<String, Requestbody> 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<APIResponse> call = API.submitNew("Auth Token", params);    enqueue.enqueue(new Callback<APIResponse>() {        @OverrIDe        public voID onResponse(Call<APIResponse> call, Response<APIResponse> response) {        }        @OverrIDe        public voID onFailure(Call<APIResponse> call, Throwable t) {        }    });}

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

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

D/Okhttp: --> POST http://{API_address}/API/*****/new http/1.1D/Okhttp: Content-Type: multipart/form-data; boundary=64360751-a7f4-44c4-a008-f5de764c7298D/Okhttp: Content-Length: 119325D/Okhttp: Authorization: {Authorization-Token}D/Okhttp: --64360751-a7f4-44c4-a008-f5de764c7298D/Okhttp: Content-disposition: form-data; name="first-parameter"D/Okhttp: Content-transfer-encoding: binaryD/Okhttp: Content-Type: multipart/form-data; charset=utf-8D/Okhttp: Content-Length: 10D/Okhttp: first-parameter-valueD/Okhttp: --64360751-a7f4-44c4-a008-f5de764c7298D/Okhttp: Content-disposition: form-data; name="second-parameter"D/Okhttp: Content-transfer-encoding: binaryD/Okhttp: Content-Type: multipart/form-data; charset=utf-8D/Okhttp: Content-Length: 10D/Okhttp: second-parameter-valueD/Okhttp: --64360751-a7f4-44c4-a008-f5de764c7298D/Okhttp: Content-disposition: form-data; name="files[0]"D/Okhttp: Content-transfer-encoding: binaryD/Okhttp: Content-Type: multipart/form-data;D/Okhttp: Content-Length: 44205D/Okhttp: �PNGD/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-f5de764c7298D/Okhttp: Content-disposition: form-data; name="files[1]"D/Okhttp: Content-transfer-encoding: binaryD/Okhttp: Content-Type: multipart/form-data;D/Okhttp: Content-Length: 44205D/Okhttp: �PNGD/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: <-- 200 OK http://{API_address}/API/*****/new (3409ms)

我试图通过比较邮递员和改版的两个日志来查找请求中的问题,但是我找不到它!
随机边界字符串是不同的,这很正常,邮递员使用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<APIResponse> 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]”

文件名未包含在多部分请求中,显然是known issue when uploading files to a php service!

我没有制作API,并且我没有任何PHP背景,所以请不要判断我.
据我所知,我已经成功地将文件发送到服务API,但是API不知道如何保存这些文件!

因此,在发送请求时:

List<Uri> files; //These are the uris for the files to be uploadedMediaType mediaType = MediaType.parse("");//Based on the Postman logs,it's not specifying Content-Type, this is why I've made this empty content/mediaTypeMultipartbody.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<APIResponse> call = API.submitNew("Auth Token", Multipartbody.create(mediaType, "first_parameter_values"), Multipartbody.create(mediaType, "second_parameter_values"), fileParts);call.enqueue(new Callback<APIResponse>() {    @OverrIDe    public voID onResponse(Call<APIResponse> call, Response<APIResponse> response) {    }    @OverrIDe    public voID onFailure(Call<APIResponse> call, Throwable t) {    }});
总结

以上是内存溢出为你收集整理的Android在一个请求中上传多个文件全部内容,希望文章能够帮你解决Android在一个请求中上传多个文件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1093348.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存