반응형
환경
- Spring Framework
요구사항
- 서버에 있는 .min.js와 css와 images 폴더를 zip 파일로 다운로드
프론트
1. html 영역
<!--다운로드 버튼-->
<a href="void(0);" onClick="downloadAPI('hahaApi')">hahaApi 다운로드</a>
2. javascript 영역
function downloadAPI(apiName){
// 컨트롤러 경로
var url = `/apiDownload?apiName=${apiName}`;
// 새로운 <a> 엘리먼트 생성
var link = document.createElement("a");
// 다운로드할 파일의 URL 설정
link.href = url;
// 다운로드할 파일의 이름 설정
link.download = url.substring(url.lastIndexOf("/") + 1);
// body에 추가
document.body.appendChild(link);
// 클릭 이벤트 발생시킴
link.click();
// 사용이 끝나면 제거
document.body.removeChild(link);
}
3. java 영역
@Controller
public class DownloadController {
@RequestMapping(value="/apiDownload", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Resource> apiDownload(String apiName, Model model) throws IOException {
String filePath = servletContext.getRealPath("/js/"+apiName+"/");
String zipFileName = apiName+".zip";
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zipOut = new ZipOutputStream(baos)) {
addFileToZip(filePath, zipOut, apiName+".min.js");
addFileToZip(filePath, zipOut, apiName+".css");
addFolderToZip(filePath+"images","images", zipOut);
}
byte[] zipBytes = baos.toByteArray();
ByteArrayResource resource = new ByteArrayResource(baos.toByteArray());
// 다운로드할 파일명 설정
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + zipFileName);
headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(zipBytes.length));
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// ResponseEntity를 사용하여 HTTP 응답 생성
return ResponseEntity
.status(HttpStatus.OK)
.headers(headers)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
}catch (IOException ioe) {
LOGGER.debug("api file write io exception",ioe);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
// 파일을 zip 파일에 추가하는 메서드
private void addFileToZip(String filePath, ZipOutputStream zipOut, String entryName) throws IOException {
File file = new File(filePath,entryName);
if (file.exists() && file.isFile()) {
try (FileInputStream in = new FileInputStream(file)) {
zipOut.putNextEntry(new ZipEntry(entryName));
int len = 0;
byte[] buf = new byte[1024];
while ((len = in.read(buf)) > 0) {
zipOut.write(buf, 0, len);
}
zipOut.closeEntry();
}
}
else{
throw new FileNotFoundException("File not found: " + file.getAbsolutePath());
}
}
// 폴더 내 파일을 zip 파일에 추가하는 메서드
private void addFolderToZip(String folderPath, String folderName, ZipOutputStream zipOut) throws IOException {
File folder = new File(folderPath);
if (folder.exists() && folder.isDirectory() && folder.listFiles() != null) {
for (File file : folder.listFiles()) {
if (file.isFile()) {
try(FileInputStream in = new FileInputStream(file)){
zipOut.putNextEntry(new ZipEntry(folderName+"/"+file.getName()));
int len = 0;
byte[] buf = new byte[4096];
while((len = in.read(buf)) > 0) {
zipOut.write(buf, 0, len);
}
zipOut.closeEntry();
}
}
else if (file.isDirectory()){
String childFolderName = folderName + "/" + file.getName();
addFolderToZip(file.getAbsolutePath() , childFolderName, zipOut);
}
}
}
else{
throw new FileNotFoundException("Folder not found: " + folder.getAbsolutePath());
}
}
}
반응형