openplanning

Hướng dẫn Upload File với Spring MVC

  1. Giới thiệu
  2. Tạo Maven project
  3. Cấu hình Maven & web.xml
  4. Cấu hình Spring MVC
  5. Controllers & Form
  6. Views
  7. Chạy ứng dụng

1. Giới thiệu

Tài liệu được viết dựa trên:
  • Eclipse 4.6 (NEON)
  • Spring 4 MVC

2. Tạo Maven project

  • File/New/Other..
Nhập vào:
  • Group ID: org.o7planning
  • Artifact ID: SpringMVCFileUD
  • Package: org.o7planning.springmvcfileud
Project đã được tạo ra.
Bạn đừng lo lắng với thông báo lỗi khi Project vừa được tạo ra. Lý do là bạn chưa khai báo thư viện Servlet.
Sử dụng Java >= 6
Project Properties:

3. Cấu hình Maven & web.xml

Sử dụng Servlet API >= 3
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   version="3.0">

   <display-name>Spring MVC File Update Download</display-name>
 

</web-app>
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>org.o7planning</groupId>
   <artifactId>SpringMVCFileUD</artifactId>
   <packaging>war</packaging>
   <version>0.0.1-SNAPSHOT</version>
   <name>SpringMVCFileUD Maven Webapp</name>
   <url>http://maven.apache.org</url>

   <dependencies>
   
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>3.8.1</version>
           <scope>test</scope>
       </dependency>


       <!-- Servlet API -->
       <!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>javax.servlet-api</artifactId>
           <version>3.1.0</version>
           <scope>provided</scope>
       </dependency>

       <!-- Jstl for jsp page -->
       <!-- http://mvnrepository.com/artifact/javax.servlet/jstl -->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>jstl</artifactId>
           <version>1.2</version>
       </dependency>


       <!-- JSP API -->
       <!-- http://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
       <dependency>
           <groupId>javax.servlet.jsp</groupId>
           <artifactId>jsp-api</artifactId>
           <version>2.2</version>
           <scope>provided</scope>
       </dependency>


       <!-- Spring dependencies -->
       <!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-core</artifactId>
           <version>4.3.3.RELEASE</version>
       </dependency>

       <!-- http://mvnrepository.com/artifact/org.springframework/spring-web -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-web</artifactId>
           <version>4.3.3.RELEASE</version>
       </dependency>

       <!-- http://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>4.3.3.RELEASE</version>
       </dependency>


       <!-- Apache Commons FileUpload -->
       <!-- http://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
       <dependency>
           <groupId>commons-fileupload</groupId>
           <artifactId>commons-fileupload</artifactId>
           <version>1.3.1</version>
       </dependency>

       <!-- Apache Commons IO -->
       <!-- http://mvnrepository.com/artifact/commons-io/commons-io -->
       <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.4</version>
       </dependency>


   </dependencies>



   <build>
       <finalName>SpringMVCFileUD</finalName>
       <plugins>

           <!-- Config: Maven Tomcat Plugin -->
           <!-- http://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin -->
           <plugin>
               <groupId>org.apache.tomcat.maven</groupId>
               <artifactId>tomcat7-maven-plugin</artifactId>
               <version>2.2</version>
               
               <!-- Config: contextPath and Port (Default - /SpringMVCFileUD : 8080) -->
               
               <!--
               <configuration>
                   <path>/</path>
                   <port>8899</port>
               </configuration>
               -->
           </plugin>
       </plugins>
   </build>
   
</project>

4. Cấu hình Spring MVC

SpringWebAppInitializer.java
package org.o7planning.springmvcfileud.config;

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;

