개발 기록이

[웹개발] 파일기능(2) MultipartFile와 MultipartHttpServletRequest 로 파일 저장하기 본문

웹 개발/Back-end

[웹개발] 파일기능(2) MultipartFile와 MultipartHttpServletRequest 로 파일 저장하기

studyingbackhoe 2024. 4. 13. 16:20

지난 포스팅에 이어서 업로드한 파일을 자바 서버단에서 처리하는 방법에 대해 알아보려고 한다.

예전에는 주로 MultipartHttpServletRequest를 사용하여 멀티파트 요청을 처리했지만, Spring 3.1 이후부터는 MultipartFile이 도입되어 더 간편하고 효율적인 파일 업로드 처리를 할 수 있다고 한다.방식을 통해 어떻게 파일을 저장하는지 알아보자!
 
 

📌 프론트단에서 파일 업로드하는 방법 확인하기

 

[웹개발] 파일기능(1) <input type="file"> 속성과 자바스크립트로 파일 정보 보내기

파일 관련 기능 구현할 때 제대로 정리가 안 되는 것 같아서 클라이언트에서부터 서버에서 어떻게 file 값을 받고 처리하는지 정리를 해보려고 한다. 1. 속성 - 은 웹에서 사용자의 로컬 파일을 입

studyingbackhoe.tistory.com

 

1. MultipartFile[] 방식(최신 버전)

- 파일 업로드에 필요한 페이지와 설정 방법을 정리하면 다음과 같다.

1) 파일 업로드 폼 페이지 만들기 (formPage.jsp)

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <h2 class="mt-5 mb-3 text-center">파일 업로드하기</h2>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-6">
                <form action="fileUpload.do" method="post" enctype="multipart/form-data" class="border p-4">
                    <div class="form-group">
                        <label for="fileUpload">파일 선택</label>
                        <input type="file" class="form-control-file" id="fileUpload" name="files" multiple>
                    </div>
                    <button type="submit" class="btn btn-primary">업로드</button>
                </form>
            </div>
        </div>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

2) pom.xml 

- 파일 업로드를 처리에 필요한 commons-fileupload dependency 추가한다.

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

3) dispatcher-context.xml

- Spring MVC에서 파일 업로드 기능을 사용할 수 있도록 CommonsMultipartResolver 설정을 추가하고 업로드 파일의 최대 크기를 제한하는 bean을 추가한다.

<!-- 파일 업로드를 위한 CommonsMultipartResolver 설정 -->
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 최대 업로드 파일 크기 설정 -->
    <beans:property name="maxUploadSize" value="10485760"/> <!-- 10MB -->
</beans:bean>

 

4) controller.java

// 파일 업로드 페이지 이동
@RequestMapping(value = "/formPage.do", method = RequestMethod.GET)
public String formPage() {
    return "formPage";
}


