(SpringBoot) 파일 업로드 구현

파일 업로드하다

파일 업로드는 내부적으로 구현해야 하는 기능이 많기 때문에 여러 측면을 고려해야 합니다.

또한 사용자의 편의를 위해 업로드 시 드래그 앤 드롭 기능(JS), 첨부파일 확인(Server), 파일 전송 진행(JS), 예외 처리 등의 다양한 기능을 추가할 수 있습니다.

Servlet 버전이 3.0 미만인 경우 commons-fileupload 라이브러리를 추가해야 하지만 3.0 이후에는 자체적으로 파일 업로드를 지원합니다.

Servlet 3.0 이전 버전의 경우 다음을 추가하십시오.

더보기

– pom.xml 구성

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

서블릿 컨텍스트 설정

<!
-- 파일업로드--> <!
-- 반드시 id를 multipartResolver 선언해야한다.

<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!
-- 최대업로드 가능한 바이트크기 --> <beans:property name="maxUploadSize" value="52428800" /> <!
-- defaultEncoding --> <beans:property name="defaultEncoding" value="utf-8" /> </beans:bean>

Spring Boot에서 프로젝트를 구동하는 WAS(Web Application Server)의 버전이 낮거나 non-WAS 환경인 경우

별도의 라이브러리를 추가해야 합니다.

Spring Boot의 내장 tomcat을 사용한다면 별도의 라이브러리를 추가하지 않아도 사용할 수 있습니다.

1. 업로드 전 설정

Spring Boot는 application.properties에서 간단한 구성이 필요합니다.

######## 파일업로드 설정 ########
# 1. 파일업로드 가능 여부 설정 true : 가능, false : 불가
spring.servlet.multipart.enabled = true
# 2. 파일 하나의 최대 용량
spring.servlet.multipart.max-file-size = 10MB
# 3. 업로드 가능한 최대 용량
spring.servlet.multipart.max-request-size = 50MB
# 4. 업로드된 파일이 저장될 임시저장경로
project.uploadpath = C:\\Users\\User\\Desktop\\Study\\SpringBoot\\upload

2. 파일 업로드

파일을 업로드하는 방법에는 여러 가지가 있습니다.

아래의 예시는 업로드된 파일을 하드디스크에 저장하는 모든 방법인데, 하드디스크 외에도 DB, 클라우드 등 다양한 방법으로 저장할 수 있습니다.

파일 업로드 입력 태그의 type 속성에 파일을 지정하여 파일을 업로드할 수 있습니다.

폼 태그에 있어야 합니다.

암호화 유형 특성 멀티파트/폼 데이터 로 설정해야 합니다

enctype 속성?

enctype 속성은 양식 데이터가 서버로 전송될 때 인코딩되는 방식을 지정합니다.

쿼리 문자열을 추가하는 GET 메소드에서는 enctype 속성을 사용할 수 없으며 POST 메소드에서 전달해야 합니다.

  • application/x-www-form-urlencoded
    이것은 기본 속성이며 모든 문자가 서버로 전송되기 전에 인코딩됨을 의미합니다.

  • 텍스트/일반
    공백을 ‘+’ 기호로 변환하고 나머지 문자는 인코딩하지 마십시오.
  • 멀티파트/폼 데이터
    어떤 문자도 인코딩하지 않으며 주로 다음에 사용됩니다.


    요소는 파일 또는 이미지를 서버로 보냅니다.

1) 단일 파일 업로드

– HTML 작성

<!
-- 단일파일 업로드 --> <form action="upload_ok" method="post" enctype="multipart/form-data"> <input type="file" name="file"><br/> <input type="submit" value="업로드"><br/> </form>

-컨트롤러 만들기

컨트롤러의 경로에 따라 요청을 처리하려면 먼저 다음 작업을 수행해야 합니다.

  • 파일이 저장된 경로 검색(@Value 주석을 사용하여 application.properties에서 생성된 경로 가져오기)
  • 파일 생성 시 날짜별 폴더 생성 -> 저장할 수 있는 파일의 최대 개수가 정해져 있기 때문에 최대 개수를 초과하지 않도록 날짜별로 폴더를 생성합니다.


    파일이 생성될 때 application.properties에서 호출된 파일을 보관할 경로를 반환합니다.

// application.properties 에 작성한 파일 임시저장경로를 불러와 String으로 저장
    @Value("${project.uploadpath}")
	private String uploadpath;
    
//  파일 생성 시 날짜 별로 폴더를 생성하는 메서드, 파일생성 후 파일이 저장될 경로를 반환시킨다.

public String makeDir() { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); String now = sdf.format(date); String path = uploadpath + "\\" + now; //uploadpath = application.properties에서 지정한 경로 File file = new File(path); if(file.exists() == false) { //파일이 존재하지 않은 경우에만 폴더생성 file.mkdir(); } return path; }

통과하다

요소가 전달한 파일은 @RequestParam 주석을 통해 MultipartFIle 인스턴스에 저장됩니다.

멀티파트 파일?

사용자가 업로드한 파일을 나타내는 데 사용되는 인터페이스로, 파일 정보를 얻기 위한 매개변수로 사용할 수 있습니다.

MultipartFile을 사용하려면 MultipartResolver Bean을 등록해야 합니다.

(스프링 부트는 자동으로 등록되지만 스프링에 등록해야 사용 가능)