public class SpringWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(ApplicationContextConfig.class);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("SpringDispatcher",
                new DispatcherServlet(appContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        // UtF8 Charactor Filter.
        FilterRegistration.Dynamic fr = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);

        fr.setInitParameter("encoding", "UTF-8");
        fr.setInitParameter("forceEncoding", "true");
        fr.addMappingForUrlPatterns(null, true, "/*");
    }

}
WebMvcConfig.java
package org.o7planning.springmvcfileud.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

     
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        // Default..
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

}
Bạn cần khai báo multipartResolverSpring BEAN. Trong Spring Bean này bạn có thể cấu hình dung lượng tối đa của file được phép tải lên.
ApplicationContextConfig.java
package org.o7planning.springmvcfileud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan("org.o7planning.springmvcfileud.*")
public class ApplicationContextConfig {

    @Bean(name = "viewResolver")
    public InternalResourceViewResolver getViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");

        return viewResolver;
    }

    @Bean(name = "multipartResolver")
    public MultipartResolver getMultipartResolver() {
        CommonsMultipartResolver resover = new CommonsMultipartResolver();
        // 1MB
        resover.setMaxUploadSize(1 * 1024 * 1024);

        return resover;
    }

}

5. Controllers & Form

MyFileUploadController.java
package org.o7planning.springmvcfileud.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.o7planning.springmvcfileud.form.MyUploadForm;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.commons.CommonsMultipartFile;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;

@Controller
public class MyFileUploadController {

   // Phương thức này được gọi mỗi lần có Submit.
   @InitBinder
   public void initBinder(WebDataBinder dataBinder) {
       Object target = dataBinder.getTarget();
       if (target == null) {
           return;
       }
       System.out.println("Target=" + target);

       if (target.getClass() == MyUploadForm.class) {
 
           // Đăng ký để chuyển đổi giữa các đối tượng multipart thành byte[]
           dataBinder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
       }
   }
 
   // GET: Hiển thị trang form upload
   @RequestMapping(value = "/uploadOneFile", method = RequestMethod.GET)
   public String uploadOneFileHandler(Model model) {

       MyUploadForm myUploadForm = new MyUploadForm();
       model.addAttribute("myUploadForm", myUploadForm);

       // Forward to "/WEB-INF/pages/uploadOneFile.jsp".
       return "uploadOneFile";
   }
 
   // POST: Sử lý Upload
   @RequestMapping(value = "/uploadOneFile", method = RequestMethod.POST)
   public String uploadOneFileHandlerPOST(HttpServletRequest request, //
           Model model, //
           @ModelAttribute("myUploadForm") MyUploadForm myUploadForm) {

       return this.doUpload(request, model, myUploadForm);

   }
 
   // GET: Hiển thị trang form upload
   @RequestMapping(value = "/uploadMultiFile", method = RequestMethod.GET)
   public String uploadMultiFileHandler(Model model) {

       MyUploadForm myUploadForm = new MyUploadForm();
       model.addAttribute("myUploadForm", myUploadForm);

       // Forward to "/WEB-INF/pages/uploadMultiFile.jsp".
       return "uploadMultiFile";
   }
 
   // POST: Sử lý Upload
   @RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
   public String uploadMultiFileHandlerPOST(HttpServletRequest request, //
           Model model, //
           @ModelAttribute("myUploadForm") MyUploadForm myUploadForm) {

       return this.doUpload(request, model, myUploadForm);

   }

