[카테캠 3단계] 이미지를 DTO로 내보내기

Seokjun Moon·2023년 10월 2일
0

이미지를 내보내야 합니다 ....

포트폴리오 이미지를 프론트로 넘겨야하는데, 이게 생각처럼 간단한 작업이 아니었습니다 .... 우선 이미지를 바이트 스트림으로 내보내려면 예제들을 찾아보니 응답 데이터 타입을 이미지로 지정하고 보내야 하고, 다른 정보 없이 이미지만 보내는 것들 뿐이었습니다.

따라서 만약 이 방법을 채택한다면, 리스트조회를 하려고 하면 우선

  1. 포트폴리오 리스트를 요청해서 응답받고
  2. 응답에 포함된 이미지 정보로 각 이미지마다 다시 또 요청을 보내기

이런 복잡하기도 하고, 리스트 조회 1번에 최대 11번의 요청을 보내는 불상사가 나타나기에 이 방법은 정말 비효율적입니다.

그래서 생각한 방법이, 맛집 프로젝트에서 했던 아이디어인 base64 인코딩이었습니다. 이미지도 base64 인코딩이 가능하므로, 인코딩하여 전달하면 문자열이므로 DTO에 다른 데이터들과 함께 같이 보낼 수 있습니다 ..!!!

구현

public PortfolioDTO getPortfolioById(Long id) {
    List<ImageItem> imageItems = imageItemJPARepository.findByPortfolioId(id);
    if (imageItems.isEmpty()) {
        throw new Exception404(BaseException.PORTFOLIO_NOT_FOUND.getMessage());
    }

    List<String> images = imageItems
            .stream()
            .map(ImageEncoder::encode)
            .toList();

    List<PriceItem> priceItems = priceItemJPARepository.findAllByPortfolioId(id);
    Portfolio portfolio = imageItems.get(0).getPortfolio();
    return PortfolioDTOConverter.toPortfolioDTO(portfolio, images, priceItems);
}

이렇게 하고, 이미지 인코더 클래스에서 인코딩을 진행합니다. 아직 DB에 저장할지, 로컬에 저장할지, 원격 서비스를 이용할지 정하지 않았기에 로컬에 저장해서 테스트를 진행했습니다. 따라서 Resource를 이용했으나, 추후 바뀔 수 있습니다.

public class ImageEncoder {
    public static String encode(ImageItem imageItem) {
        Resource resource = new FileSystemResource(imageItem.getFilePath() + imageItem.getOriginFileName());
        if (!resource.exists()) {
            throw new Exception404(BaseException.PORTFOLIO_IMAGE_NOT_FOUND.getMessage());
        }

        try {
            return Base64.getEncoder().encodeToString(resource.getContentAsByteArray());
        }
        catch (IOException exception) {
            exception.printStackTrace();
        }

        return null;
    }
}
profile
차근차근 천천히

0개의 댓글