이번엔 두번째 글로 자바에서 여러개의 파일을 하나의 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
'Java > Java' 카테고리의 다른 글
[ Java ] 구글 Firebase 메시지 (앱 푸쉬 알림) 전송하기 (Admin SDK) (0) | 2023.05.25 |
---|---|
[ Java ] HTML 페이지를 PDF로 변환하기 ( itextpdf 사용 ) (0) | 2023.02.13 |