Java | Spring

[Spring Boot] Bank App (13) 파일 업로드 1단계 (Multipart)

@leem 2025. 2. 25. 15:16

멀티파트(Multipart)의 개념과 HTTP 요청 방식 이해
Spring Boot에서 멀티파트 요청 처리하기
회원가입 시 파일 업로드 기능 구현
전체 코드 흐름과 실행 과정 확인


1. 멀티파트(Multipart)

멀티파트(Multipart)는 웹에서 파일을 업로드할 때 사용하는 데이터 전송 방식입니다.
"멀티파트"라는 이름에서 알 수 있듯이, 하나의 HTTP 요청에 여러 개의 데이터를 포함할 수 있습니다.

HTTP 요청의 기본 구조
HTTP 요청은 크게 세 가지 부분으로 구성됩니다.

[1] 시작 라인 (Start Line)  
[2] 헤더 (Headers)  
[3] 바디 (Body)

 1.1 일반적인 HTTP 요청 예시

텍스트 기반 요청 (단순 POST 요청)

 
POST /example HTTP/1.1
Host: example.com
Content-Type: text/plain
Content-Length: 13

Hello, World!

위 요청은 텍스트 데이터만 포함된 요청입니다.

바이너리 기반 요청 (파일 업로드 요청)

POST /example HTTP/1.1
Host: example.com
Content-Type: application/octet-stream
Content-Length: 5

\x48\x65\x6C\x6C\x6F

이 요청은 바이너리 데이터를 전송하는 요청입니다.


📌 1.2 멀티파트 요청 (파일과 데이터를 동시에 전송)

파일을 업로드하려면 멀티파트 요청(multipart/form-data) 방식을 사용해야 합니다.

파일 업로드 요청 예시

POST /submitForm HTTP/1.1
Host: tenco.com
Content-Type: multipart/form-data; boundary="boundary123"
Content-Length: [계산된 총 길이]

--boundary123
Content-Disposition: form-data; name="username"

길동
--boundary123
Content-Disposition: form-data; name="password"

1234
--boundary123
Content-Disposition: form-data; name="binaryData"; filename="data.bin"
Content-Type: application/octet-stream

01010101 01101100 01101100 01101111
--boundary123--

💡 여기서 중요한 부분

  •  boundary="boundary123" → 요청의 각 부분을 구분하는 역할
  • 텍스트 데이터(username, password)파일(binaryData)을 함께 전송

2. Spring Boot에서 파일 업로드 처리하기 

Spring Boot에서는 파일 업로드 기능을 제공하는 MultipartResolver 인터페이스를 통해 멀티파트 요청을 쉽게 처리할 수 있습니다.

Spring Boot에서는 별도 설정 없이도 멀티파트 지원이 자동 활성화됨
업로드 제한을 조정하려면 application.yml에서 설정 가능


2.1 application.yml 설정 (파일 크기 제한)

spring:
  servlet:
    multipart:
      max-file-size: 20MB   # 파일 1개 최대 크기
      max-request-size: 20MB # 요청 전체 크기 제한
  • max-file-size: 단일 파일 최대 크기 (기본값: 1MB)
  • max-request-size: 전체 요청 크기 제한 (기본값: 10MB)

🚨 설정을 하지 않으면 기본적으로 1MB 이상의 파일을 업로드할 수 없습니다!


2.2 파일 업로드 폼 만들기 (JSP)

📌 회원가입 시 파일 업로드 기능 추가
📌 폼 태그에서 enctype="multipart/form-data" 설정 필수!

<form action="/user/sign-up" method="post" enctype="multipart/form-data">
    <label for="username">Username:</label>
    <input type="text" name="username" required>

    <label for="password">Password:</label>
    <input type="password" name="password" required>

    <label for="file">Profile Image:</label>
    <input type="file" name="mFile">  

    <button type="submit">회원가입</button>
</form>
  • 파일을 전송하려면 반드시 enctype="multipart/form-data"를 추가해야 함!

3. 회원가입 시 파일 업로드 기능 구현하기

회원가입할 때 파일(프로필 이미지)도 함께 저장하는 기능을 구현해보겠습니다.


3.1 DTO 클래스 (SignUpDTO.java)

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SignUpDTO {
    private String username;
    private String password;
    private String fullname;
    private MultipartFile mFile;  // 업로드된 파일 정보
    private String originFileName;
    private String uploadFileName;

    // DTO → Entity 변환
    public User toUser() {
        return User.builder()
                .username(this.username)
                .password(this.password)
                .fullname(this.fullname)
                .originFileName(originFileName)
                .uploadFileName(uploadFileName)
                .build();
    }
}
  • 업로드된 파일(MultipartFile)을 DTO에서 관리
  • DB 저장을 위해 DTO → User 객체로 변환

3.2 User 엔티티 (User.java)

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private String originFileName;  // 원본 파일명
    private String uploadFileName;  // 서버 저장 파일명
    private String fullname;
    private Timestamp createdAt;
}
  • originFileName: 사용자가 업로드한 원본 파일명
  • uploadFileName: 서버에 저장될 파일명

3.3 파일 업로드 처리 (UserService.java)

@Transactional
public void createUser(SignUpDTO dto) {
    if (!dto.getMFile().isEmpty()) {
        String[] fileNames = uploadFile(dto.getMFile());
        dto.setOriginFileName(fileNames[0]);
        dto.setUploadFileName(fileNames[1]);
    }
    userRepository.insert(dto.toUser());
}

// 파일 저장 메서드
private String[] uploadFile(MultipartFile file) {
    String uploadFileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
    File destination = new File("uploads/" + uploadFileName);
    
    try {
        file.transferTo(destination);
    } catch (IOException e) {
        throw new RuntimeException("파일 업로드 실패", e);
    }
    
    return new String[] {file.getOriginalFilename(), uploadFileName};
}
  • 파일명을 랜덤으로 생성하여 중복 방지
  • 서버 폴더에 저장 후 파일명 리턴
  •  

 

Multipart는 텍스트와 파일을 함께 전송할 수 있는 방식
Spring Boot에서 파일 업로드는 MultipartFile로 쉽게 처리 가능
회원가입 시 프로필 이미지 업로드 기능 구현 완료!