Springboot

[Springboot] S3에 이미지 올리기

KJihun 2023. 8. 1. 22:54
728x90

 

 

S3에서 버킷 생성 및 IAM 설정을 완료한 후 작성해야 한다.

 

gradle.build

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

 

application-security.properties

# mySql
spring.datasource.url=jdbc:mysql://localhost:3306/{DB명}
spring.datasource.username={유저이름}
spring.datasource.password={패스워드}

#AWS S3
cloud.aws.credentials.accessKey={엑세스키 입력}
cloud.aws.credentials.secretKey={시크릿키 입력}
cloud.aws.stack.auto=false

# AWS S3 Service bucket
cloud.aws.s3.bucket={DB명}
cloud.aws.region.static=ap-northeast-2

# AWS S3 Bucket URL
cloud.aws.s3.bucket.url=https://s3.ap-northeast-2.amazonaws.com/{DB명}

 

 

S3Config

@Configuration
public class S3Config {

    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;

    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;

    @Value("${cloud.aws.region.static}")
    private String region;

    @Value("${cloud.aws.s3.bucket}")
    private String bucket;

    @Bean
    public AmazonS3Client amazonS3Client() {
        BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);

        return (AmazonS3Client) AmazonS3ClientBuilder
                .standard()
                .withRegion(region)
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .build();
    }

    @Bean
    public String Bucket() {
        return bucket;
    }
}

 

 

Entity

@Entity
@Getter
@NoArgsConstructor
public class Image {
    @Id
    private String imageKey;

    @Column(nullable = false)
    private String image;

	// TransientPropertyValueException으로 인해 cascade추가
    @ManyToOne(cascade = CascadeType.PERSIST) 
    @JoinColumn(name = "{연관관계를 맺을 엔티티의 키값}")
    private 엔티티명;

    public Image(String imageKey, String image, Goods goods) {
        this.imageKey = imageKey;
        this.image = image;
        this.goods = goods;
    }
}

 

다른 클래스에서 사용할것이기에 Service가 아닌 Helper로 명명했다.

@Service
@RequiredArgsConstructor
public class ImageHelper {
    private final ImageRepository imageRepository;

	// 이미지 업로드 및 Repository에 저장
    public List<String> saveImagesToS3AndRepository(List<MultipartFile> images, AmazonS3 amazonS3, String bucket) {
        // .. 파일검증구문 필요 

        List<String> uploadedFileUuids = new ArrayList<>();
        for (MultipartFile image : images) {

            String imageName = image.getOriginalFilename(); // 파일의 원본명
            String extension = StringUtils.getFilenameExtension(Paths.get(imageName).toString()); // 확장자명
            String imageUuid = UUID.randomUUID() + "." + extension; // 해당 파일의 고유한 이름

            // 업로드할 파일의 메타데이터 생성(확장자 / 파일 크기.byte)
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType("image/" + extension);
            metadata.setContentLength(image.getSize());

            // 요청 객체 생성(버킷명, 파일명, 스트림, 메타정보)
            PutObjectRequest request;
            try {
                request = new PutObjectRequest(bucket, imageUuid, image.getInputStream(), metadata);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            // S3 버킷에 등록
            amazonS3.putObject(request);
            uploadedFileUuids.add(imageUuid);

			// Repository에 저장
            imageRepository.save(new Image(imageUuid, amazonS3.getUrl(bucket, imageUuid).toString()));
        }

        return uploadedFileUuids;
    }

	// S3삭제
    public void deleteFileFromS3(String imageUuid, AmazonS3 amazonS3, String bucket) {
        amazonS3.deleteObject(bucket, imageUuid);
    }

	// Repository 삭제
    public List<Image> repositoryImageDelete(Long goodsId) {
        return ImageRepository. // 구현 필요
    }

 }

 

이후 원하는 클래스에서 사용하면 정상적으로 작동할 것이다.

'Springboot' 카테고리의 다른 글

[Springboot] QueryDSL  (0) 2023.08.08
[SpringBoot] Redis Caching  (0) 2023.08.06
[Springboot] UnsatisfiedDependencyException  (0) 2023.08.01
[Springboot] OneToMany VS ManyToOne  (0) 2023.07.30
[CS] 정규화 및 반정규화  (0) 2023.07.29