Spring MVCファイルのアップロード例 - Commons FileUpload

Spring MVCファイルのアップロード例– Commons FileUpload

この記事では、CommonsMultipartResolverを使用してSpring MVCWebアプリケーションでファイルのアップロードを処理する方法を説明します。

使用ツール:

  1. Spring 4.3.5.RELEASE

  2. commons-fileupload 1.3.2

  3. メーベン3

  4. Tomcat 7または8およびJetty 8、9

Note
StandardServletMultipartResolver –サーブレット3.0マルチパートリクエスト解析を使用したファイルアップロードについては、このSpring MVC file upload exampleを参照してください。

1. プロジェクト構造

標準のMavenプロジェクト構造。

spring-multi-file-upload-example-directory

2. プロジェクトの依存関係

2.1 You need commons-fileupload.jar

pom.xml

    
    
        commons-fileupload
        commons-fileupload
        1.3.2
    

2.2 Complete Maven Pom file.

pom.xml


    4.0.0
    com.example
    spring-mvc-file-upload
    war
    1.0-SNAPSHOT
    Spring MVC file upload

    
        1.8
        4.3.5.RELEASE
        1.2
        3.1.0
        1.3.2
        1.1.3
        1.7.12
    

    

        
            org.springframework
            spring-webmvc
            ${spring.version}
            
                
                    commons-logging
                    commons-logging
                
            
        

        
            javax.servlet
            jstl
            ${jstl.version}
        

        
        
            javax.servlet
            javax.servlet-api
            ${servletapi.version}
            provided
        

        
        
            org.slf4j
            jcl-over-slf4j
            ${jcl.slf4j.version}
        

        
            ch.qos.logback
            logback-classic
            ${logback.version}
        

        
        
            commons-fileupload
            commons-fileupload
            ${commons.fileupload.version}
        

    

    
        

            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.3
                
                    ${jdk.version}
                    ${jdk.version}
                
            

            
            
                org.eclipse.jetty
                jetty-maven-plugin
                9.2.11.v20150529
                
                    10
                    
                        /spring4upload
                    
                
            

            
            
                org.apache.maven.plugins
                maven-eclipse-plugin
                2.9
                
                    true
                    true
                    2.0
                    /spring4upload
                
            

        
    

ターミナル

$ mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring MVC file upload 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ spring-mvc-file-upload ---
[INFO] com.example:spring-mvc-file-upload:war:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-webmvc:jar:4.3.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.3.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:4.3.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:4.3.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-core:jar:4.3.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-expression:jar:4.3.5.RELEASE:compile
[INFO] |  \- org.springframework:spring-web:jar:4.3.5.RELEASE:compile
[INFO] +- javax.servlet:jstl:jar:1.2:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.7.12:compile
[INFO] +- ch.qos.logback:logback-classic:jar:1.1.3:compile
[INFO] |  \- ch.qos.logback:logback-core:jar:1.1.3:compile
[INFO] \- commons-fileupload:commons-fileupload:jar:1.3.2:compile
[INFO]    \- commons-io:commons-io:jar:2.2:compile

3. CommonsMultipartResolver

multipartResolverBeanを作成します。

SpringWebMvcConfig.java

package com.example;

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.example"})
public class SpringWebMvcConfig extends WebMvcConfigurerAdapter {

    private int maxUploadSizeInMb = 5 * 1024 * 1024; // 5 MB

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Bean
    public CommonsMultipartResolver multipartResolver() {

        CommonsMultipartResolver cmr = new CommonsMultipartResolver();
        cmr.setMaxUploadSize(maxUploadSizeInMb * 2);
        cmr.setMaxUploadSizePerFile(maxUploadSizeInMb); //bytes
        return cmr;

    }

}

完了、ファイルのアップロード設定は適切に設定されています。

4. ServletInitializer

標準的なサーブレット初期化子、ここでは特別なものはありません。

MyWebInitializer.java

package com.example;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[]{SpringWebMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected Class[] getRootConfigClasses() {
        return null;
    }

}

5. スプリングコントローラー

5.1 The uploaded files will map to MultipartFile

UploadController.java

package com.example.controller;

import com.example.model.UploadForm;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
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;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.StringJoiner;

@Controller
public class UploadController {

    // save uploaded file to this folder
    private static String UPLOADED_FOLDER = "F://temp//";

    @GetMapping("/")
    public String index() {
        return "upload";
    }

    @PostMapping("/upload")
    public String multiFileUpload(@ModelAttribute UploadForm form,
                                  RedirectAttributes redirectAttributes) {

        StringJoiner sj = new StringJoiner(" , ");

        for (MultipartFile file : form.getFiles()) {

            if (file.isEmpty()) {
                continue; //next pls
            }

            try {

                byte[] bytes = file.getBytes();
                Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
                Files.write(path, bytes);

                sj.add(file.getOriginalFilename());

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        String uploadedFileName = sj.toString();
        if (StringUtils.isEmpty(uploadedFileName)) {
            redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
        } else {
            redirectAttributes.addFlashAttribute("message", "You successfully uploaded '" + uploadedFileName + "'");
        }

        return "redirect:/uploadStatus";

    }

    @GetMapping("/uploadStatus")
    public String uploadStatus() {
        return "uploadStatus";
    }

}

5.2 Maps HTML values into this model.

UploadForm.java

package com.example.model;

import org.springframework.web.multipart.MultipartFile;

public class UploadForm {

    MultipartFile[] files;

    public MultipartFile[] getFiles() {
        return files;
    }

    public void setFiles(MultipartFile[] files) {
        this.files = files;
    }

}

6. Spring JSPビュー

upload.jsp

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



Spring MVC multi files upload example





uploadStatus.jsp



Upload Status

Message : ${message}

7. 最大アップロードサイズを超えました

最大アップロードサイズ超過例外を処理するために、@ControllerAdviceを宣言し、MaxUploadSizeExceededExceptionをキャッチします

GlobalExceptionHandler.jsp

package com.example.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@ControllerAdvice
public class GlobalExceptionHandler {

    //commons-fileupload
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public String handleError2(MaxUploadSizeExceededException e, RedirectAttributes redirectAttributes) {

        redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
        return "redirect:/uploadStatus";

    }

}

8. DEMO

8.1 Get the source code below and test with the embedded Jetty server mvn jetty:run. コンテキストは/spring4uploadです

ターミナル

project $ mvn jetty:run
//...
[INFO] Started o.e.j.m.p.JettyWebAppContext@341672e{/spring4upload,
    file:/SpringMVCUploadExample/src/main/webapp/,AVAILABLE}{file:/SpringMVCUploadExample/src/main/webapp/}
[WARNING] !RequestLog
[INFO] Started ServerConnector@3ba1308d{HTTP/1.1}{0.0.0.0:8080}
[INFO] Started @3743ms
[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 10 seconds.

8.2 Access http://localhost:8080/spring4upload , select a few of files and upload it.

spring-multi-file-upload-example1

8.3 Result.

spring-multi-file-upload-example2

8.3 If you upload a total file size bigger than 10mb, this exception page will be displayed.

spring-multi-file-upload-example-max-size

Connection Reset
WebアプリをTomcatにデプロイし、ファイルサイズ超過の例外をキャッチできない場合、TomcatのmaxSwallowSize設定が原因である可能性があります。 これを読んでください–Spring file upload and connection reset issue

8. ソースコードをダウンロード

ダウンロード–spring-file-upload-commons-fileupload.zip(5 KB)