우리의 귀요미 오이마켓이 2번째 스프린트 주간을 맞이했다
나는 게시글을 업로드할때 함께 이미지를 올릴수있는 기능을 맡아서 진행하기로 하였다
사진 업로드만큼 쉬운게 없었는데 내가 구현하려니 세상에서 제일 어려운 것이었다 😫
파일을 업로드 하기위해서는 필요한 친구가 있는데 그것이 바로 Multipartfile
라는 친구다
Spring doc 에서 Multipartfile
을 어떻게 설명했는지 살펴보자
멀티파트 요청에서 수신된 업로드된 파일의 표현입니다.
파일 내용은 메모리에 저장되거나 일시적으로 디스크에 저장됩니다. 두 경우 모두 사용자는 원하는 경우 파일 내용을 세션 수준 또는 영구 저장소에 복사할 책임이 있습니다. 임시 저장소는 요청 처리가 끝나면 지워집니다.
사실 구선생님이 번역해준거라 조금 어색한 감이 있지만 파일을 업로드하면 잠시 보관해주는 친구이다
나는 잠시 저장되어있는 파일을 내가 저장해서 사용하면 되겠네!
라는 생각으로 접근했다
처음 테이블을 구성할 당시에는 image
를 String
으로 저장하면 될거라고 생각하고 설계했는데, 이미지 파일의 이름과 경로가 함께 있어야 불러올 수 있을것이라 생각이 들어서 Entity class
에 String fileName
과 String filePath
를 추가해주었다
원래 구현되어있던 Service
에도 코드 수정을 해주었다
// 경로지정
String projectPath = System.getProperty("user.dir") +
"\\src\\main\\resources\\static\\files";
// 랜덤 식별자 생성
UUID uuid = UUID.randomUUID();
// uuid_원래파일명
String fileName = uuid + "_" + file.getOriginalFilename();
// 빈 파일 생성
File saveFile = new File(projectPath, fileName);
// 업로드 된 파일 저장
file.transferTo(saveFile);
파일명이 중복될 것을 방지하기위에 randomUUID
를 사용했는데 일단 이건 임시 방편이고 더 좋은 방법이 있으면 적용할 예정이다
테스트를 위해 아주 원시의 html파일을 하나 생성해주고, ajax
를 이용해서 서버와 통신을 해보았다. 처음에는 FormData
를 모르고 String
으로 파일을 보내려다가 계속 실패를 맛보았다
여기서 FormData란...
FormData 인터페이스는 form 필드와 그 값을 나타내는 일련의 key/value 쌍을 쉽게 생성할 수 있는 방법을 제공합니다.
출처 : mozilla.org
넘겨줘야하는 정보를 모두 append해주고나니 정상작동 하였다
function upload() {
let title = $("#title").val();
let content = $("#content").val();
let form = $("#file")[0].files[0];
let formData = new FormData();
formData.append('file', form);
formData.append('title', title);
formData.append('content',content);
$.ajax({
method: "POST",
url: "/api/article/write",
enctype: "multipart/form-data",
data: formData,
processData: false,
contentType: false,
cache: false,
success: function (data) {
alert("등록 성공")
window.location.reload();
}
})
}
dataType
대신 enctype
에 내가 사용할 multipart/form-data
를 꼭 추가해주고, processData
와 contentType
는 기본값이 true
이기 때문에 false
로 변경 해주어야한다
- contentType : false 로 선언 시 content-type 헤더가 multipart/form-data로 전송
- processData : false로 선언 시 formData를 string으로 변환하지 않음
출처 : stackoverflow
로컬에 이미지가 촥촥 쌓이길래 아...내가 해내다니!!!!😆
하면서 기뻤는데 그 알 수없는 찜찜함이 나를 감쌌다 😫
저장된 이미지를 불러오려고 할 때 그 찜찜함의 이유를 알 수 있었는데...
Entity
에 저장한 fileName
과 filePath
가 null
이었다...
why null....?
나는 파일만 저장하고 테이블에 저장해주지 않았던 것이었다 🤯
그걸 깨우치는데 많은 시간을 할애했지만 해결했다는것에 또 뿌듯해 하고 있는 와중에...
이제 한번 브라우저에서 불러와볼까?
했지만 일단 내 로컬에 저장되어있는 이미지이기 때문에 브라우저에서는 불러올 수가 없었다
이건 S3
에 업로드해야 해결이 될 것 같은데...
일단 오늘은 저장에 성공한 것만으로도 매우 만족한다 🤣