In this Spring MVC Multiple File Upload Example, we will learn how to upload multiple files in Spring MVC using CommonsMultipartResolver. We must add the Apache Commons File Upload dependency (commons-fileupload.jar) in order to use CommonsMultipartResolver.
Spring by default will not handle multipart file uploads, however it provides the support to multipart using the pluggable multipart object called “MultipartResolver”. We will have to be enabling the MultipartResolver in the context, in our case it is CommonsMultipartResolver.
Once we have enabled the MultipartResolver in the context each request will be checked whether it has a multipart in it, if present then the configured CommonsMultipartResolver will be used.
Folder Structure:
- Create a simple Maven webapp Project “SpringMVCFileUpload” and create a package for our source files “com.javainterviewpoint” under src/main/java
- Now add the following dependency in the POM.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javainterviewpoint</groupId> <artifactId>SpringMVCFileUpload</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>Spring MVC Multiple File Upload Example</name> <url>http://maven.apache.org</url> <properties> <jdk.version>1.8</jdk.version> <spring.version>4.3.7.RELEASE</spring.version> <jstl.version>1.2</jstl.version> <servlet.version>3.1.0</servlet.version> <commons.fileupload.version>1.3.2</commons.fileupload.version> </properties> <dependencies> <!-- Spring MVC Dependency --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- Apache Commons file upload Dependency--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons.fileupload.version}</version> </dependency> <!-- JSTL Dependency --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- Servlet Dependency --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>SpringMVCFileUpload</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> </plugins> </build> </project>
- Create the Java class UploadController.java,WebApplicationInitializer.java and SpringWebMvcConfig.java under com.javainterviewpoint folder.
- Place the uploadForm.jsp under the sub directory under WEB-INF/Jsp
Spring MVC Multiple File Upload Example
Dependency Tree
[INFO] ------------------------------------------------------------------------ [INFO] Building Spring MVC Multiple File Upload Example 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ SpringMVCFileUpload --- [INFO] com.javainterviewpoint:SpringMVCFileUpload:war:0.0.1-SNAPSHOT [INFO] +- org.springframework:spring-webmvc:jar:4.3.7.RELEASE:compile [INFO] | +- org.springframework:spring-aop:jar:4.3.7.RELEASE:compile [INFO] | +- org.springframework:spring-beans:jar:4.3.7.RELEASE:compile [INFO] | +- org.springframework:spring-context:jar:4.3.7.RELEASE:compile [INFO] | +- org.springframework:spring-core:jar:4.3.7.RELEASE:compile [INFO] | | \- commons-logging:commons-logging:jar:1.2:compile [INFO] | +- org.springframework:spring-expression:jar:4.3.7.RELEASE:compile [INFO] | \- org.springframework:spring-web:jar:4.3.7.RELEASE:compile [INFO] +- commons-fileupload:commons-fileupload:jar:1.3.2:compile [INFO] | \- commons-io:commons-io:jar:2.2:compile [INFO] +- jstl:jstl:jar:1.2:compile [INFO] \- javax.servlet:javax.servlet-api:jar:3.1.0:provided [INFO] ------------------------------------------------------------------------
WebMvcConfiguration.java
Create our SpringWebMvcConfig.java under the com.javainterviewpoint package.
package com.javainterviewpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration @ComponentScan({"com.javainterviewpoint"}) public class SpringWebMvcConfig extends WebMvcConfigurerAdapter { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/Jsp"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Bean public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver resolver= new CommonsMultipartResolver(); resolver.setMaxUploadSize(1048576); //1MB return cmr; } }
- We have created the new instance for the CommonsMultipartResolver and have set the setMaxUploadSize to permit only 1 MB.
- Whenever the DispatcherServlet detects a multipart request, it activates the CommonsMultipartResolver which is declared in the Spring Context.
- The MultipartResolver then wraps the plain HttpServletRequest into a MultipartHttpServletRequest which has support for multipart file uploads.
We have annotated our WebMvcConfiguration class with the below annotation
- @Configuration indicates that our SpringWebMvcConfig class can be used by the Spring IoC container as a source of bean definitions.
- @EnableWebMvc is equivalent to <mvc:annotation-driven /> in XML. It enables support for @Controller annotated classes. This annotation imports configuration from WebMvcConfigurationSupport
- @ComponentScan scans the stereotype annotations specified in @Controller, @Service etc.. annotated classes.
Equivalent XML configuration – SpringConfig-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.javainterviewpoint"> </context:component-scan> <mvc:annotation-driven> </mvc:annotation-driven> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/Jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- Setting the Maximum upload size to 1MB --> <property name="maxUploadSize" value="1048576" /> </bean> </beans>
WebApplicationInitializer.java
We can use AbstractAnnotationConfigDispatcherServletInitializer class to register and initialize the DispatcherServlet when the Servlet used in greater than 3.0 (No need for web.xml)
package com.javainterviewpoint; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringWebMvcConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } @Override protected Class<?>[] getRootConfigClasses() { return null; } }
Equivalent XML configuration – web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>SpringConfig</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringConfig</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/SpringConfig-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
UploadController.java
package com.javainterviewpoint; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.multipart.MultipartFile; @Controller public class UploadController { @GetMapping("/") public String showUploadForm(Model model) { return "uploadForm"; } @PostMapping("/save") public String saveFiles(@ModelAttribute("uploadFiles") FileData fileData, Model model) throws IOException { //Get the list of files List files = fileData.getFiles(); //Check whether the list is not null or empty if (files != null && !files.get(0).getOriginalFilename().isEmpty()) { //Get the individual MultipartFile for (MultipartFile multipartFile : files) { //Write each MultipartFile in the directory specified if (!multipartFile.getOriginalFilename().isEmpty()) { BufferedOutputStream outputStream = new BufferedOutputStream( new FileOutputStream(new File("E:\\JIP\\", multipartFile.getOriginalFilename()))); outputStream.write(multipartFile.getBytes()); outputStream.flush(); outputStream.close(); } } model.addAttribute("message", "All Files are uploaded successfully!!"); } else { model.addAttribute("message", "Please select atleast one file!!"); } return "uploadForm"; } }
- We have annotated our “UploadController” class with @Controller annotation which tells Spring Container to treat this class as a Controller.
- @GetMapping annotation on top of showUploadForm() redirects the request to this method, when the request given is “/” and it can take only GET request and redirects the user to the uploadForm.jsp
- Once the user submits the form, the saveFiles() method will be called, it gets the form data using @ModelAttribute and in-turn iterates each MultipartFile and writes to the new directory.
uploadForm.jsp
The uploadForm.jsp should be created under /WEB-INF/Jsp folder.
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <body> <h1>Spring MVC Multiple File Upload Example</h1> <form:form method="POST" action="save" modelAttribute="uploadFiles" enctype="multipart/form-data"> <input type="file" name="files" /> <br><br> <input type="file" name="files" /> <br><br> <input type="submit" value="Submit" /> </form:form> <br> <hr /> <h3 style="color: red;">${message}</h3> </body> </html>
In form, the modelAttribute holds the form data using FileData bean and we have also we have added the encoding attribute (enctype=”multipart/form-data”) which is necessary to let the browser know how to encode the multipart fields
Output
Once the server is started, hit on the url : http://localhost:8080/SpringMVCFileUpload/
When the user hits on submit button without selecting a single file, the below error message will be thrown
On successful upload
Leave a Reply