티스토리 뷰
반응형
로직 : 자바에서 JSON을 csv 파일로 만든 다음 zip 아카이브 파일로 압축하여 다운로드
* 이 때, 임시로 /tmp/ 디렉터리에 csv 파일과 zip 파일을 생성하여 response에 zip 파일을 내려준 후, 임시 디렉터리에 생성된 csv 파일과 zip 파일을 일정 시간 뒤에 삭제한다.
csv 파일 다운로드
컨트롤러 작성
@ApiOperation(value = "로그 리스트 전체 다운로드")
@GetMapping(value = "/download", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity downloadUpdateLog(String uuid) throws Exception {
String fileName = uuid + ".csv";
HttpHeaders header = new HttpHeaders();
header.add("Content-Type", "text/csv");
header.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
return new ResponseEntity(logService.downloadUpdateLog(uuid), header, HttpStatus.CREATED);
}
서비스 작성
public String downloadUpdateLog(String uuid) throws IllegalAccessException {
String index = Constants.INDEX_PREFIX_NAME + "-" + uuid;
String query = sourceBuilder.makeSearchQueryScroll();
List<Map<String, Object>> data = new ArrayList<>();
Map<String, Object> result = searchDAO.requestPostScrollSearch(index, query);
List<Map<String, Object>> list;
String scrollId = (String) result.get("_scroll_id");
do {
result = (Map<String, Object>) result.get("hits");
list = (List<Map<String, Object>>) result.get("hits");
for (Map<String, Object> log : list) {
data.add(EsParseUtils.getValue(log, "_source"));
}
if (!StringUtils.isEmpty(scrollId)) {
query = sourceBuilder.makeSearchQueryScroll(scrollId);
result = searchDAO.requestPostScrollIdSearch(index, query);
}
} while (list.size() > 0);
return createCSV(data);
}
private String createCSV(List<Map<String, Object>> list) throws IllegalAccessException {
StringBuffer parameter = new StringBuffer();
parameter.append("thingName,status,timestamp\n");
for (Map<String, Object> data : list) {
String thingName = (String) data.get("thingName");
String status = (String) data.get("status");
String timestamp = (String) data.get("timestamp");
parameter.append(thingName).append(",")
.append(status).append(",")
.append(timestamp).append("\n");
}
parameter.delete(parameter.length()-2, parameter.length());
return parameter.toString();
}
zip 파일 다운로드
컨트롤러 작성
@ApiOperation(value = "로그 리스트 전체 다운로드")
@GetMapping(value = "/download/{uuid}")
public ResponseEntity<InputStreamResource> downloadUpdateLog(@PathVariable String uuid) throws Exception {
String fileName = uuid + "-" + UUID.randomUUID();
String zipFileName = fileName + ".zip";
MediaType mediaType = new MediaType("application","zip");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(mediaType);
httpHeaders.setContentDispositionFormData("attachment", zipFileName);
return new ResponseEntity<InputStreamResource>(logService.downloadUpdateLog(uuid, fileName), httpHeaders, HttpStatus.OK);
}
서비스 작성
public InputStreamResource downloadUpdateLog(String uuid, String fileName) throws Exception {
String path = "/tmp/";
String csvFileName = fileName + ".csv";
String zipFileName = fileName + ".zip";
File file = null;
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try {
// 임시 .csv 파일 생성
file = new File(path + csvFileName);
fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write("thingName,status,timestamp");
String index = Constants.INDEX_PREFIX_NAME + "-" + uuid;
String query = sourceBuilder.makeSearchQueryScroll();
Map<String, Object> result = searchDAO.requestPostScrollSearch(index, query);
String scrollId = (String) result.get("_scroll_id");
List<Map<String, Object>> list;
do {
result = (Map<String, Object>) result.get("hits");
list = (List<Map<String, Object>>) result.get("hits");
for (Map<String, Object> log : list) {
log = EsParseUtils.getValue(log, "_source");
String thingName = (String) log.get("thingName");
String status = (String) log.get("status");
String timestamp = (String) log.get("timestamp");
bufferedWriter.newLine();
bufferedWriter.write(thingName + "," + status + "," + timestamp);
}
if (!StringUtils.isEmpty(scrollId)) {
query = sourceBuilder.makeSearchQueryScroll(scrollId);
result = searchDAO.requestPostScrollIdSearch(index, query);
}
} while (list.size() > 0);
} catch (Exception e) {
log.error("", e);
throw new EsServiceException(e);
} finally {
if(bufferedWriter != null) {
try{
bufferedWriter.close();
} catch(IOException e) {
log.error("", e);
}
}
if(fileWriter != null) {
try{
fileWriter.close();
} catch(IOException e) {
log.error("", e);
}
}
}
// 임시 .zip 파일 압축
ZipUtils.fileCompress(path + csvFileName, path + zipFileName);
// .zip 파일 다운로드
File zipFile = new File(path + zipFileName);
tempDataDeleteTimer(path + csvFileName);
tempDataDeleteTimer(path + zipFileName);
return new InputStreamResource(new FileInputStream(zipFile));
}
private void tempDataDeleteTimer(String fileName) {
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
File file = new File(fileName);
if (file.delete()) {
log.debug(fileName + " 파일 삭제");
} else {
log.debug(fileName + " 파일 삭제 실패");
}
}
};
timer.schedule(timerTask, 1000 * 60); // 60 seconds
}
ZipUtils
import lombok.extern.log4j.Log4j2;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Log4j2
public class ZipUtils {
public static boolean directoryCompress(String path, String zipFileName) {
File[] files = new File(path).listFiles();
byte[] buf = new byte[4096];
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(path + zipFileName))) {
for (int i=0; i<files.length; i++) {
try (FileInputStream in = new FileInputStream(files[i])) {
Path p = Paths.get(String.valueOf(files[i]));
String fileName = p.getFileName().toString();
ZipEntry ze = new ZipEntry(fileName);
out.putNextEntry(ze);
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
}
}
} catch (IOException e) {
log.error(e);
return false;
}
return true;
}
public static boolean fileCompress(String targetFile, String zipFile) {
File file = new File(targetFile);
byte[] buf = new byte[4096];
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile))) {
try (FileInputStream in = new FileInputStream(file)) {
Path p = Paths.get(String.valueOf(file));
String fileName = p.getFileName().toString();
ZipEntry ze = new ZipEntry(fileName);
out.putNextEntry(ze);
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
}
} catch (IOException e) {
log.error(e);
return false;
}
return true;
}
}
반응형
'Java' 카테고리의 다른 글
[Java] JSP에서 Date 타입으로 파라미터 값 전달 (6) | 2021.02.22 |
---|---|
[Java] @RefreshScope (0) | 2021.02.10 |
[Java] Url 파일 다운로드 (0) | 2021.02.10 |
[Java] Timestamp 비교 (0) | 2021.02.10 |
[Java] 객체 정렬 방법 (Collections.sort()) (0) | 2021.02.10 |