파일 업로드하다
파일 업로드는 내부적으로 구현해야 하는 기능이 많기 때문에 여러 측면을 고려해야 합니다.
또한 사용자의 편의를 위해 업로드 시 드래그 앤 드롭 기능(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;
}
멀티파트 파일?
사용자가 업로드한 파일을 나타내는 데 사용되는 인터페이스로, 파일 정보를 얻기 위한 매개변수로 사용할 수 있습니다.
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
썸네일