이번엔 두번째 글로 자바에서 여러개의 파일을 하나의 zip으로 압축하여 다운로드하는 과정을 진행해 보려고 합니다.

IDE : intelliJ

자바 : Java 17

스프링 부트 : Spring Boot 3.0.2

템플릿 엔진 : Thymeleaf

빌드 도구 : Gradle

그외 Lombok , spring boot web

 

작성자의 OS는 Mac입니다. ( Window의 경우 파일 디렉토리 확인 바랍니다. )

 

 

 

 

 

 

 

 

 

src 하위 패키지 구조 입니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

우선 DTO 입니다.

압축 될 파일의 이름과 파일을 담아둘 List 변수를 같이 선언해둡니다.

@Getter
@Setter
public class DownloadDto {
    private String zipFileName; // 압축될 파일 이름 (xxxx.zip)
    private List<String> sourceFiles; // 압축될 파일 리스트
}

 

바로 실제 압축 동작이 실행되는 소스 입니다.

@Component
@RequiredArgsConstructor
public class DownloadUtil {

    public void downloadZip(DownloadDto downloadDto, HttpServletResponse response) {
        
        // 압축될 파일명이 존재하지 않을 경우
        if(downloadDto.getZipFileName() == null || "".equals(downloadDto.getZipFileName()))
            throw new IllegalArgumentException("파일명이 존재하지 않습니다.");
        
        // 파일이 존재하지 않을 경우
        if(downloadDto.getSourceFiles() == null || downloadDto.getSourceFiles().size() == 0)
            throw new IllegalArgumentException("파일이 존재하지 않습니다.");
        
        // ======================== 파일 다운로드 위한 response 세팅 ========================
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=" + new String(downloadDto.getZipFileName().getBytes(StandardCharsets.UTF_8)) + ".zip;");
        response.setStatus(HttpServletResponse.SC_OK);
        // =============================================================================
        
        // 본격적인 zip 파일을 만들어 내기 위한 로직
        try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())){
            
            // List<String> 변수에 담아두었던 파일명을 검색한다
            for (String sourceFile : downloadDto.getSourceFiles()) {
                Path path = Path.of(sourceFile);
                try (FileInputStream fis = new FileInputStream(path.toFile())) {
                    // 압축될 파일명을 ZipEntry에 담아준다
                    ZipEntry zipEntry = new ZipEntry(path.getFileName().toString());
                    // 압축될 파일명을 ZipOutputStream 에 담아준다
                    zos.putNextEntry(zipEntry);
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = fis.read(buffer)) >= 0) {
                        zos.write(buffer, 0, length);
                    }
                } catch (FileNotFoundException e) {
                    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                    throw new IllegalArgumentException("파일 변환 작업중, [ " + sourceFile + " ] 파일을 찾을 수 없습니다.");
                } catch (IOException e) {
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    throw new IllegalArgumentException("파일 변환 작업중, [ " + sourceFile + " ] 파일을 다운로드 할 수 없습니다.");
                } finally {
                    // ZipOutputStream 에 담아둔 압축될 파일명을 flush 시켜준다
                    zos.flush();
                    // ZipOutputStream 에 담아둔 압축될 파일명을 close 시켜준다
                    zos.closeEntry();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // response 에 담아둔 파일을 flush 시켜준다
                response.flushBuffer();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

파일의 경로를 찾은 후 ZipEntry에 담아 압축파일을 생성하는 과정입니다

.

햇갈리실 수 있는 List<String> 에 변수를 담은 컨트롤러 부분입니다.

 

@Controller
@RequiredArgsConstructor
public class DownloadController {
    private final DownloadUtil downloadUtil;

    @GetMapping("/download/zip")
    public void downloadZip(HttpServletResponse response) {
        // 파일 작업처리를 위한 DTO 선언
        DownloadDto downloadDto = new DownloadDto();
        // 압축할 파일 일므 지정
        downloadDto.setZipFileName("imageZip");
        // 파일 경로를 담아둘 List 선언
        List<String> downloadFileList = new ArrayList<>();

        // ===================================== 여기에 파일 경로를 넣어주세요 ==============================================================
        // 작성자는 Mac 기준으로 작성했습니다.
        downloadFileList.add("/Users/jeon/Documents/JavaProject/Blog/zip/src/main/resources/static/images/beach.jpg");
        downloadFileList.add("/Users/jeon/Documents/JavaProject/Blog/zip/src/main/resources/static/images/bird.jpg");
        downloadFileList.add("/Users/jeon/Documents/JavaProject/Blog/zip/src/main/resources/static/images/corgi.jpg");
        // Window 예시
        // downloadFileList.add("C:\\Users\\jeon\\Documents\\JavaProject\\Blog\\zip\\src\\main\\resources\\static\\images\\beach.jpg");
        // downloadFileList.add("C:\\Users\\jeon\\Documents\\JavaProject\\Blog\\zip\\src\\main\\resources\\static\\images\\bird.jpg");
        // downloadFileList.add("C:\\Users\\jeon\\Documents\\JavaProject\\Blog\\zip\\src\\main\\resources\\static\\images\\bird.jpg");
        downloadDto.setSourceFiles(downloadFileList);
        // ============================================================================================================================


        // 데이터를 담은 DTO 를 압축 파일 생성 및 다운로드를 위한 메소드에 전달
        try {
            downloadUtil.downloadZip(downloadDto, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

실행 화면 입니다

 

해당 소스 GitHub : https://github.com/wjsskagur/zip

 

+ Recent posts