当前位置: 首页 > 知识库问答 >
问题:

如何使用改装上载多文件

颛孙俊
2023-03-14

如何使用改造上传多文件,

我尝试使用以下代码上载文件:

ApiService:

@Multipart
@POST("uploadData.php")
Call<ServerResponse> uploadFile(@Part MultipartBody.Part file,
                                @Part("name") RequestBody name,
                                @Part MultipartBody.Part img,
                                @Part("imgname") RequestBody imgname);

以及上传方法:

private void uploadFile() {
    File file = new File(Environment.getExternalStorageDirectory() + "/Download/audio2.wav");
    File file2 = new File(Environment.getExternalStorageDirectory() + "/Download/Salty.png");

    RequestBody mFile = RequestBody.create(MediaType.parse("audio/*"), file);
    MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", file.getName(), mFile);
    RequestBody filename = RequestBody.create(MediaType.parse("text/plain"), file.getName());

    RequestBody mFile2 = RequestBody.create(MediaType.parse("image/*"), file2);
    MultipartBody.Part fileToUpload2 = MultipartBody.Part.createFormData("file", file2.getName(), mFile2);
    RequestBody filename2 = RequestBody.create(MediaType.parse("text/plain"), file2.getName());

    ApiService uploadImage = ApiClient.getClient().create(ApiService.class);
    Call<ServerResponse> fileUpload = uploadImage.uploadFile(fileToUpload, filename, fileToUpload2, filename2);
    fileUpload.enqueue(new Callback<ServerResponse>() {
            @Override
            public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
                Toast.makeText(MainActivity.this, "Success " + response.message(), Toast.LENGTH_LONG).show();
                Toast.makeText(MainActivity.this, "Success " + response.body().toString(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Call<ServerResponse> call, Throwable t) {
                Log.d("TAG", "Error " + t.getMessage());
            }
    });
}

和php代码:

$result = array("success" => $_FILES["file"]["name"]);
$file_path = basename($_FILES['file']['name']);

$imgResult = array("success" => $_FILES["img"]["imgname"]);
$img_path = basename($_FILES['img']['imgname']);


if (move_uploaded_file($_FILES['img']['tmp_name2'], "$img_path") or
        move_uploaded_file($_FILES['file']['tmp_name'], "$file_path")) {
    $result = array("success" => "File successfully uploaded");
} else {
    $result = array("success" => "error uploading file");
}

echo json_encode($result, JSON_PRETTY_PRINT);

此代码仅适用于一个文件,我不知道原因,

任何帮助,提前感谢。

共有3个答案

程亦
2023-03-14

如上@chintak的回答是正确的,您需要添加

Gson gson = new GsonBuilder()
.setLenient()
.create();

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()

如您在上述评论中所述,您面临的是宽大的格式错误异常。

赵晨
2023-03-14

无需从Android传递您的文件名,在您收到文件后,然后在此处获取该文件名(在PHP代码中)

@Multipart
@POST("uploadData.php")
Call<ServerResponse> uploadFile(@Part MultipartBody.Part file,
                                @Part MultipartBody.Part img);

Java中的文件上载代码

MultipartBody.Part audioFile= null;
        try {
            File file = new File(Environment.getExternalStorageDirectory() + "/Download/audio2.wav");
            if file != null) {                
                RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"),
                        file);
                audioFile = MultipartBody.Part.createFormData("AudioFile", file.getName(), requestFile);
            }
        }
        catch (Exception ex)
        {
            Log.d("UploadStatus", "Multipart Audio as exception occurs");
        }

MultipartBody.Part imageFile = null;
        try {
            File file = new File(Environment.getExternalStorageDirectory() + "/Download/Salty.png");
            if file != null) {                
                RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"),
                        file);
                imageFile = MultipartBody.Part.createFormData("ImageFile", file.getName(), requestFile);
            }
        }
        catch (Exception ex)
        {
            Log.d("UploadStatus", "Multipart Image as exception occurs");
        }


