Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting MultipartFile to java.io.File without copying to local machine

I have a Java Spring MVC web application. From client, through AngularJS, I am uploading a file and posting it to Controller as webservice.

In my Controller, I am gettinfg it as MultipartFile and I can copy it to local machine.

But I want to upload the file to Amazone S3 bucket. So I have to convert it to java.io.File. Right now what I am doing is, I am copying it to local machine and then uploading to S3 using jets3t.

Here is my way of converting in controller

MultipartHttpServletRequest mRequest=(MultipartHttpServletRequest)request;

Iterator<String> itr=mRequest.getFileNames();
        while(itr.hasNext()){
            MultipartFile mFile=mRequest.getFile(itr.next());
            String fileName=mFile.getOriginalFilename();

            fileLoc="/home/mydocs/my-uploads/"+date+"_"+fileName; //date is String form of current date.

Then I am using FIleCopyUtils of SpringFramework

File newFile = new File(fileLoc);

                  // if the directory does not exist, create it
                  if (!newFile.getParentFile().exists()) {
                    newFile.getParentFile().mkdirs();  
                  }
                FileCopyUtils.copy(mFile.getBytes(), newFile);

So it will create a new file in the local machine. That file I am uplaoding in S3

S3Object fileObject = new S3Object(newFile);

s3Service.putObject("myBucket", fileObject);

It creates file in my local system. I don't want to create.

Without creating a file in local system, how to convert a MultipartFIle to java.io.File?

like image 722
Shiju K Babu Avatar asked Jan 13 '14 10:01

Shiju K Babu


People also ask

How do I get files from MultipartFile?

MultipartFile#transferTo Using the transferTo() method, we simply have to create the File that we want to write the bytes to, then pass that file to the transferTo() method. The transferTo() method is useful when the MultipartFile only needs to be written to a File.

How do you pass a multipart file in Java?

To pass the Json and Multipart in the POST method we need to mention our content type in the consume part. And we need to pass the given parameter as User and Multipart file. Here, make sure we can pass only String + file not POJO + file. Then convert the String to Json using ObjectMapper in Service layer.

What is Java MultipartFile?

public interface MultipartFile extends InputStreamSource. A representation of an uploaded file received in a multipart request. The file contents are either stored in memory or temporarily on disk. In either case, the user is responsible for copying file contents to a session-level or persistent store as and if desired ...

How do I convert a file to multipart in spring boot?

MultipartFile has a getBytes () method that returns a byte array of the file's contents. We can use this method to write the bytes to a file: MultipartFile multipartFile = new MockMultipartFile ("sourceFile.


2 Answers

MultipartFile, by default, is already saved on your server as a file when user uploaded it. From that point - you can do anything you want with this file. There is a method that moves that temp file to any destination you want. http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/web/multipart/MultipartFile.html#transferTo(java.io.File)

But MultipartFile is just API, you can implement any other MultipartResolver http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/web/multipart/MultipartResolver.html

This API accepts input stream and you can do anything you want with it. Default implementation (usually commons-multipart) saves it to temp dir as a file.

But other problem stays here - if S3 API accepts a file as a parameter - you cannot do anything with this - you need a real file. If you want to avoid creating files at all - create you own S3 API.

like image 158
Boris Avatar answered Oct 12 '22 19:10

Boris


The question is already more than one year old, so I'm not sure if the jets35 link provided by the OP had the following snippet at that time.

If your data isn't a File or String you can use any input stream as a data source, but you must manually set the Content-Length.

// Create an object containing a greeting string as input stream data.
String greeting = "Hello World!";

S3Object helloWorldObject = new S3Object("HelloWorld2.txt");

ByteArrayInputStream greetingIS = new ByteArrayInputStream(greeting.getBytes());

helloWorldObject.setDataInputStream(greetingIS);
helloWorldObject.setContentLength(
    greeting.getBytes(Constants.DEFAULT_ENCODING).length);
helloWorldObject.setContentType("text/plain");

s3Service.putObject(testBucket, helloWorldObject);

It turns out you don't have to create a local file first. As @Boris suggests you can feed the S3Object with the Data Input Stream, Content Type and Content Length you'll get from MultipartFile.getInputStream(), MultipartFile.getContentType() and MultipartFile.getSize() respectively.

like image 21
Kostas Filios Avatar answered Oct 12 '22 19:10

Kostas Filios