43

I want to save uploaded images to a specific folder in a Spring 3 MVC application deployed on Tomcat

My problem is that I cannot save the uploaded images files to the host where the appliciation is running.

Here is what I tried:

private void saveFile(MultipartFile multipartFile, int id) throws Exception {
    String destination = "/images/" + id + "/"  + multipartFile.getOriginalFilename();
    File file = new File(destination);
    multipartFile.transferTo(file);
}

Result: FileNotFoundException - Yes sure, I do want create this file!?!

I tried it using the context.getRealPath or getResources("destination"), but without any success.

How can I create a new file in a specific folder of my app with the content of my multipart file?

kiedysktos
  • 3,910
  • 7
  • 31
  • 40
Alexander
  • 7,178
  • 8
  • 45
  • 75
  • What errors did you get when you tried context.getRealPath or getResources("destination") see http://stackoverflow.com/questions/2970643/create-a-file-and-store-in-java-web-application-folder – Rob Kielty Jun 01 '12 at 10:41
  • Ah okay thanks, getRealPath didn't work, because it returns null if the app got deployed into a war file and was not extracted! Its working outside of the war container! But are there any options to get the path to a file inside of a war? – Alexander Jun 01 '12 at 11:37
  • I wouldn't say so. It doesn't really make sense to add files into a deployed war. Is that what you want to do? – Rob Kielty Jun 01 '12 at 11:56
  • No not really, but I read that some webservers do not extract the war file so that I thought to make the above example possible, there must be a way to write in that war directory. Therfore getRealPath is not the proper method cause it'll return null. Fortunately it is working on my tomcat, but just to briden my horizont I would like to know if there is another solution – Alexander Jun 02 '12 at 09:02
  • FileNotFoundException means you don't have folder /images/{id}/, you should create folder first. – teik Apr 20 '21 at 06:52

6 Answers6

43

This code will surely help you.

String filePath = request.getServletContext().getRealPath("/"); 
multipartFile.transferTo(new File(filePath));
vault
  • 3,930
  • 1
  • 35
  • 46
Ravi Maroju
  • 657
  • 6
  • 11
19

Let's create the uploads directory in webapp and save files in webapp/uploads:

@RestController
public class GreetingController {

    private final static Logger log = LoggerFactory.getLogger(GreetingController.class);

    @Autowired
    private HttpServletRequest request;


    @RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
        public
        @ResponseBody
        ResponseEntity handleFileUpload(@RequestParam("file") MultipartFile file) {
            if (!file.isEmpty()) {
                try {
                    String uploadsDir = "/uploads/";
                    String realPathtoUploads =  request.getServletContext().getRealPath(uploadsDir);
                    if(! new File(realPathtoUploads).exists())
                    {
                        new File(realPathtoUploads).mkdir();
                    }

                    log.info("realPathtoUploads = {}", realPathtoUploads);


                    String orgName = file.getOriginalFilename();
                    String filePath = realPathtoUploads + orgName;
                    File dest = new File(filePath);
                    file.transferTo(dest);

the code
String realPathtoUploads = request.getServletContext().getRealPath(uploadsDir);

returns me next path if I run the app from Idea IDE
C:\Users\Iuliia\IdeaProjects\ENumbersBackend\src\main\webapp\uploads\

and next path if I make .war and run it under Tomcat:
D:\Programs_Files\apache-tomcat-8.0.27\webapps\enumbservice-0.2.0\uploads\

My project structure:
enter image description here

Yuliia Ashomok
  • 8,336
  • 2
  • 60
  • 69
  • 1
    The last line of the code ' file.transferTo(dest);' gives me IO exception and the error message is "The system cannot find the path specified". Any idea why this is happening? – MR AND Apr 17 '17 at 20:20
  • 1
    @AND, are you sure the path is exist in your file system? You need to create directories firstly (manually or programmatically). – Yuliia Ashomok Apr 18 '17 at 07:22
  • 1
    This was very helpful. While its effectively the same answer as Ravi's, this is a more thorough answer. This answer is still valid in Spring Boot 1.5.10 – Stephan Mar 26 '18 at 20:39
13

You can get the inputStream from multipartfile and copy it to any directory you want.

public String write(MultipartFile file, String fileType) throws IOException {
    String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss-"));
    String fileName = date + file.getOriginalFilename();
    
    // folderPath here is /sismed/temp/exames
    String folderPath = SismedConstants.TEMP_DIR + fileType;
    String filePath = folderPath + File.separator + fileName;
    
    // Copies Spring's multipartfile inputStream to /sismed/temp/exames (absolute path)
    Files.copy(file.getInputStream(), Paths.get(filePath), StandardCopyOption.REPLACE_EXISTING);
    return filePath;
}

This works for both Linux and Windows.

Diego Victor de Jesus
  • 2,575
  • 2
  • 19
  • 30
1

I saw a spring 3 example using xml configuration (note this does not wok for spring 4.2.*): http://www.devmanuals.com/tutorials/java/spring/spring3/mvc/spring3-mvc-upload-file.html `

<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000" />
<property name="uploadTempDir" ref="uploadDirResource" />
</bean>

<bean id="uploadDirResource" class="org.springframework.core.io.FileSystemResource">
<constructor-arg>
<value>C:/test111</value>
</constructor-arg>
</bean>
0
String ApplicationPath = 
        ContextLoader.getCurrentWebApplicationContext().getServletContext().getRealPath("");

This is how to get the real path of App in Spring (without using response, session ...)

0

The following worked for me on ubuntu:

String filePath = request.getServletContext().getRealPath("/");
File f1 = new File(filePath+"/"+multipartFile.getOriginalFilename());
multipartFile.transferTo(f1);
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
Vijay
  • 213
  • 1
  • 9