1. 개요

이전 기사에서 우리 는 양식 처리 의 기본소개하고 Spring MVC 양식 태그 라이브러리탐색했습니다 .

이 기사에서는 웹 애플리케이션에서 멀티 파트 (파일 업로드) 지원위해 Spring이 제공하는 것에 중점을 둡니다 .

Spring은 플러그 형 MultipartResolver 객체 로이 멀티 파트 지원을 가능하게 합니다. 프레임 워크는 Commons FileUpload함께 사용하기위한 하나의 MultipartResolver 구현을 제공 하고 다른 하나는 Servlet 3.0 멀티 파트 요청 구문 분석 함께 사용하기 위해 제공합니다 .

MultipartResolver를 구성한 후 단일 파일과 여러 파일을 업로드하는 방법을 볼 수 있습니다.

Spring Boot 에 대해서도 다룰 것입니다.

2. 공용 파일 업로드

CommonsMultipartResolver 를 사용하여 파일 업로드를 처리 하려면 다음 의존성을 추가해야합니다.

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

이제 CommonsMultipartResolver 빈을 Spring 구성에 정의 할 수 있습니다.

MultipartResolver업로드의 최대 크기와 같은 속성을 정의 하는 일련의 set 메서드 와 함께 제공됩니다 .

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(100000);
    return multipartResolver;
}

여기서 우리 는 Bean 정의 자체에서 CommonsMultipartResolver의 다른 속성을 제어해야 합니다.

3. Servlet 3.0 사용

Servlet 3.0 멀티 파트 구문 분석 을 사용 하려면 응용 프로그램 몇 개를 구성해야합니다. 먼저 DispatcherServlet 등록 에서 MultipartConfigElement 를 설정해야합니다 .

public class MainWebAppInitializer implements WebApplicationInitializer {

    private String TMP_FOLDER = "/tmp"; 
    private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; 
    
    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        
        ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(
          new GenericWebApplicationContext()));

        appServlet.setLoadOnStartup(1);
        
        MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, 
          MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
        
        appServlet.setMultipartConfig(multipartConfigElement);
    }
}

에서 MultipartConfigElement의 객체, 우리는 저장 위치, 개별 파일의 최대 크기 (하나의 요청에서 여러 파일의 경우) 최대 요청 크기, 파일 업로드 진행 상황이 저장 위치에 플러시되는 크기를 구성했습니다.

CommonsMultipartResolver 의 경우 처럼 Servlet 3.0 에서는 MultipartResolver에 등록 할 수 없으므로 이러한 설정은 servlet 등록 수준에서 적용되어야합니다 .

이 작업이 완료되면 Spring 구성에 StandardServletMultipartResolver추가 할 수 있습니다 .

@Bean
public StandardServletMultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}

4. 파일 업로드

파일을 업로드하기 위해 type = 'file' 과 함께 HTML 입력 태그를 사용하는 간단한 양식을 작성할 수 있습니다 .

업로드 처리 구성에 관계없이 양식의 인코딩 속성을 multipart / form-data 로 설정해야합니다 . 이를 통해 브라우저는 양식을 인코딩하는 방법을 알 수 있습니다.

<form:form method="POST" action="/spring-mvc-xml/uploadFile" enctype="multipart/form-data">
    <table>
        <tr>
            <td><form:label path="file">Select a file to upload</form:label></td>
            <td><input type="file" name="file" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form>

업로드 된 파일을 저장하기 위해 MultipartFile 변수를 사용할 수 있습니다 . 컨트롤러 메서드 내부의 요청 매개 변수에서이 변수를 검색 할 수 있습니다.

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String submit(@RequestParam("file") MultipartFile file, ModelMap modelMap) {
    modelMap.addAttribute("file", file);
    return "fileUploadView";
}

의 MultipartFile 클래스는 업로드 된 파일에 대한 세부 사항에 대한 액세스 제공 등 파일 이름, 파일 형식, 등을. 간단한 HTML 페이지를 사용하여이 정보를 표시 할 수 있습니다.

<h2>Submitted File</h2>
<table>
    <tr>
        <td>OriginalFileName:</td>
        <td>${file.originalFilename}</td>
    </tr>
    <tr>
        <td>Type:</td>
        <td>${file.contentType}</td>
    </tr>
</table>

5. 여러 파일 업로드

단일 요청으로 여러 파일을 업로드하려면 양식에 여러 입력 파일 필드를 넣으면됩니다.

