[Spring] 파일 업로드 받기
- 카테고리 없음
- 2021. 7. 22.
파일 업로드
파일 업로드를 하기 위해서는 기본적으로 바이너리에 대해 약간 이해를 하고 넘어가야 합니다.
일반적인 request 같은 경우, text타입을 전송하고 있습니다.
사용자의 id, 패스워드, 성함, 닉네임 등 텍스트로 이루어진 데이터는 그대로 DB에 저장되거나 다시 response로 넘어가게 됩니다.그러나 사진, 동영상 등은 텍스트로 표현하기엔 매우 어려우며 그렇기 때문에 다른 데이터 타입의 저장 수단이 필요하게 됩니다.
그것이 바로 바이너리입니다. 바이너리를 전송하는 대표적인 수단은 MultipartHttpServletRequest가 있으며, 이를 활용하여 사용자에게 파일을 전송할 수 있게 도와줄 수 있습니다.
파일 업로드 사용처
1. 웹 서버 내 사용자들이 업로드하는 파일 저장하기
2. 웹 서버 2개 이상일 경우, 이미지 파일 공유하기
사용 방법
public @ResponseBody String joinApplication(MultipartHttpServletRequest request)
{
//등록된 파일 관리하기
MultipartFile files = request.getFiles("files");
//파일의 저장 경로 설정하기
String downPath = AREA_FILE_PATH;
//현재 날짜 / 사용자 번호 / area_seq
downPath+=instDate+"/"+phone+"/"+area_seq+"/";
File fileDir = new File(downPath);
//license 폴더가 없으면 생성
if (!fileDir.exists()) {
fileDir.mkdirs();
}
int titleNumber = 0;
String instDate = Function.getCurrentDate();
String fileName = request.getParameter(files);
//저장 받은 파일의 확장명을 가져온다.
String fileExtensions = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
//현재 시간을 받는다. (년, 월, 일을 0.001초 단위로 받는다. 시계의 기준은 한국이 아니다.)
long time = System.currentTimeMillis();
//저장 파일명을 정의한다. 파일의 이름의 중복을 최소화 시킨다.
String saveFileName = String.format("%s_%s", time, fileName+"."+fileExtensions);
// 파일생성
//파일 저장경로, 저장파일 이름
File saveFile = new File(downPath, saveFileName);
multipartFile.transferTo(saveFile);
//파일 생성 여부 체크
if(saveFile.exists()) {
//파일 체크 가능한 log 이용하기
}
}
보통 파일 업로드 같은 경우 비동기와 동기가 나뉘지만, 저 같은 경우 비동기를 애용하는 편이니 비동기 방식으로 설명드리겠습니다.
파일을 받기 위해서는 MultipartHttpServletRequest가 필요합니다.
일반 request는 바이너리를 표현하기 어렵기 때문입니다.
XssPreventer.escape()는 신경 안 쓰셔도 됩니다.
일반 request를 받아온 값을 VO나 String 혹은 HashMap을 이용해서 옮겨 담습니다.
다만, 바이너리 타입을 가진 file은 getFile() 함수를 이용해서 MultipartFile에 옮겨 담도록 합니다.
제가 List를 사용한 이유는, 여러 개의 중복된 이름을 소유한 file의 name이 존재했기 때문입니다.
넘어온 request의 key값이 같을 경우, 배열에 담기는 특성을 이용한 방식입니다.
파일을 저장하기 위해서는 반드시 저장 경로가 필요하게 됩니다.
한 곳에 저장할 수도 있지만, 되도록이면 각 분리할 수 있도록 설정하도록 합니다.
그렇다고 무작정 경로를 지정하는 것보다는 저장되는 DB 컬럼들을 이용해서 디렉터리를 저장하도록 합니다.
저 같은 경우에는 '기본 파일 저장 경로' + 현재 날짜(210722) + 사용자 구분 UNIQUE 특성(SEQ 혹은 PHONE) + 게시판 번호입니다.
파일 저장 경로 예시 : D:/web/was/fileupload/210722/01012341234/1
무엇을 상위 디렉터리에 넣느냐에 따라서 파일을 어떻게 관리할 것인지가 선택하게 됩니다.
저장 경로명에 해당되는 디렉터리가 존재하지 않을 경우, 해당 디렉터리가 자동으로 생성되도록 설정하도록 합니다.
만약 이를 안 할 경우, 저장 경로를 찾을 수가 없어서 500 Error가 발생하게 됩니다.
다수로 받은 파일을 저장하기 위해 for문을 활용하였습니다.
시간은 millisecond 단위로 지정했으며, index와 기존 파일 이름을 조합하여 중복된 파일명이 나올 수 없도록 하였습니다.
가장 중요한 것은 아래의 File saveFile = new('저장 경로', '저장 파일 이름');입니다.
이를 이용하면, 사진과 같이 저장된 파일이 정상적으로 등록된 것을 확인할 수 있게 됩니다.
이제 파일을 저장하게 되었으니, DB를 통해 파일이 어디에 있는지를 저장하면 끝.
저는 생성 날짜 + 사용자 핸드폰 번호 + 게시판 SEQ 이므로, 이 3개만 DB에 저장되면 됩니다.
그리고 저장한 파일명을 저장하기 위해서 별도로 파일명만 DB에 담도록 합니다.
마무리
소스는 일반적인 Multipart를 이용하여 공유해드렸습니다.
설명글에 올린 것은, 저의 프로젝트 환경상 여러 개의 file을 처리하기 위해 필요한 수단이고 소스와 설명의 차이가 생겨버렸네요.
설정은 포스팅된 이전 글을 이용해서 참고해주시면 감사하겠습니다.
오늘도 파이팅입니다.
Spring에서 MultipartHttpServletRequest 설정하기
2021.07.21 - [Web/Spring] - [Spring] 파일 업로드 사용하기