   private String doUpload(HttpServletRequest request, Model model, //
           MyUploadForm myUploadForm) {

       String description = myUploadForm.getDescription();
       System.out.println("Description: " + description);

       // Thư mục gốc upload file.
       String uploadRootPath = request.getServletContext().getRealPath("upload");
       System.out.println("uploadRootPath=" + uploadRootPath);

       File uploadRootDir = new File(uploadRootPath);
       //
       // Tạo thư mục gốc upload nếu nó không tồn tại.
       if (!uploadRootDir.exists()) {
           uploadRootDir.mkdirs();
       }
       CommonsMultipartFile[] fileDatas = myUploadForm.getFileDatas();
       //
       List<File> uploadedFiles = new ArrayList<File>();
       for (CommonsMultipartFile fileData : fileDatas) {

           // Tên file gốc tại Client.
           String name = fileData.getOriginalFilename();
           System.out.println("Client File Name = " + name);

           if (name != null && name.length() > 0) {
               try {
                   // Tạo file tại Server.
                   File serverFile = new File(uploadRootDir.getAbsolutePath() + File.separator + name);

                   // Luồng ghi dữ liệu vào file trên Server.
                   BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
                   stream.write(fileData.getBytes());
                   stream.close();
                   //
                   uploadedFiles.add(serverFile);
                   System.out.println("Write file: " + serverFile);
               } catch (Exception e) {
                   System.out.println("Error Write file: " + name);
               }
           }
       }
       model.addAttribute("description", description);
       model.addAttribute("uploadedFiles", uploadedFiles);
       return "uploadResult";
   }

}
MyUploadForm.java
package org.o7planning.springmvcfileud.form;

import org.springframework.web.multipart.commons.CommonsMultipartFile;

public class MyUploadForm {

    private String description;
    
    // Upload files.
    private CommonsMultipartFile[] fileDatas;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public CommonsMultipartFile[] getFileDatas() {
        return fileDatas;
    }

    public void setFileDatas(CommonsMultipartFile[] fileDatas) {
        this.fileDatas = fileDatas;
    }
    
}

6. Views

_menu.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>

<div style="border:1px solid #ccc;padding:5px;">

  <a href="${pageContext.request.contextPath}/uploadOneFile">Upload One File</a>

  &nbsp;|&nbsp;

  <a href="${pageContext.request.contextPath}/uploadMultiFile">Upload Multi File</a>
 
 
</div>
Chú ý: Trên các form để upload dữ liệu bạn cần có thuộc tính enctype="multipart/form-data".
uploadOneFile.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Upload One File</title>
</head>
<body>
    <jsp:include page="_menu.jsp"/>
    
    <h3>Upload One File:</h3>

    <!-- MyUploadForm -->
    <form:form modelAttribute="myUploadForm" method="POST"
                        action="" enctype="multipart/form-data">

        Description:
        <br>
        <form:input path="description" style="width:300px;"/>                
        <br/><br/>  
            
        File to upload: <form:input path="fileDatas" type="file"/><br />  
        
          
        <input type="submit" value="Upload">
        
    </form:form>
    
</body>

</html>
uploadMultiFile.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Upload Multi File</title>
</head>
<body>
   <jsp:include page="_menu.jsp"/>
   
   <h3>Upload Multiple File:</h3>
   
    <!-- MyUploadForm -->
    <form:form modelAttribute="myUploadForm" method="POST"
                        action="" enctype="multipart/form-data">
        
        Description:
        <br>
        <form:input path="description" style="width:300px;"/>                
        <br/><br/>                 
    
        File to upload (1): <form:input path="fileDatas" type="file"/><br />      
        File to upload (2): <form:input path="fileDatas" type="file"/><br />    
        File to upload (3): <form:input path="fileDatas" type="file"/><br />    
        File to upload (4): <form:input path="fileDatas" type="file"/><br />    
        File to upload (5): <form:input path="fileDatas" type="file"/><br />    
        
        <input type="submit" value="Upload">
         
    </form:form>
    
    
</body>
</html>
uploadResult.jsp
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    
<html>
<head>
<meta charset="UTF-8">
<title>Upload Result</title>
</head>
<body>
    <jsp:include page="_menu.jsp"/>
   
    <h3>Uploaded Files:</h3>
    
    Description: ${description}
    
    <br/>
    
    <c:forEach items="${uploadedFiles}" var="file">
           - ${file} <br>
    </c:forEach>

</body>
</html>

7. Chạy ứng dụng

Cấu hình để chạy ứng dụng:
Nhập vào:
  • Name: Run SpringMVCFileUD
  • Base directory: ${workspace_loc:/SpringMVCFileUD}
  • Goals: tomcat7:run