61
votes

Is there any way to convert a File object to MultiPartFile? So that I can send that object to methods that accept the objects of MultiPartFile interface?

File myFile = new File("/path/to/the/file.txt")

MultiPartFile ....?

def (MultiPartFile file) {
  def is = new BufferedInputStream(file.getInputStream())
  //do something interesting with the stream
}
10
You should be able to write your own class which implements FileItem but that takes an actual File to delegate to, then pass this FileItem instance to the constructor of CommonsMultipartFile which implements MultiPartFile - tim_yates
I've made a class that implements FileItem but I don't know how to implement all the methods of that interface. I've created a variable in this class which is File myFile. Should I just implement getinputStream() and getOutputStream()? - birdy
in particular, I don't know what you mean by this "but that takes an actual File to delegate to". This is what I have so far: gist.github.com/birdy101/5616009 - birdy
Something like this. Not tested it, but as you can see for methods where it's possible, I call methods on the artifact. You should be able to construct it with new StoredFile( artifact: new File( '/path/to/file' ) )... Fingers crossed it works... - tim_yates

10 Answers

51
votes

MockMultipartFile exists for this purpose. As in your snippet if the file path is known, the below code works for me.

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.mock.web.MockMultipartFile;

Path path = Paths.get("/path/to/the/file.txt");
String name = "file.txt";
String originalFileName = "file.txt";
String contentType = "text/plain";
byte[] content = null;
try {
    content = Files.readAllBytes(path);
} catch (final IOException e) {
}
MultipartFile result = new MockMultipartFile(name,
                     originalFileName, contentType, content);
25
votes
File file = new File("src/test/resources/input.txt");
FileInputStream input = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile("file",
            file.getName(), "text/plain", IOUtils.toByteArray(input));
18
votes
MultipartFile multipartFile = new MockMultipartFile("test.xlsx", new FileInputStream(new File("/home/admin/test.xlsx")));

This code works fine for me. May be you can have a try.

13
votes

In my case, the

fileItem.getOutputStream();

wasn't working. Thus I made it myself using IOUtils,

File file = new File("/path/to/file");
FileItem fileItem = new DiskFileItem("mainFile", Files.probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile());

try {
    InputStream input = new FileInputStream(file);
    OutputStream os = fileItem.getOutputStream();
    IOUtils.copy(input, os);
    // Or faster..
    // IOUtils.copy(new FileInputStream(file), fileItem.getOutputStream());
} catch (IOException ex) {
    // do something.
}

MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
12
votes

This is a solution without creating manually a file on disc :

MultipartFile fichier = new MockMultipartFile("fileThatDoesNotExists.txt",
            "fileThatDoesNotExists.txt",
            "text/plain",
            "This is a dummy file content".getBytes(StandardCharsets.UTF_8));
5
votes
File file = new File("src/test/resources/validation.txt");
DiskFileItem fileItem = new DiskFileItem("file", "text/plain", false, file.getName(), (int) file.length() , file.getParentFile());
fileItem.getOutputStream();
MultipartFile multipartFile = new CommonsMultipartFile(fileItem);

You need the following to prevent NPE.

fileItem.getOutputStream();

Also, you need to copy the file content to fileItem so that file won't be empty

new FileInputStream(f).transferTo(item.getOutputStream());

3
votes

Solution without Mocking class, Java9+ and Spring only.

FileItem fileItem = new DiskFileItemFactory().createItem("file",
    Files.probeContentType(file.toPath()), false, file.getName());

try (InputStream in = new FileInputStream(file); OutputStream out = fileItem.getOutputStream()) {
    in.transferTo(out);
} catch (Exception e) {
    throw new IllegalArgumentException("Invalid file: " + e, e);
}

CommonsMultipartFile multipartFile = new CommonsMultipartFile(fileItem);
3
votes

If you can't import MockMultipartFile using

import org.springframework.mock.web.MockMultipartFile;

you need to add the below dependency into pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
0
votes

It's working for me:

File file = path.toFile();
String mimeType = Files.probeContentType(path);     

DiskFileItem fileItem = new DiskFileItem("file", mimeType, false, file.getName(), (int) file.length(),
            file.getParentFile());
fileItem.getOutputStream();
MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
0
votes
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.commons.io.IOUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

public static void main(String[] args) {
        convertFiletoMultiPart();
    }

    private static void convertFiletoMultiPart() {
        try {
            File file = new File(FILE_PATH);
            if (file.exists()) {
                System.out.println("File Exist => " + file.getName() + " :: " + file.getAbsolutePath());
            }
            FileInputStream input = new FileInputStream(file);
            MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain",
                    IOUtils.toByteArray(input));
            System.out.println("multipartFile => " + multipartFile.isEmpty() + " :: "
                    + multipartFile.getOriginalFilename() + " :: " + multipartFile.getName() + " :: "
                    + multipartFile.getSize() + " :: " + multipartFile.getBytes());
        } catch (IOException e) {
            System.out.println("Exception => " + e.getLocalizedMessage());
        }
    }

This worked for me.