이번 포스팅에서는 기존 S3에 파일을 저장하고, 접근하도록 구현된 SpringBoot 프로젝트(워디 프로젝트)를 AWS에서 배포한 CloudFront를 경유하도록 설정해보고자 한다.
시작하기에 앞서, AWS CloudFront를 배포한 상황에서 시작하려고 한다. AWS CloudFront를 배포하는 방법은 다음 포스팅을 참고하도록 하자.
AwsS3Service 수정
현재 S3에 파일을 저장하고, 저장된 경로를 CloudFront를 경유하여 접근하는 방식을 구현할 예정이다.
그렇다면, S3에 파일을 저장하고 저장된 경로를 DB에 저장할 때 S3의 경로가 아닌 CloudFront를 통해 접근한 경로를 저장시켜줘야 한다.
가장 먼저 S3에 파일을 저장시키고, 해당 URL을 반환해주는 로직이 구현되어 있는 AwsS3Service 부분을 수정해보자.
먼저 전체 코드를 참고하자.
@RequiredArgsConstructor
@Service
public class AwsS3Service implements StorageService{
private final AwsProperties awsProperties;
private AmazonS3 s3Client;
@PostConstruct
private void setS3Client() {
AWSCredentials credentials = new BasicAWSCredentials(awsProperties.getAccessKey(),
awsProperties.getSecretKey());
s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(awsProperties.getRegionStatic())
.build();
}
public String uploadBucket(MultipartFile file) {
return upload(file, awsProperties.getBucket());
}
public String upload(MultipartFile file, String bucket) {
String fileName = file.getOriginalFilename();
String convertedFileName = FileNameUtils.fileNameConvert(fileName);
try {
String mimeType = new Tika().detect(file.getInputStream());
ObjectMetadata metadata = new ObjectMetadata();
FileNameUtils.checkMimeType(mimeType);
metadata.setContentType(mimeType);
s3Client.putObject(
new PutObjectRequest(bucket, convertedFileName, file.getInputStream(), metadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (IOException exception) {
throw new FileRoadFailedException("파일 저장에 실패하였습니다.");
}
return s3Client.getUrl(bucket, convertedFileName).toString();
}
}
위 코드 중에서 파일의 경로를 반환하는 부분인 return 부분에서 s3Client.getUrl() 메서드를 통해 다음과 같이 S3에 저장된 경로를 반환받고 있다.
return s3Client.getUrl(bucket, convertedFileName).toString();
현재 우리는 저장된 S3 경로에 직접 접근하지 않을 예정이기 때문에 해당 부분에서 저장한 파일 이름만 반환 받도록하고, 실제 접근할 경로는 반환 후, 설정해주는 방식으로 하자.
따라서 다음과 같이 수정해준다.
return convertedFileName;
CloudFront 도메인 명 상수 등록
CloudFront 배포 시 발급 받은 도메인 명을 사용 및 관리하기 편하도록 상수로 등록해주자.
패키지는 다음과 같이 utils - constants에 CloudFrontConstants를 생성해주었다.
생성한 CloudFrontConstants class의 상수 등록 코드는 다음과 같다.
public class CloudFrontConstants {
public static final String CLOUD_FRONT_DOMAIN_NAME = "dqkvehwnfe1ut.cloudfront.net";
}
Service 수정
자, 이제 AwsS3Service로 부터 파일 업로드 후, 반환받은 파일명과 상수로 등록한 CloudFront 도메인 명을 조합하여 파일 조회 시에 조회할 URL을 Service 단에 만들어보자.
먼저 기존의 Service 전체 코드는 다음과 같다.
@Transactional
public void createMentor(Long userId, CreateRequest createRequest, @Nullable MultipartFile profileImage, MultipartFile certification) {
User user = userRepository.findByIdAndStatus(userId, ACTIVE)
.orElseThrow(() -> new NoExistUserException("접속한 회원 정보와 일치하는 회원 정보가 없습니다."));
if(mentorRepository.countByUser(user)>=1) {
throw new ExistMentorException("이미 가입하신 멘토 정보가 있습니다.");
}
// 프로필 이미지 파일 저장
if (!profileImage.isEmpty()) {
String s3FilePath = awsS3Service.uploadBucket(profileImage);
createRequest.updateImageUrl(s3FilePath);
}
// 멘토 증명서 파일 저장
if (!certification.isEmpty()) {
String s3FilePath = awsS3Service.uploadBucket(certification);
createRequest.updateCertificationUrl(certification.getOriginalFilename(), s3FilePath);
}
// 멘토 정보 저장
Mentor mentor = mentorRepository.save(createRequest.toEntity(user));
// 멘토 키워드 저장
createRequest.getKeywordList().stream()
.forEach(k -> mentorKeywordRepository.save(new MentorKeyword(mentor, k)));
// 멘토 일정 저장
createRequest.getScheduleList().stream()
.forEach(s -> mentorScheduleRepository.save(s.toMentorSchedule(mentor)));
}
여기서 프로필 이미지 파일 저장, 멘토 증명서 파일 저장 부분을 다음과 같이 수정해주자.
// 프로필 이미지 파일 저장
if (!profileImage.isEmpty()) {
String s3SaveFileName = awsS3Service.uploadBucket(profileImage);
String fileFullPath = "https://" + CLOUD_FRONT_DOMAIN_NAME + "/" + s3SaveFileName;
createRequest.updateImageUrl(fileFullPath);
}
// 멘토 증명서 파일 저장
if (!certification.isEmpty()) {
String s3SaveFileName = awsS3Service.uploadBucket(certification);
String fileFullPath = "https://" + CLOUD_FRONT_DOMAIN_NAME + "/" + s3SaveFileName;
createRequest.updateCertificationUrl(certification.getOriginalFilename(), fileFullPath);
}
경로 저장 확인
수정된 코드로 데이터가 저장되는지 확인해보자.
Postman을 활용하여 다음과 같이 요청을 보내자 성공 응답 코드가 뜨는 것을 볼 수 있다.
이후 DataGrip에 접속하여 저장된 경로를 확인해보니 다음과 같이 CloudFront를 경유한 URL 경로로 수정된 것을 볼 수 있다.
참고
https://victorydntmd.tistory.com/336?category=764331
'👨💻 개발' 카테고리의 다른 글
서블릿(Servlet)이란? 서블릿에서 스프링까지 (0) | 2021.12.11 |
---|---|
IAM이란? (0) | 2021.12.08 |
AWS CloudFront 배포하기 (0) | 2021.12.07 |
SpringBoot로 AWS S3에 파일 업로드 하기 (0) | 2021.12.05 |
AWS S3 저장소 구축하기 (0) | 2021.12.05 |