ApiService uploadImage = ApiClient.getClient().create(ApiService.class);
    Call<ServerResponse> fileUpload = uploadImage.uploadFile(audioFile, imageFile);
    fileUpload.enqueue(new Callback<ServerResponse>() {
            @Override
            public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
                Toast.makeText(MainActivity.this, "Success " + response.message(), Toast.LENGTH_LONG).show();
                Toast.makeText(MainActivity.this, "Success " + response.body().toString(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Call<ServerResponse> call, Throwable t) {
                Log.d("TAG", "Error " + t.getMessage());
            }
    });

在PHP代码中

访问以下两个文件

file 1    ==>   $_FILES["AudioFile"]["name"]

file 1    ==>   $_FILES["ImageFile"]["name"]

然后在此处获取文件名。。。

您必须避免改装Builder上的正面setLenient错误

Gson gson = new GsonBuilder()
        .setLenient()
        .create();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(client)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build(); 

希望这能帮助你。。。

雍飞雨
2023-03-14

您必须更改代码,以便在一次请求中上载多个文件,使用如下改装。

创建一个创建多部件体的函数。零件,并将自动获取其类型扩展名。

public static MultipartBody.Part prepareFilePart(String partName, String fileUri) {
    File file = new File(fileUri);
    String mimeType= URLConnection.guessContentTypeFromName(file.getName());
    Log.e("mimeType",mimeType);
    //create RequestBody instance from file
    RequestBody requestFile = RequestBody.create(MediaType.parse(mimeType), file);
    //MultipartBody.Part is used to send also the actual file name
    return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
}

现在在您的代码中,要上传多个文件,请创建ArrayList

public void uploadFile(){
    ArrayList<MultiPartBody.Part> files = new ArrayList<MultiPartBody.Part>();

    for(int i=0; i < selectedFiles.size; i++){
        files.add(prepareFilePart("file_"+(i+1), selectedFiles.get(i)));
        //Where selectedFiles is selected file URI list
    }

    RequestBody totalFiles = RequestBody.create(MediaType.parse("text/plain"), files.size);

    ApiService uploadImage = ApiClient.getClient().create(ApiService.class);
    Call<ServerResponse> fileUpload = uploadImage.uploadFile(files,totalFiles);
    fileUpload.enqueue(...);

}

并且在您的ApiService中,将更改为

@Multipart
@POST("uploadData.php")
Call<ServerResponse> uploadFile(@Part ArrayLisy<MultipartBody.Part> files, @Part("totalFiles") RequestBody totalFiles);

并在PHP文件中进行如下代码更改

$totalFiles = $_REQUEST['totalFiles'];
$successUpload = 0;

for($i=1; $i <= $totalFiles; $i++){
    $fileName = 'file_'.$i;
    if(move_uploaded_file($_FILES[$fileName]['tmp_name'],"Valid_file_path"){
        $successUpload += 1;
    }
}

echo $successUpload.' Files uploaded successfully.';

 类似资料:
  • 我需要使用@POST-in-reformation提交大数据(嵌套的json对象)以及多个图像/文件。 一种简单/hacky的方法是将图像转换为base 64字符串 但是如何使用@Multipart发送身体和图像。 上述方法引发错误:@Body参数不能用于表单或多部分编码。 就如何在Retrofit中上传多个文件以及请求正文(@body Foo)提出建议。

  • 有没有办法用Flask接收多个上传的文件?我尝试了以下方法: 然后打印的内容: 如果我上载多个文件,它只打印集合中的第一个文件: 有没有一种方法可以使用Flask的内置上传处理来接收多个文件?谢谢你的帮助!

  • 我正在执行使用Python请求库上传文件的简单任务。我搜索了Stack Overflow,似乎没有人遇到同样的问题,即服务器无法接收文件: 我正在用我的文件名填充upload_file关键字的值,因为如果我把它留空,它会说 现在我得到了 只有当文件为空时才会显示。所以我一直在思考如何成功地发送文件。我知道这个文件是有效的,因为如果我去这个网站手动填写表单,它会返回一个匹配对象的列表,这就是我想要的

  • 我正在尝试下载https://occ.ca/our-publications 我的最终目标是解析PDF文件中的文本并定位某些关键字。 到目前为止,我已经能够抓取所有页面上PDF文件的链接。我已将这些链接保存到列表中。现在,我想浏览一下列表并用Python下载所有pdf文件。下载完文件后,我想对它们进行解析。 这是我迄今为止使用的代码: 这是我运行代码时遇到的错误。 回溯(最近的最后一次调用):ur

  • 我试图理解以下文档: Transferutility.UploadDirectory null null null

  • 但是如何为多个文件做呢? PS.在webflux中有没有另一种上传一组文件的方法?