본문 바로가기
Spring

Spring boot에서 AWS S3에서 받은 파일들을 Zip파일로 압축후 response하기 (in memory)

by 디찌s 2023. 5. 23.
728x90
반응형

스트림 InputStream,OutputStream

프로세스가 데이터의 도착지라면 입력스트림(inputstream),프로세스가 데이터의 출발지라면 출력 스트림(OutputStream) 이라고 불린다. 기준은 항상 프로그램이다.

JAVA의 스트림

JAVA의 스트림은 바이트 기반 스트림,문자 기반 스트림이 존재한다.

  1. 바이트 기반 스트림 : 문자,그림,영상등 다양한 형태의 데이터를 주고 받을수 있다.
  2. 문자 기반 스트림 : 오직 문자만 주고 받을수 있도록 설계됨.

JAVA에서 InputStream은 바이트 기반 입력 스트림 최상위 추상 클래스이고,OutputStream은 바이트 기반 출력 스트림 최상위 클래스이다. 이들의 하위 클래스는 XXXInputStream,XXXOutputStream 이라는 네이밍을 가진다.

SPRING BOOT를 이용해서 S3에서 받은 파일들을 ZIP 파일로 다운로드 시키기 (IN MEMORY)



List<Map<String,Object>> kg = new ArrayList();
List<String> fileTypeList = new ArrayList<>();
fileTypeList.add("PDF");
fileTypeList.add("HTML");
 List<MemberUploadFileDTO> list = memberQueryService.selectMemberUploadFileInfoList(loginDto.getId(),fileTypeList);

위코드는 현재 DB에 적재된 S3 URL 및 KEY값, 파일 이름등 리스트 형식으로 가져오는 서비스이다.


   /**
     * file 다운로드
     *
     * @param fileKey  파일 key 로 해당 버킷에서 파일 찾아서 들고옴
     * @return
     */
    public byte[] downloadS3(String fileKey) throws IOException {
        byte[] bytes = null;
        if (fileKey == null) {
            return null;
        }
        S3Object fullObject = null;
        try {
            fullObject = amazonS3Client.getObject(bucket, fileKey);
            if (fullObject == null) {
                return null;
            }
        } catch (AmazonS3Exception e) {
            throw new BadRequestException("다운로드 파일이 존재하지 않습니다.");
        }

        try {
            S3ObjectInputStream objectInputStream = fullObject.getObjectContent();
            bytes = IOUtils.toByteArray(objectInputStream);

        } catch (IOException e) {
            log.debug(e.getMessage(), e);
        } finally {

           return bytes;
        }

    }

일단 S3에서 가져온 파일을 다운로드 한뒤에 byte[]변수에 데이터를 담는다.



       for(MemberUploadFileDTO item : list) {
            byte[] in = awsS3UploaderUtil.downloadS3(item.getFileKey());
            Map<String,Object> temp = new HashMap<>();
            temp.put("item",in);
            temp.put("filename",item.getFileName());
            kg.add(temp);
        }


for 문을 통해서 S3에서 받은 내용과 원본 파일이름을 맵 List에 저장해준다.




try(ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {
     for(Map<String,Object> data : kg) {
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream((byte[])data.get("item"));
                ZipEntry zipEntry = new ZipEntry(String.valueOf(data.get("filename")));
                zipEntry.setSize(((byte[]) data.get("item")).length);
                zipEntry.setTime(System.currentTimeMillis());

                zipOutputStream.putNextEntry(zipEntry);

                StreamUtils.copy(byteArrayInputStream, zipOutputStream);
                zipOutputStream.closeEntry();
            }

            zipOutputStream.finish();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } 


bytearrayInputstream을 이용해서 s3에서 받은 byte를 넣어주고 zipentry생성후 zipoutputstream을 통해 output한다.

728x90
반응형

댓글