6

Hi i'm trying to upload multiple files using multipart form

I use this but i get Bad Request Status, how can i upload multiple files?


public class AttachmentBody {

    @FormParam("files")
    @PartType(MediaType.APPLICATION_OCTET_STREAM)
    public InputStream[] files;

}

Efraim LA
  • 63
  • 1
  • 5

1 Answers1

9

I was working in a part, I thought it would be helpful for multiple files upload. I am using RestEasy and Quarkus framework. Find below the code.

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import org.apache.commons.io.IOUtils;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;

@Path("/multiupload")
public class MultiFileUploadController {

    private static String UPLOAD_DIR = "E:/sure-delete";

    @POST
    @Path("/files")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public Response handleFileUploadForm(@MultipartForm MultipartFormDataInput input) {
    
        Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
        List<String> fileNames = new ArrayList<>();
    
        List<InputPart> inputParts = uploadForm.get("file");
        System.out.println("inputParts size: " + inputParts.size());
        String fileName = null;
        for (InputPart inputPart : inputParts) {
            try {
    
                MultivaluedMap<String, String> header = inputPart.getHeaders();
                fileName = getFileName(header);
                fileNames.add(fileName);
                System.out.println("File Name: " + fileName);
                InputStream inputStream = inputPart.getBody(InputStream.class, null);
                byte[] bytes = IOUtils.toByteArray(inputStream);
    
                File customDir = new File(UPLOAD_DIR);
                fileName = customDir.getAbsolutePath() + File.separator + fileName;
                Files.write(Paths.get(fileName), bytes, StandardOpenOption.CREATE_NEW);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        String uploadedFileNames = String.join(", ", fileNames);
        return Response.ok().entity("All files " + uploadedFileNames + " successfully.").build();
    }
    
    private String getFileName(MultivaluedMap<String, String> header) {
        String[] contentDisposition = header.getFirst("Content-Disposition").split(";");
        for (String filename : contentDisposition) {
            if ((filename.trim().startsWith("filename"))) {
                String[] name = filename.split("=");
                String finalFileName = name[1].trim().replaceAll("\"", "");
                return finalFileName;
            }
        }
        return "unknown";
    }
}

To test from the postman client, find below the image.

enter image description here

You can take it as an example also handle the exception.

jones1008
  • 157
  • 1
  • 15
Sambit
  • 7,625
  • 7
  • 34
  • 65
  • 2
    Dont do ` byte[] bytes = IOUtils.toByteArray(inputStream);` when you upload bigger files, this will cause a OOME. Better do `Files.copy(inputStream, Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING);` – Stefan Höltker Aug 13 '21 at 09:43
  • Thanks @Stefan for highlighting. – Sambit Aug 13 '21 at 10:16
  • also important to close the MultipartFormDataInput Object, if not the temporary files will not be deleted after method call, they will be deleted on GC or JVM exit. `finally { /** * Call this method to delete any temporary files created from * unmarshalling this multipart message Otherwise they will be deleted on * Garbage Collection or JVM exit. */ input.close(); }` – Stefan Höltker Aug 23 '21 at 11:15