// 파일 업로드
@RequestMapping(value = "/fileUpload.do", method = RequestMethod.POST)
public String fileUpload(@RequestParam("files") MultipartFile[] files) {

    for (MultipartFile file : files) {
        if (!file.isEmpty()) {
            try {
                // 파일 저장 경로
                String uploadDir = "C:/fileUpload/"; 
                String filePath = uploadDir + file.getOriginalFilename();

                // 파일 저장
                file.transferTo(new File(filePath));
                
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return "success"; // 파일 업로드 성공 시 success.jsp 페이지로 이동하기
}

 
1. MultipartFile
Spring 프레임워크에서 파일 업로드를 처리하기 위한 인터페이스이다. Spring MVC와 Spring Boot 애플리케이션에서 웹 요청으로 전송된 파일을 처리할 수 있도록 해준다.
 
formPage.jsp 에서 <input type="file" name="files" ...>로 파일값을 넘기기 때문에 java에서 files라는 이름으로 파일 파라미터를 받아온다. 그리고 여러 개의 파일정보를 받아오기 위해 MultipartFile이 아닌 MultipartFile[] 과 같이 배열 형태로 값을 받아올 수 있도록 한다. formPage.jsp에서 파일 3개를 올렸다고 가정했을 때 디버깅을 통해  files 값을 확인해보면 3개의 값을 가져오는 것을 확인할 수 있다.

 
파일 업로드에 성공하면 success 페이지로 이동하게 된다!

2. MultipartHttpServletRequest 방식 (이전 버전)

 

1) controller.java

@RequestMapping(value = "/fileUpload2.do", method = RequestMethod.POST)
public String fileUpload2(MultipartHttpServletRequest multipartRequest) {

    String uploadDir = "C:/fileUpload/";

    MultiValueMap<String, MultipartFile> files = multipartRequest.getMultiFileMap();

    Iterator<Map.Entry<String, List<MultipartFile>>> iter = files.entrySet().iterator();
    List<MultipartFile> multipartFileList = new ArrayList();

    // 파일들을 순회하면서 처리
    while (iter.hasNext()) {
        Map.Entry<String, List<MultipartFile>> entry = iter.next();
        List<MultipartFile> fileList = entry.getValue();

        // 각 파일들을 multipartFileList 리스트에 추가
        for (MultipartFile file : fileList) {
            if (file.isEmpty()) continue;

            multipartFileList.add(file);
        }
    }

    // 파일 저장
    for (MultipartFile file : multipartFileList) {
        try {
            String filePath = uploadDir + file.getOriginalFilename();
            file.transferTo(new File(filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return "success";
}

 
1. MultipartHttpServletRequest
Spring에서 멀티파트 요청을 처리하기 위한 인터페이스를 의미하며, 멀티파트 데이터(파일 업로드 등)를 처리할 수 있도록 해준다.
 
2. getMultiFileMap()
MultipartHttpServletRequest로 받아온 파일값을 가져오는 메서드다. 반환형은 MultiValueMap<String, List<MultipartFile>> 이며, 이 메서드를 통해 업로드된 파일들을 요청 파라미터 이름에 따라 그룹화하여 가져올 수 있다.
 
3. MultiValueMap
여러 개의 값을 가진 Map 구조로, 하나의 키(key)에 여러 개의 값을 연결할 수 있다. 이 구조를 통해 하나의 요청 파라미터에 대응하는 여러 파일을 관리할 수 있다.

4. files.entrySet()
MultiValueMap<String, List<MultipartFile>> 에서 각 키(요청 파라미터 이름 즉, 여기서는 "files")에 대응하는 파일 리스트 값을 가져오는 역할을 한다.
 
5. files.entrySet().iterator()
files.entrySet() 를 통해 가져온 파일 리스트를 순회하고 접근할 수 있는 Iterator를 반환한다. 이 Iterator를 사용하여 각 요청 파라미터에 대응하는 파일 리스트를 순회하고 처리할 수 있다.
 
6. Map.Entry<String, List<MultipartFile>>
Map.Entry는 맵의 각 엔트리(키-값 쌍)를 나타내는 인터페이스이며, 각 엔트리는 특정 키(key)와 해당 키에 대응하는 값(value)으로 구성된다. getKey()getValue() 메서드를 사용하여 엔트리의 키와 값에 접근할 수 있다.
 
7. Iterator<Map.Entry<String, List<MultipartFile>>>
Iterator가 순회하는 요소의 타입을 명시하는 것으로, Iterator가 다음 요소를 반환할 때마다 Map.Entry<String, List<MultipartFile>> 형태의 요소를 반환한다는 의미를 나타낸다. 이를 통해 Iterator를 사용하여 맵의 각 엔트리를 순회하고 다룰 수 있게 된다.
 
그래서 iter.hasNext()를 통해 파일 리스트를 순회하고  List<MultipartFile> multipartFileList = new ArrayList(); 로 생성한 multipartFileList에 저장하여 업로드한 파일을 저장하게 된다.
 
 
MultipartHttpServletRequest 방식은 내용 정리하면서도 복잡해서 앞으로 MultipartFile 방식으로 사용해야겠다... 🙂
 

폴더 아이콘 제작자: Freepik - Flaticon

출처 :  OpenAI ChatGPT (https://openai.com), https://chung-develop.tistory.com/2