방법 설명하다
문자열 getName() 매개변수의 이름을 반환
문자열 getOriginalFilename() 업로드된 파일의 이름을 반환
문자열이 비어 있습니다() 업로드된 파일이 있으면 false, 그렇지 않으면 true
긴 getSize() 업로드된 파일의 크기를 반환
byte() getBytes()는 IOException을 발생시킵니다.

업로드된 파일에서 데이터 반환
무효 transferTo(파일 파일) 업로드된 파일 데이터를 지정된 경로에 저장

* 파일 파일 = 새 파일(문자열 경로명) 문자열 경로명을 사용하여 경로를 생성하면 해당 위치에 File 객체가 생성됩니다.

	@PostMapping("/upload_ok")
	public String uploadOk(@RequestParam("file") MultipartFile file) {
		String origin = file.getOriginalFilename();
	/*브라우저마다 getOriginalFilename()이 다르게 나타난다.

경로가 포함되서 나타나는 경우가 있기 때문에 substring으로 잘라서 순수한 파일이름만 나타나도록 한다.

*/ String filename = origin.substring(origin.lastIndexOf("\\") + 1); //폴더생성 및 파일저장 경로 받기 String filePath = makeDir(); //중복된 파일이름 방지위해 UUID 사용 String uuid = UUID.randomUUID().toString(); //최종저장경로 + 저장될 파일이름 String saveName = filePath + "\\" + uuid + "_" + filename; //경로에 업로드된 파일 저장하기 try { File save = new File(saveName); file.transferTo(save); String thumbsName = filePath + "\\" + uuid + "_thumbs" + filename; //썸네일 생성(복사할 파일위치, 썸네일 생성위치, 가로, 세로 Thumbnailator.createThumbnail(new File(saveName), new File(thumbsName), 150, 150); } catch (Exception e) { e.printStackTrace(); } return "upload/ex01_ok"; }

UUID

UUID(Universally Unique Identifier)는 각 개체를 고유하게 식별하는 값입니다.


UUID는 16옥텟(128비트) 숫자입니다.

표준 형식에서 UUID는 8-4-4-4-12라고 하는 5개의 그룹으로 하이픈으로 구분된 32개의 16진수로 총 36자(32개의 문자와 4개의 하이픈)로 표시됩니다.


– 위키백과


2) 다중 파일 업로드

-HTML

도착하다 요소 많은 종류의 속성을 추가하여 여러 파일을 업로드할 수 있습니다.

<form action="multiUpload_ok" method="post" enctype="multipart/form-data">
	<input type="file" name="file" multiple="multiple"><br/>
	<input type="submit" value="업로드"><br/>
</form>

-제어 장치

다중 파일은 MultipartFile이 아닌 다중 파일을 수신하기 위해 MultipartHttpServletRequest 인터페이스를 사용합니다.

List를 사용하여 파일 데이터를 받은 후 주기적으로 파일을 업로드합니다.

@PostMapping("/multiUpload_ok")
public String multiUpload_ok( MultipartHttpServletRequest files) {
	
	//name 태그가 file인 것을 찾는다 (= form input태그와 연결시키는 것)
	List<MultipartFile> list = files.getFiles("file"); 
	
	for(MultipartFile file : list) {
		String origin = file.getOriginalFilename();		
		String filename = origin.substring(origin.lastIndexOf("\\") + 1);
		String filePath = makeDir();
		String uuid = UUID.randomUUID().toString();
		String saveName = filePath + "\\" + uuid + "_" + filename;
		try {
			File save = new File(saveName);
 			file.transferTo(save);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	return "upload/ex01_ok";
}


다중 라벨 파일 업로드

하나의 입력 태그에 여러 파일을 업로드하는 대신 여러 입력 태그를 통해 여러 파일을 업로드합니다.

<form action="multiTag_ok" method="post" enctype="multipart/form-data">
<input type="file" name="file"><br/>
<input type="file" name="file"><br/>
<input type="file" name="file"><br/>
<input type="submit" value="업로드"><br/>
</form>

	@PostMapping("/multiTag_ok")
	public String multiTagOk(@RequestParam("file") List<MultipartFile> list) {
		List<MultipartFile> newList = list.stream()
				.filter((x) -> x.isEmpty() == false)
				.collect(Collectors.toList());
		
		for(MultipartFile file : newList) {
			String origin = file.getOriginalFilename();		
			String filename = origin.substring(origin.lastIndexOf("\\") + 1);
			String filePath = makeDir();
			String uuid = UUID.randomUUID().toString();
			String saveName = filePath + "\\" + uuid + "_" + filename;

			File save = new File(saveName);
			try {
				file.transferTo(save);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return "/upload/ex01_ok";
	}


JSON 형식으로 보낼 때 contentType은 application/json입니다.

xml -> 애플리케이션/xml

에서 -> 신청서/양식

파일 전송 -> multipart/form-data

contentType은 MIME 타입으로 작성되며, 확장자에 따른 MIME 타입을 확인하고 싶다면 다음 사이트를 확인하세요.

https://developer.mozilla.org/en/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

MIME 유형의 전체 목록 – HTTP | MDN

다음은 문서 유형과 관련된 MIME 유형의 전체 목록이며 공통 확장자로 정렬됩니다.

developer.mozilla.org


console.dir(파일)


썸네일