๐ค ์ด ๊ฒ์๋ฌผ์ ์์ฑํ๊ฒ ๋ ๊ณ๊ธฐ
์๋ก ์์ํ ํ๋ก์ ํธ์์ ๋์์ ์ ๋ก๋๋ฅผ ๊ตฌํํ ์ผ์ด ์๊ฒจ์ ๊ตฌํํ๋ ์ค์ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ฑ์ด๋ด์ง ์๊ณ Unkown Exception์ด ์๊พธ ๋จ์ด์ง๋ ๊ฒ์ ํ์ธํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฒ์๋ฌผ์ 4~5๊ฐ ์ ๋ ์์นญํ๊ณ ์งํผํ ์ 30๋ถ์งธ ํ๊ณ ์์ ๋ ๋ก๊ทธ ๋ ๋ฒจ์ Debug ๊น์ง ๋ฎ์ถ๊ณ ๋์์ผ
Resolved [org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded]
๋ผ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๊ณ ์๋ ๊ฒ์ ์๊ฒ ๋์๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ์๋ฌ ๊ฒ์์ ํด๋ณด๊ณ ๋์์ผ ์ด๊ฑธ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์๊ฒ ๋์๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ์ application.yaml
ํ์ผ์ max file size๋ฅผ ์ค์ ํด์ฃผ๋ ๊ฒ์ด๋ค.
spring:
servlet:
multipart:
enabled: true
max-file-size: 10000MB #10GB
max-request-size: 10000MB # 10GB
file-size-threshold:
๊ตฌํ
VideoService
@Service
@Slf4j
public class VideoService {
private static final long MAX_FILE_SIZE = 1024L * 1024L * 1024L * 10L; // 10GB
public String upload(MultipartFile file) {
checkFileTypeOrThrow(file);
checkFileSizeOrThrow(file);
String fileName = UUID.randomUUID() + ".mp4";
//
String directoryPath = getDirectoryPath();
Path filePath = Paths.get(directoryPath, fileName);
try (OutputStream os = Files.newOutputStream(filePath)) {
os.write(file.getBytes());
return fileName;
} catch (IOException e) {
log.error("file upload failed", e);
throw new ApiException(VideoStatus.FILE_UPLOAD_FAILED);
}
}
/**
* ํ์ผ์ ์ ์ฅํ ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ค๊ณ ์๋ค๋ฉด ์์ฑํ๋ค.
*/
private String getDirectoryPath() {
String dierctory = "src/main/resources/static/video";
Path directtoryPath = Paths.get(dierctory);
if (!Files.exists(directtoryPath)) {
try {
Files.createDirectories(directtoryPath);
} catch (IOException e) {
log.error("file upload failed", e);
throw new ApiException(VideoStatus.FILE_UPLOAD_FAILED);
}
}
return directtoryPath.toString();
}
/**
* ํ์ผ ํ์
์ด MP4์ธ์ง ํ์ธ
*/
private void checkFileTypeOrThrow(MultipartFile file) {
String contentType = file.getContentType();
if (!contentType.equals("video/mp4")) {
throw new ApiException(VideoStatus.INVALID_FILETYPE);
}
}
/**
* ํ์ผ ์ฌ์ด์ฆ๊ฐ 10GB ์ด์์ธ์ง ํ์ธ
*/
private void checkFileSizeOrThrow(MultipartFile file) {
long fileSize = file.getSize();
if (fileSize >= MAX_FILE_SIZE) {
throw new ApiException(VideoStatus.FILE_SIZE_EXCEEDED);
}
}
}
VideoApiController
@RestControllerWithEnvelopPattern
@RequestMapping("/open-api/video")
@RequiredArgsConstructor
public class VideoApiController {
private final VideoService videoService;
@PostMapping("/upload")
public String saveFile(@RequestParam("file") MultipartFile file) {
String fileName = videoService.upload(file);
return fileName;
}
}
VideoStatus
@Getter
@AllArgsConstructor
public enum VideoStatus implements ApiStatusIfs {
INVALID_FILETYPE(4400, "์ง์ํ์ง ์๋ ํ์ผ ํ์์
๋๋ค."),
FILE_SIZE_EXCEEDED(4401, "ํ์ผ ํฌ๊ธฐ๊ฐ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ด๊ณผํ์์ต๋๋ค."),
FILE_UPLOAD_FAILED(4502, "ํ์ผ ์
๋ก๋์ ์คํจํ์์ต๋๋ค."),
EMPTY_FILE(4403, "ํ์ผ์ด ๋น์ด์์ต๋๋ค."),
;
private final Integer statusCode;
private final String message;
}
์ฝ๋ ์ค๋ช
VideoController ๐ VideoService๋ก ์ด์ด์ง๋ ์ฝ๋์ด๋ค. VideoService์์๋ ํด๋นํ๋ ํ์ผ์ด .mp4 ํ์ผ์ธ์ง ํ์ธํ๊ณ ์ฉ๋์ ํ์ธํด์ 10GB๋ฅผ ๋๋์ง ํ์ธํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด ๊ฒ์ฆ ๊ตฌ๊ฐ์ ํต๊ณผํ๊ณ ๋๋ฉด getDirectoryPath() ๋ฉ์๋๋ฅผ ํตํด์ project root๋ฅผ ๊ธฐ์ค์ผ๋ก src/main/resources/static/video ํด๋๊ฐ ์๋์ง ํ์ธํ๊ณ ์๋ค๋ฉด ์์ฑํ ํ ๊ทธ ํด๋์ randomํ UUID๋ก ํ์ผ์ด๋ฆ์ ์ง์ ํด์ ์ ์ฅํ๋ค.
'Spring > Best Practice' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Boot letscript๋ก HTTPS ๋ฐ๊ธ (0) | 2024.10.30 |
---|