<form:form method="POST" action="/spring-mvc-java/uploadMultiFile" enctype="multipart/form-data">
    <table>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>

MultipartFile 배열로 액세스 할 수 있도록 각 입력 필드가 동일한 이름을 갖도록주의해야합니다 .

@RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
public String submit(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) {
    modelMap.addAttribute("files", files);
    return "fileUploadView";
}

이제 해당 배열을 반복하여 파일 정보를 표시 할 수 있습니다.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <head>
        <title>Spring MVC File Upload</title>
    </head>
    <body>
        <h2>Submitted Files</h2>
        <table>
            <c:forEach items="${files}" var="file">    
                <tr>
                    <td>OriginalFileName:</td>
                    <td>${file.originalFilename}</td>
                </tr>
                <tr>
                    <td>Type:</td>
                    <td>${file.contentType}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
</html>

6. 추가 양식 데이터가있는 파일 업로드

업로드중인 파일과 함께 추가 정보를 서버로 보낼 수도 있습니다. 다음 양식에 필수 필드 만 포함하면됩니다.

<form:form method="POST" 
  action="/spring-mvc-java/uploadFileWithAddtionalData"
  enctype="multipart/form-data">
    <table>
        <tr>
            <td>Name</td>
            <td><input type="text" name="name" /></td>
        </tr>
        <tr>
            <td>Email</td>
            <td><input type="text" name="email" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="file" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form:form>

컨트롤러에서 @RequestParam 어노테이션을 사용하여 모든 양식 데이터를 가져올 수 있습니다 .

@PostMapping("/uploadFileWithAddtionalData")
public String submit(
  @RequestParam MultipartFile file, @RequestParam String name,
  @RequestParam String email, ModelMap modelMap) {

    modelMap.addAttribute("name", name);
    modelMap.addAttribute("email", email);
    modelMap.addAttribute("file", file);
    return "fileUploadView";
}

이전 섹션과 마찬가지로 JSTL 태그가 있는 HTML 페이지를 사용 하여 정보를 표시 할 수 있습니다.

모델 클래스의 모든 양식 필드를 캡슐화 하고 컨트롤러에서 @ModelAttribute 어노테이션을 사용할 수도 있습니다 . 이것은 파일과 함께 많은 추가 필드가있을 때 유용합니다. 코드를 살펴 보겠습니다.

public class FormDataWithFile {

    private String name;
    private String email;
    private MultipartFile file;

    // standard getters and setters
}
@PostMapping("/uploadFileModelAttribute")
public String submit(@ModelAttribute FormDataWithFile formDataWithFile, ModelMap modelMap) {

    modelMap.addAttribute("formDataWithFile", formDataWithFile);
    return "fileUploadView";
}

7. 스프링 부트 파일 업로드

Spring Boot를 사용하는 경우 지금까지 본 모든 것이 여전히 적용됩니다.

그러나 Spring Boot를 사용하면 번거 로움없이 모든 것을 구성하고 시작할 수 있습니다.

특히, 우리가 의존성에 웹 모듈을 포함한다면 Boot가 그것을 등록하고 구성 할 것이기 때문에 서블릿을 구성 할 필요가 없습니다 .

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.1.8.RELEASE</version>
</dependency>

Maven Central 에서 최신 버전의 spring-boot-starter-web찾을 수 있습니다 .

최대 파일 업로드 크기를 제어하려면 application.properties를 편집 할 수 있습니다 .

spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB

또한 파일 업로드 활성화 여부와 파일 업로드 위치를 제어 할 수 있습니다.

spring.servlet.multipart.enabled=true
spring.servlet.multipart.location=${java.io.tmpdir}

우리가 사용했던 것을 참고 $ {java.io.tmpdir을}을 (를) 우리가 다른 운영 체제에 대한 임시 위치를 사용할 수 있도록하는 업로드 위치를 정의 할 수 있습니다.

8. 결론

이 기사에서는 Spring에서 멀티 파트 지원을 구성하는 다양한 방법을 살펴 보았습니다. 이를 사용하여 웹 애플리케이션에서 파일 업로드를 지원할 수 있습니다.

이 예제의 구현은 GitHub 프로젝트 에서 찾을 수 있습니다 . 프로젝트가 로컬에서 실행되면 http : // localhost : 8080 / spring-mvc-java / fileUpload에서 양식 예제에 액세스 할 수 있습니다.