본문 바로가기
Spring/SpringBoot

[SpringBoot] 파일 업로드 - MultipartFile(With. React)

by J4J 2021. 5. 27.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 부트에서 multipartFile을 이용한 파일 업로드 방법에 대해 적어보는 시간을 가져보려고 합니다.

 ※ legacy에서 multipartFile을 이용한 파일 업로드하는 방법이 궁금하신 분은 여기를 참고해주세요.

 

 

반응형

 

 

부트 설정 및 코드

 

[ 1. application.yml에 multipart 설정해주기 ]

 

spring:
  servlet:
    multipart: 
      max-file-size: 20MB  #최대 파일 사이즈를 20MB로 지정

 

 

참고적으로 max-file-size 말고도 더 다양한 설정값들이 있으니 한 번 확인해보시는 것도 좋을 것 같습니다.

 

 

[ 2. controller단 ]

 

package com.spring.multipart.controller;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Random;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.spring.multipart.dto.FoodDto;

@RestController
public class MultipartController {
	
	@PostMapping("/uploadFiles")
	public ResponseEntity<Object> uploadFiles(MultipartFile[] multipartFiles, String stringFoodDto) { // 파라미터의 이름은 client의 formData key값과 동일해야함
		String UPLOAD_PATH = "F:\\myUpload"; // 업로드 할 위치
		
		try {
			// 객체는 client에서 직렬화를 하여 전달
			FoodDto foodDto = new ObjectMapper().readValue(stringFoodDto, FoodDto.class); // String to Object
			System.out.println("foodDto= " + foodDto);
			
			for(int i=0; i<multipartFiles.length; i++) {
				MultipartFile file = multipartFiles[i];
                
				String fileId = (new Date().getTime()) + "" + (new Random().ints(1000, 9999).findAny().getAsInt()); // 현재 날짜와 랜덤 정수값으로 새로운 파일명 만들기
				String originName = file.getOriginalFilename(); // ex) 파일.jpg
				String fileExtension = originName.substring(originName.lastIndexOf(".") + 1); // ex) jpg
				originName = originName.substring(0, originName.lastIndexOf(".")); // ex) 파일
				long fileSize = file.getSize(); // 파일 사이즈
				
				File fileSave = new File(UPLOAD_PATH, fileId + "." + fileExtension); // ex) fileId.jpg
				if(!fileSave.exists()) { // 폴더가 없을 경우 폴더 만들기
					fileSave.mkdirs();
				}
                
				file.transferTo(fileSave); // fileSave의 형태로 파일 저장
				
				System.out.println("fileId= " + fileId);
				System.out.println("originName= " + originName);
				System.out.println("fileExtension= " + fileExtension);
				System.out.println("fileSize= " + fileSize);
			}
		} catch(IOException e) {
			return new ResponseEntity<Object>(null, HttpStatus.CONFLICT);
		}
		
		return new ResponseEntity<Object>("Success", HttpStatus.OK);
	}
}

 

 

 

 

리액트 코드

 

import * as React from 'react';
import axios from 'axios';

const FileUpload = (): JSX.Element => {
    const fileList: File[] = []; // 업로드한 파일들을 저장하는 배열

    const onSaveFiles = (e: React.ChangeEvent<HTMLInputElement>) => {
        const uploadFiles = Array.prototype.slice.call(e.target.files); // 파일선택창에서 선택한 파일들

        uploadFiles.forEach((uploadFile) => {
            fileList.push(uploadFile);
        });
    };

    const onFileUpload = () => {
        const formData = new FormData();

        fileList.forEach((file) => {
            // 파일 데이터 저장
            formData.append('multipartFiles', file);
        });

        // 객체
        const foodDto = {
            name: '피자',
            price: 13500,
        };

        formData.append('stringFoodDto', JSON.stringify(foodDto)); // 직렬화하여 객체 저장

        axios.post('http://localhost:8080/uploadFiles', formData);
    };

    return (
        <div>
            <input type="file" multiple /* 파일 여러개 선택 가능하게 하기 */ onChange={onSaveFiles} />
            <button onClick={onFileUpload}>파일 업로드</button>
        </div>
    );
};

export default FileUpload;

 

 

 

 

실행 화면

 

코드를 위와 같이 작성을 하고 리액트를 실행시키면 다음과 같이 간단한 파일 업로드 페이지가 나옵니다.

 

리액트 실행화면

 

 

 

그리고 파일 선택이라는 버튼을 누르게 되면 다음과 같이 파일을 선택하는 화면이 나오게 됩니다.

 

파일 선택 화면

 

 

 

화면에 보이는 사진 파일을 모두 선택하여 열기를 누르면 다음과 같이 파일이 올라간 것을 확인할 수 있습니다.

 

파일 선택된 화면

 

 

 

다음으로 파일 업로드 버튼을 누르게 되면 스프링에 데이터가 넘어가게 되고 콘솔창에 다음과 같은 문구가 출력이 됩니다.

 

스프링 콘솔창

 

 

 

 

직렬화하여 같이 전달했던 객체도 확인이 되고 또한 파일들도 각자의 fileId를 가지며 정상적으로 처리된 것으로 보입니다.

 

정상 처리가 되었다면 UPLOAD_PATH로 지정한 위치에 해당 파일들이 저장이 되어있어야 합니다.

 

저같은 경우는 다음과 같이 파일이 저장되어 있는 것이 확인되고 있습니다.

 

업로드 경로에 저장된 파일들

 

 

 

 

 

이상으로 부트에서 multipartFile을 이용한 파일 업로드 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

728x90
반응형

댓글