This tutorial shows you about Spring MVC Multiple File Upload Validation Example. This example uses Spring validator to validate the uploaded file. This tutorial extends from the tutorial Spring MVC File Upload Validation Example.
Talbe of contents:
1. Maven Dependencies
2. Project Structure
3. Spring MVC File Upload Java/XML Configuration
4. Spring MVC File Upload
5. Upload file views
6. Deploy Spring MVC Multiple File Upload Validation Example
Other interesting posts you may like
Now, we are ready to build the Spring MVC Multiple File Upload Validation Example step by step
Maven Dependencies
We added the commons-fileupload which is used to upload a MultipartFile. We also include the javax.validation API so we can annotate our controller methods with the @Valid annotation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javabycode.spring.mvc</groupId> <artifactId>file-upload</artifactId> <version>1.0.0-SNAPSHOT</version> <name>SPRING-MVC - ${project.artifactId}</name> <url>http://javabycode.com</url> <packaging>war</packaging> <properties> <encoding>UTF-8</encoding> <spring.version>4.3.0.RELEASE</spring.version> </properties> <dependencies> <!-- spring dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- apache file upload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- java bean validation --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <!-- servlet api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project> |
Project Structure
The Project structure will looks like the following structure.
Spring MVC File Upload Java/XML Configuration
The CommonsMultipartResolver saves temporary files to the temporary directory in application server. The following properties should be configured for the file upload operation: maxUploadSize, maxUploadSizePerFile, maxInMemorySize, uploadDir, defaultEncoding and resolveLazily. Although they are optionally but you need to set the property resolveLazily to true if you want to catch execption correctly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
package com.javabycode.config; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; 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.javabycode"}) public class MyWebConfig extends WebMvcConfigurerAdapter { @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource; } @Bean(name="multipartResolver") public CommonsMultipartResolver multipartResolver(){ CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSizePerFile(10240); //10Kb resolver.setDefaultEncoding("UTF-8"); resolver.setResolveLazily(true); return resolver; } @Bean public InternalResourceViewResolver viewResolver(){ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } } |
If you want to adapt the file upload feature into your current Spring MVC XML configuration. You can add the below configuration. It is equivalent with the above java configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <mvc:annotation-driven /> <context:component-scan base-package="com.javabycode" /> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="messages"/> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSizePerFile" value="10240"/> <property name="defaultEncoding" value="UTF-8"/> <property name="resolveLazily" value="true"/> </bean> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </beans> |
For simplicity, the navigation cases will be put in a NavigationController.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class NavigationController { @RequestMapping(value = "/success", method = RequestMethod.GET) public String success(){ return "success"; } @RequestMapping(value = "/error", method = RequestMethod.GET) public String error(){ return "error"; } } |
Validation Messages
These validation messages are used to display an appropriate message with an error operation to the user. These messags are stored in the property file messages.properties that is located in the src/main/resources/ folder.
1 2 |
file.empty = Please select a file. file.maxsize = {0} exceeds the maximum size of {1} Kb. |
Spring MVC Multi File Upload
The MultiFileModel is used to upload multiple files. We reuse FileModel of the previous post.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.javabycode.model; import java.util.ArrayList; import java.util.List; public class MultiFileModel { List<FileModel> files = new ArrayList<FileModel>(); public MultiFileModel(int count){ for (int i = 0; i < count; i++){ files.add(new FileModel()); } } public List<FileModel> getFiles() { return files; } public void setFiles(List<FileModel> files) { this.files = files; } } |
The MultiFileUploadController processes multiple file uploads.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
package com.javabycode.controller; import com.javabycode.model.FileModel; import com.javabycode.model.MultiFileModel; import com.javabycode.validator.MultipleFileValidator; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; import java.io.File; import java.io.IOException; import java.io.InputStream; @Controller public class MultiFileUploadController { @Autowired private MultipleFileValidator multipleFileValidator; @ModelAttribute public MultiFileModel multiFileModel(){ return new MultiFileModel(3); } @InitBinder protected void initBinderFileModel(WebDataBinder binder) { binder.setValidator(multipleFileValidator); } @RequestMapping(value = "/", method = RequestMethod.GET) public String index(Model model){ model.addAttribute("multiFileModel", new MultiFileModel(3)); return "index"; } @RequestMapping(value="/upload", method = RequestMethod.POST) public String handleFormUpload(@Valid MultiFileModel models, BindingResult result, RedirectAttributes redirectMap) throws IOException { if (result.hasErrors()){ return "index"; } String[] files = new String[models.getFiles().size()]; int index = 0; for (FileModel model : models.getFiles()){ MultipartFile file = model.getFile(); InputStream in = file.getInputStream(); File destination = new File("/tmp/" + file.getOriginalFilename()); FileUtils.copyInputStreamToFile(in, destination); files[index] = file.getOriginalFilename(); index++; } redirectMap.addFlashAttribute("filenames", files); return "redirect:success"; } } |
The MultipleFileValidator handles validates multiple files. It’ll reject the request that submit a empty file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package com.javabycode.validator; import com.javabycode.model.FileModel; import com.javabycode.model.MultiFileModel; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; @Component public class MultipleFileValidator implements Validator { @Override public boolean supports(Class<?> clazz) { return MultiFileModel.class.isAssignableFrom(clazz); } @Override public void validate(Object target, Errors errors) { MultiFileModel multiModel = (MultiFileModel) target; int index = 0; for (FileModel model : multiModel.getFiles()){ if (model.getFile() != null && model.getFile().isEmpty()){ errors.rejectValue("files[" + index + "].file", "file.empty"); } index++; } } } |
Upload file views
We created a simple view to upload multiple files.
Upload view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Spring MVC Upload Multiple Files</title> <style> .error { color: red; } </style> </head> <body> <h1>Spring MVC Upload Multiple Files</h1> <form:form method="post" modelAttribute="multiFileModel" enctype="multipart/form-data" action="upload"> <c:forEach var="f" varStatus="fi" items="${multiFileModel.files}"> <c:set var="file" value="files[${fi.index}].file"/> Upload file: <form:input type="file" path="${file}" id="${file}"/> <form:errors path="${file}" cssClass="error"/> <br/> </c:forEach> <br/> <input type="submit" value="upload"/> </form:form> <a href="<c:url value='/'/>">Home</a> </body> </html> |
Success View
When the file is successfully uploaded, the file name will displayed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Upload a file please</title> </head> <body> <h1>Upload success</h1> <c:if test="${not empty filename}"> ${filename} uploaded successfully. <br/><br/> </c:if> <c:if test="${not empty filenames}"> <c:forEach var="file" items="${filenames}"> ${file} uploaded successfully. <br/> </c:forEach> <br/><br/> </c:if> <a href="<c:url value='/'/>">Page Upload</a> </body> </html> |
Error View
The content of the error is displayed if an error occurs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Upload Error</title> <style> .error { color: red; } </style> </head> <body> <h1>Upload Error</h1> <span class="error">${errors}</span> <br/><br/> <a href="<c:url value='/'/>">Page Upload</a> </body> </html> |
Deploy Spring MVC Multipe File Upload Validation Example
Building project with maven then deploy file war on application server or servlet container (Tomcat 8 for example). Access the address URL http://localhost:8080/spring-mvc-multiple-file-upload/ and browse files to upload such as the below screen shot.
Click the Upload button the success screen will display
Click the Upload Page link to return the Upload form screen and submit form without browsing file. The error screen will display such as
That’s it on how to build Spring MVC Multiple File Upload Validation Example.
Download complete source code of example, please click link below
Spring-Mvc-Multiple-File-Upload-Validation-Example.zip (390 downloads)
Source code on Github https://github.com/javabycode/spring-mvc-multiple-file-upload-validation-example