-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
12 changed files
with
402 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package umc.spring.aws.s3; | ||
|
||
import com.amazonaws.services.s3.AmazonS3; | ||
import com.amazonaws.services.s3.model.ObjectMetadata; | ||
import com.amazonaws.services.s3.model.PutObjectRequest; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import umc.spring.config.AmazonConfig; | ||
import umc.spring.domain.Uuid; | ||
import umc.spring.repository.UuidRepository; | ||
|
||
import java.io.IOException; | ||
|
||
// 12주차 사진도 같이 업로드하기 | ||
|
||
// 이제 다음으로 AWS S3에 사진을 업로드 하는 매서드를 가진 | ||
// AmazonS3Manager라는 클래스를 만들어서 사용합시다. | ||
// S3 말고도 다른 AWS의 서비스를 사용 할 수 있으니 | ||
// aws라는 폴더에 s3라는 폴더를 만들고 | ||
// 하위에 AmazonS3Manager를 만들어 두겠습니다. | ||
@Slf4j | ||
@Component | ||
@RequiredArgsConstructor | ||
public class AmazonS3Manager { | ||
|
||
private final AmazonS3 amazonS3; | ||
// amazonS3는 저희가 만들 필요는 없고 build.gradle에서 | ||
// amazon 관련 외부 모듈을 받으면 사용이 가능합니다. | ||
// 해당 amazonS3가 제공하는 메서드를 사용하면 됩니다. | ||
private final AmazonConfig amazonConfig; | ||
// amazonConfig는 S3를 사용하기 위해서 필요한 | ||
// 인증에 대한 과정 등이 포함이 됩니다. | ||
// 인증이 되었다는 것을 가지고 AmazonS3를 사용해서 | ||
// 파일을 업로드하면 됩니다 | ||
private final UuidRepository uuidRepository; | ||
|
||
// AWS S3를 사용해서 파일을 업로드하고 그 결과로 | ||
// 우리가 필요한 것은 파일의 URL입니다. | ||
// uploadFile은 내부적으로 Amazon이 제공하는 | ||
// putObject 메서드를 사용 할 것입니다. | ||
public String uploadFile(String KeyName, MultipartFile file){ | ||
|
||
System.out.println(KeyName); | ||
|
||
ObjectMetadata metadata = new ObjectMetadata(); | ||
// metaData는 필수는 아니고 추가적인 정보를 담아주는 것입니다. | ||
metadata.setContentLength(file.getSize()); | ||
|
||
try { | ||
|
||
amazonS3.putObject(new PutObjectRequest(amazonConfig.getBucket(), KeyName, file.getInputStream(), metadata)); | ||
// putObject 메서드는 PutObjectRequest를 | ||
// 파라미터로 받아 S3 버킷에 저장합니다. | ||
// amazonS3의 putObject 매서드에 파라미터로 | ||
// PutObjectReqeust를 담는 것을 확인 가능하며, | ||
// PutObjectRequest를 만들 때, | ||
// 어떤 S3의 버킷에 올릴지, 식별 할 이름은 무엇인지, | ||
// 그리고 파일의 데이터는 무엇인지를 담죠. | ||
// keyName과 file의 경우는 당연히 | ||
// 해당 매서드를 호출할 서비스 계층에서 담아줍니다! | ||
|
||
// 이제 저희가 S3에 사진을 업로드 할 때 | ||
// 이렇게 요청을 해야합니다. | ||
// 어떤 버킷의 특정 디렉토리에 이런 식별자로 | ||
// 업로드 해줘! | ||
// amazonConfig.getBucket() | ||
// 어떤 버킷인지 가져온다 | ||
// KeyName | ||
// 어떤 디렉토리의 어떤 식별자인지 KeyName으로 지정한다 | ||
|
||
}catch (IOException e){ | ||
|
||
log.error("error at AmazonS3Manager uploadFile : {}", (Object) e.getStackTrace()); | ||
|
||
} | ||
|
||
return amazonS3.getUrl(amazonConfig.getBucket(), KeyName).toString(); | ||
// 우리는 getUrl 메서드를 이용해서 버킷에 저장된 | ||
// 파일의 URL을 받아서 최종적으로 return합니다. | ||
|
||
} | ||
|
||
// 이제 KeyName을 만들어서 리턴 해주는 매서드를 | ||
// Manager에 추가해봅시다! | ||
public String generateReviewKeyName(Uuid uuid){ | ||
|
||
return amazonConfig.getReviewPath() + '/' + uuid.getUuid(); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package umc.spring.config; | ||
|
||
import com.amazonaws.auth.AWSCredentials; | ||
import com.amazonaws.auth.AWSCredentialsProvider; | ||
import com.amazonaws.auth.AWSStaticCredentialsProvider; | ||
import com.amazonaws.auth.BasicAWSCredentials; | ||
import com.amazonaws.services.s3.AmazonS3; | ||
import com.amazonaws.services.s3.AmazonS3ClientBuilder; | ||
import jakarta.annotation.PostConstruct; | ||
import lombok.Getter; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
// 12주차 사진도 같이 업로드하기 | ||
|
||
// 이제 AWS S3에 사진을 업로드 하기 위한 | ||
// 설정 정보가 담긴 클래스를 만들어 줍시다. | ||
// 해당 클래스는 순수하게 AWS의 서비스를 사용하기 위한 | ||
// 설정 정보가 담기게 됩니다. | ||
// 11주차 CI/CD에서도 AWS는 보안에 굉장히 민감하고 | ||
// 외부에서 AWS의 서비스를 사용하기 위해 | ||
// Access Key와 Secret Key를 발급했죠? | ||
// 그런 정보를 담아 둘 클래스라고 생각하면 됩니다. | ||
@Configuration | ||
@Getter | ||
public class AmazonConfig { | ||
|
||
private AWSCredentials awsCredentials; | ||
// 이제 저 키를 어디에 보관 해야할지가 문제이죠 | ||
// CI/CD에서는 깃허브 액션에서 사용이 되니 | ||
// 리포지토리의 키에 저장을 했죠? | ||
// 지금은 어떻게 할까요? | ||
// 여기서 환경변수라는 개념을 활용 할 수 있습니다. | ||
// 일단 무식하게 아래처럼 가능합니다. | ||
// private String accessKey = "Springboot 액세스 키"; | ||
// private String secretKey = "Springboot 비밀 액세스 키"; | ||
// private String region = "ap-northeast-2"; | ||
// 네. 저렇게 했다가 깃허브에 올리면 바로 털리겠죠? | ||
// 따라서 저런 상수 값들은 저렇게 직접 가져다 넣기 보다는 | ||
// application.yml에 두고 가져오는 것이 좋습니다. | ||
// application.yml에서 처음 시작이 cloud | ||
// (잘 보면 spring이랑 별개임) | ||
// 1depth 아래가 aws 그리고 s3, region 등등이 같은 depth이죠 | ||
// 저렇게 depth에 맞춰서 어떤 값을 가져올지 기입하면 됩니다. | ||
@Value("${cloud.aws.credentials.accessKey}") | ||
private String accessKey; | ||
@Value("${cloud.aws.credentials.secretKey}") | ||
private String secretKey; | ||
@Value("${cloud.aws.region.static}") | ||
private String region; | ||
@Value("${cloud.aws.s3.bucket}") | ||
private String bucket; | ||
// 버킷의 정보 지정 | ||
@Value("${cloud.aws.s3.path.review}") | ||
private String reviewPath; | ||
|
||
|
||
|
||
@PostConstruct | ||
public void init(){ | ||
|
||
this.awsCredentials = new BasicAWSCredentials(accessKey, secretKey); | ||
|
||
} | ||
|
||
@Bean | ||
public AmazonS3 amazonS3(){ | ||
|
||
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); | ||
|
||
return AmazonS3ClientBuilder.standard() | ||
.withRegion(region) | ||
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) | ||
.build(); | ||
|
||
} | ||
|
||
@Bean | ||
public AWSCredentialsProvider awsCredentialsProvider() { | ||
|
||
return new AWSStaticCredentialsProvider(awsCredentials); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package umc.spring.converter; | ||
|
||
import umc.spring.domain.Review; | ||
import umc.spring.domain.ReviewImage; | ||
import umc.spring.web.dto.StoreRequestDTO; | ||
|
||
import java.util.List; | ||
|
||
// 12주차 사진도 같이 업로드하기 | ||
public class ReviewConverter { | ||
|
||
public static ReviewImage toReviewImage(String imageUrl, Review review){ | ||
|
||
return ReviewImage.builder() | ||
.imageUrl(imageUrl) | ||
.review(review) | ||
.build(); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package umc.spring.domain; | ||
|
||
import jakarta.persistence.*; | ||
import lombok.*; | ||
import umc.spring.domain.common.BaseEntity; | ||
|
||
// 12주차 사진도 같이 업로드하기 | ||
|
||
// 우선 너무 코드가 복잡해지지 않도록 하기 위해 | ||
// 리뷰에 사진이 여러 장 가능하지만 한 장만 업로드를 해보겠습니다. | ||
// 우선 사진 각각을 아마존 자체에서도 구분이 가능해야 합니다. | ||
// 그 이유는 물론 사진마다 이름이 존재하겠지만… | ||
// 사람이 붙이는 이름이 같을 수 있기 때문에 | ||
// 따로 겹치지 않는 정보가 필요합니다. | ||
// 가장 쉬운 방법은 업로드 하는 파일에 | ||
// 일련번호를 붙이는 방법이 있겠지만.. 이 방법도 유효하지 않습니다. | ||
// 왜냐하면 자바 자체적으로 변수를 두면 | ||
// 서버가 꺼질 때 초기화가 되기 때문에 영속되는 데이터로 둬야 합니다. | ||
// 저희는 UUID라는 것을 사용해서 일련번호를 두겠습니다. | ||
// 4UUID는 겹칠 확률이 극히 적은(사실상 안 겹칩니다) | ||
// 일련의 식별자 입니다! | ||
// Java에서는 UUID를 생성해주는 API가 존재하며 | ||
// 이를 이용해서 UUID를 담은 엔티티를 하나 만들어서 사용합시다. | ||
// 이후 AWS S3에 업로드 시 uuid를 파일 이름에 붙여서 | ||
// 업로드 해서 업로더가 지은 파일의 이름이 | ||
// 동일하더라도 각각의 파일이 식별이 되도록 합시다! | ||
@Entity | ||
@Builder | ||
@Getter | ||
@AllArgsConstructor(access = AccessLevel.PROTECTED) | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Uuid extends BaseEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@Column(unique = true) | ||
private String uuid; | ||
|
||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/umc/spring/repository/ReviewImageRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package umc.spring.repository; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import umc.spring.domain.ReviewImage; | ||
|
||
// 12주차 사진도 같이 업로드하기 | ||
public interface ReviewImageRepository extends JpaRepository<ReviewImage, Long> { | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package umc.spring.repository; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import umc.spring.domain.Uuid; | ||
|
||
// 12주차 사진도 같이 업로드하기 | ||
public interface UuidRepository extends JpaRepository<Uuid, Long> { | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.