Controller
@RestController
@RequestMapping()
@RequiredArgsConstructor
@Slf4j
public class S3Controller {
private final S3Service s3Service;
@PostMapping(value = "/upload", produces = APPLICATION_JSON_VALUE)
public ResponseEntity<FileDetail> post(
@RequestPart("file") MultipartFile multipartFile) {
return ResponseEntity.ok(s3Service.save(multipartFile));
}
}
Service
@Service
@RequiredArgsConstructor
@Slf4j
public class S3Service {
private final S3ResourceStorage s3Storage;
public FileDetail save(MultipartFile multipartFile) {
FileDetail fileDetail = FileDetail.multipartOf(multipartFile);
s3Storage.store(fileDetail.getPath(), multipartFile);
return fileDetail;
}
}
S3 Storage
@Component
@RequiredArgsConstructor
@Slf4j
public class S3ResourceStorage {
@Value("${cloud.aws.s3.bucket}")
private String bucket;
private final AmazonS3Client amazonS3Client;
public void store(String fullPath, MultipartFile multipartFile) {
File file = new File(MultipartUtil.getLocalHomeDirectory(), fullPath);
try {
multipartFile.transferTo(file);
amazonS3Client.putObject(new PutObjectRequest(bucket, fullPath, file)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (Exception e) {
log.error(e.getMessage());
throw new RuntimeException();
} finally {
if (file.exists()) {
file.delete();
}
}
}
}
model
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@Slf4j
public class FileDetail {
private String id;
private String name;
private String format;
private String path;
private long bytes;
@Builder.Default
private LocalDateTime createdAt = LocalDateTime.now();
public static FileDetail multipartOf(MultipartFile multipartFile) {
final String fileId = MultipartUtil.createFileId();
final String format = MultipartUtil.getFormatByName(multipartFile.getOriginalFilename());
return FileDetail.builder()
.id(fileId)
.name(multipartFile.getOriginalFilename())
.format(format)
.path(MultipartUtil.createPath(fileId, format))
.bytes(multipartFile.getSize())
.build();
}
}
util
@Slf4j
public class MultipartUtil {
private static final String BASE_DIR = "video";
public static String getLocalHomeDirectory() {
return System.getProperty("user.home");
}
public static String createFileId() {
return UUID.randomUUID().toString();
}
public static String getFormat(String contentType) {
if (StringUtils.hasText(contentType)) {
return contentType.substring(contentType.lastIndexOf('/') + 1);
}
return null;
}
public static String getFormatByName(String contentType) {
if (StringUtils.hasText(contentType)) {
log.info("contentType = {}", contentType);
return contentType.substring(contentType.lastIndexOf('.') + 1);
}
return null;
}
public static String createPath(String fileId, String format) {
return String.format("%s/%s.%s", BASE_DIR, fileId, format);
}
}
전체 코드
spring-s3-practice 깃허브
📚참고문헌