코딩과 결혼합니다

[Game_Crew] 리팩토링 : S3 + 이미지 리사이징 적용하기 본문

코딩과 매일매일♥/Game_Crew

[Game_Crew] 리팩토링 : S3 + 이미지 리사이징 적용하기

코딩러버 2023. 11. 12. 16:43
728x90

문제

기존에는 UserS3Service, PostS3Service 에서 각각 S3에 사진을 업로드하고 이미지 리사이징을 하는 과정을 거쳤다.

중복된 코드들이나 기능이 겹치는 부분이 있어 가독성이 떨어지고 유지보수 면에서도 효율적이지 못하였다.

https://coding-s2-chaewon.tistory.com/207


해결

UserS3Service와 PostS3Service 의 공통적인 부분은 S3Service 클래스를 만들어 따로 관리하였다.
사진을 업로드 하고, 리사이징 하는 메서드들이 있다.

@Service
@RequiredArgsConstructor
public class S3Service {

    private final AmazonS3Client amazonS3Client;

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

    public String uploadFileToS3(MultipartFile file, String dir) throws IOException {
        
        //업로드 하는 로직
        ...
        return fileName;
    }

    public BufferedImage resizeImage(BufferedImage originalImage, int targetWidth) {
		//이미지 리사이징 하는 로직
        ...

        return scaledImge;
    }

    private String getFormatName(MultipartFile photo) {
        //이미지 파일의 확장자 반환하는 로직
        ...

        return originalFileName.substring(lastDotIndex + 1);
    }

    public void deleteFileFromS3(String filePath) {
        amazonS3Client.deleteObject(bucketName, filePath);
    }

    public String getURLFromS3(String filePath) {
        return "https://s3.ap-northeast-2.amazonaws.com/" + bucketName + "/" + filePath;
    }
}

 

중복되는 메서드들을 한 곳에서 관리하고 원래의 UserS3Service와 PostS3Service는 각각의 필요한 메서드들로 구성하여 역할을 명확히 하였다.

@Service
@RequiredArgsConstructor
public class UserS3Service {

    private final UserRepository userRepository;
    private final S3Service s3Service;

    @Transactional
    public void updateUserImage(Long userId, MultipartFile userImg) throws IOException {
        User user = userRepository.findById(userId)
                .orElseThrow(()-> new CustomException(ErrorMessage.NON_EXISTENT_USER, HttpStatus.BAD_REQUEST));

        // 이전에 이미지가 존재하면 삭제
        if (user.getUserImg() != null) {
            String oldFileName = user.getUserImg().substring(user.getUserImg().lastIndexOf("/") + 1);
            s3Service.deleteFileFromS3("user_image/" + oldFileName);
        }

        String fileName = s3Service.uploadFileToS3(userImg, "user_image");

        // S3에서 이미지 URL 가져오기
        String imageUrl = s3Service.getURLFromS3("user_image/" + fileName);

        user.updateUserImg(imageUrl);
        userRepository.save(user);
    }
}
@Service
@RequiredArgsConstructor
public class PostS3Service {

    private final S3Service s3Service;

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


    //이미지를 S3에 업로드하고, PostImg 객체를 생성하여 리스트에 추가
    public List<PostImg> uploadPhotosToS3AndCreatePostImages(List<MultipartFile> photos) throws IOException {
        List<PostImg> postImgList = new ArrayList<>();

        for (MultipartFile photo : photos) {
            if (!photo.isEmpty()) { // 파일이 비어있지 않은 경우에만 업로드 진행
                String fileName = s3Service.uploadFileToS3(photo, "post_img");
                String url = s3Service.getURLFromS3("post_img/" + fileName);
                PostImg postImg = new PostImg(url, null);
                postImgList.add(postImg);
            }
        }
        return postImgList;
    }
}

리사이징 전/후

 

전 (JPG파일)  

 

후 (리사이징)

 

 

이미지의 비율과 화질이 깨지지 않고 잘 리사이징 됨을 확인하였다.



https://pixabay.com/ko/photos/%EA%B9%83%ED%84%B8-%EC%83%88-%EC%A1%B0%EB%A5%98-%EC%9E%90%EC%97%B0-5272833/