ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AWS S3를 이용한 사진 저장
    프로젝트/Trend-Pick 2023. 7. 31. 19:00

    AWS의 S3를 이용해서 S3 버킷을 생성했다.

    프리티어를 이용하면 20000개의 GET 요청과 2000개의 PUT, POST 요청이 월별 무료라고 한다.

     

     

     

    기본 설정

     

     

    build.gradle에 추가

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

     

    application.properties에 추가

    cloud.aws.credentials.accessKey='엑세스 키'
    cloud.aws.credentials.secretKey='엑세스 비밀 키'
    
    cloud.aws.s3.bucket=trendpick-photo
    cloud.aws.region.static=ap-northeast-2
    cloud.aws.stack.auto=false

     

     

     

    S3 Configuration

    @Configuration
    public class S3Config {
    
        @Value("${cloud.aws.credentials.accessKey}")
        private String accessKey;
        @Value("${cloud.aws.credentials.secretKey}")
        private String secretKey;
        @Value("${cloud.aws.region.static}")
        private String region;
    
        @Bean
        public AmazonS3 amazonS3Client() {
            AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
            return AmazonS3ClientBuilder
                    .standard()
                    .withCredentials(new AWSStaticCredentialsProvider(credentials))
                    .withRegion(region)
                    .build();
        }
    }

     

     

     

    Service 계층에서의 upload 로직 추가

    public class S3FileService {
    
        @Value("${cloud.aws.s3.bucket}")
        private String bucket;
    
        private final AmazonS3 amazonS3;
    
        public String upload (MultipartFile multipartFile) throws IOException {
            String s3FileName = UUID.randomUUID() + "-" + multipartFile.getOriginalFilename();
            // filename을 랜덤으로 생성
    
            ObjectMetadata objMeta = new ObjectMetadata();
            objMeta.setContentLength(multipartFile.getInputStream().available());
            // file 사이즈 알려주는거
    
            amazonS3.putObject(bucket, s3FileName, multipartFile.getInputStream(), objMeta);
            // S3의 메서드인데 파일 stream을 열어서 S3에 파일을 업로드 하는 기능
    
            return amazonS3.getUrl(bucket, s3FileName).toString();
            // 업로드 된 사진 URL을 가져오는 기능
        }
    }

    Service 계층에서 bucket을 이용해서 fine이름을 UUID로 랜덤으로 생성한 다음에 업로드 된 사진의 url을 return 해주는 로직이다.

     

     

     

    컨트롤러에서 이미지 저장 로직 사용

    @PostMapping("/create_picture")
    public CreatePictureDto savePicture(@RequestParam("cody_img") MultipartFile codyImg)
            throws Exception{
        // PictureCreateDto pictureDto = new PictureCreateDto.builder()
        // 여기서 날라왔을 때
        Member member = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
        String oriImgName = codyImg.getOriginalFilename();
        String imgName = "";
        String imgUrl = "";
    
        imgName = s3FileService.upload(codyImg);
    
        imgUrl = imgLocation+"/"+ imgName;
    
        Picture picture = Picture.builder()
                .picture_member(member)
                .imgName(imgName).oriImgName(oriImgName).imgUrl(imgUrl).pictureTime(LocalDateTime.now()).build();
    
        pictureService.save(picture);
        return new CreatePictureDto(picture);
        //  codyImgService.save(picture_member,codyImg);
    
    }

    가운데 보이는 s3FileService.upload() 로직으로 S3에 파일을 저장할 수 있다.

    로컬로 했을 때에는 FileSerivce에서 로컬로 저장했는데 이제는 S3에 있는 저장소로 저장되게 된다.

     

    S3에 객체가 넣어졌다.
    물론 db에도 반영이 됐다. (mysql workbench 캡처)

     

     

    투표를 하는 cody_image랑 post_image, member_image가 같은 S3에 들어가는게 문제인데 이 문제는 폴더를 만들거나 S3 버킷을 여러개 만드는 것을 공부해가면서 분리해야겠다.

Designed by Tistory.