-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathImageStorageService.java
68 lines (58 loc) · 2.28 KB
/
ImageStorageService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package practice.s3.application;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import practice.s3.dto.ImageUploadResponse;
import practice.s3.exception.BadRequestException;
import practice.s3.exception.InternalServerException;
@Service
@RequiredArgsConstructor
public class ImageStorageService {
private static final int MAX_IMAGE_LENGTH = 10;
private final StorageClient storageClient;
private final Executor executor;
@Value("${s3.base-url}")
private String baseUrl;
public ImageUploadResponse uploadFiles(MultipartFile[] imageFiles) {
validate(imageFiles);
List<String> fileNames = new ArrayList<>();
try {
Arrays.stream(imageFiles)
.map(storageClient::upload)
.forEach(fileNames::add);
return convertFileNamesToResponse(fileNames);
} catch (Exception e) {
executor.execute(() -> deleteFiles(fileNames));
throw new InternalServerException("이미지 업로드시 예외가 발생했습니다.");
}
}
private void validate(MultipartFile[] imageFiles) {
if (imageFiles.length > MAX_IMAGE_LENGTH) {
throw new BadRequestException("파일 수가 너무 많습니다.");
}
Arrays.stream(imageFiles)
.forEach(this::validateImageFile);
}
private void validateImageFile(MultipartFile file) {
String contentType = file.getContentType();
if (contentType == null || !contentType.startsWith("image/")) {
throw new BadRequestException("image 형식이 아닙니다.");
}
}
private ImageUploadResponse convertFileNamesToResponse(List<String> fileNames) {
List<String> urls = fileNames.stream()
.map(fileName -> baseUrl + fileName)
.toList();
return new ImageUploadResponse(urls, fileNames);
}
@Async
public void deleteFiles(List<String> fileNames) {
fileNames.forEach(storageClient::delete);
}
}