나는 MultipartFile
을 File
로 변환하는 convert()
메서드를 작성하였다.
public Optional<File> convert(MultipartFile multipartFile) throws IOException {
String homeDirectory = System.getProperty("user.dir");
String targetDirectory = homeDirectory + "/src/main/resources/images/";
File directory = new File(targetDirectory);
if (!directory.exists()) {
directory.mkdirs();
}
// 유니크한 파일명
String uniqueFileName = UUID.randomUUID().toString() + "_" + multipartFile.getOriginalFilename();
File convertFile = new File(targetDirectory + uniqueFileName);
if (convertFile.createNewFile()) {
try (FileOutputStream fileOutputStream = new FileOutputStream(convertFile)) { // fileOutputStream 데이터 -> 바이트 스트림으로 저장
fileOutputStream.write(multipartFile.getBytes());
}
return Optional.of(convertFile);
}
throw new IOException("파일 전환에 실패했습니다: " + multipartFile.getOriginalFilename() + " (경로: " + convertFile.getAbsolutePath() + ")");
}
로컬에서 실행을 했을 때는 잘 실행이 되었지만, 서버에서 실행했을 때는 계속 오류가 나왔다.
오류를 확인해보니 경로에서 오류가 났다고 한다......
String homeDirectory = System.getProperty("user.dir");
String targetDirectory = homeDirectory + "/src/main/resources/images/";
File convertFile = new File(targetDirectory + uniqueFileName);
시스템 속성에서 현재 사용자의 홈 디렉토리 경로를 가져와서 이미지를 저장할 /src/main/resources/images/
경로를 만든다.
문제점: 로컬에서는 문제없이 작동하지만, 배포환경에서는 경로 설정이 달라질 수 있다 ➡️ 이미지 저장 못할 수도 있다.
String targetDirectory = new ClassPathResource("static/images/").getFile().getAbsolutePath();
File convertFile = new File(targetDirectory + File.separator + uniqueFileName);
문제점: JAR 파일로 패키징 된 프로그램이면 JAR 내부 리소스를 참조해서 운영환경에서는 접근을 허용하지 않아 파일 입출력 작업을 수행할 수 없다.
맞다. JAR 파일이다...
그리고 Mac에서는 경로 구분자가 /
이지만 윈도우에서는 \
여서 구분자를 사용할 때는 File.separator
를 사용해야한다고 한다.
나는 처음에 resources/images/
가 빈 패키지라서 GitHub에 올라가지 않아서 그런 줄 알았다.
/src/main/resources/images/
폴더가 생기도록 .gitkeep
파일 추가
/src/main/resources/images/
에 TEST.png
파일 추가
String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
String fileName = File.separator + originalFileName.substring(0, originalFileName.lastIndexOf(".")) + "-";
// 유니크한 파일명 -> createTempFile 중복방지: 자체적으로 난수 생성
File convertFile = File.createTempFile(fileName, fileExtension);
이렇게 했다.
생각해보니 파일명에는 UUID
를 붙여줄 필요가 없었다.
왜냐하면 File.createTempFile()
를 사용하게 되면 임시로 저장되는 파일에서 파일명 뒤에 난수를 붙여주기 때문으로 자동으로 중복 방지가 된다.
사실 중간에 더 많은 시도들이 있었다...