설명
DEXTUploadX5는 1.3.0.0 버전부터 압축 다운로드를 지원한다.
압축 다운로드는 여러 파일을 동시에 받기 위해서 서버에 대상 파일을 하나의 압축 파일로 묶도록 서버에 요청하고, 그 압축 파일을 내려받는다. 다른 예제에서 보았던, 단일/다중 파일 다운로드 예제와 달리, 압축 다운로드는 압축 과정을 서버에 일임하기 때문에, 대상 파일에 대한 다운로드 경로를 지정하는 속성(downUrl)에 영향을 받지 않는다.
압축 다운로드를 하려면, 압축을 담당하며, 압축된 파일을 다운로드할 수 있도록 그 경로값을 반환하는 주소를 setCompressURL 메소드를 사용하여 지정해야 한다. 그리고 단일/다중 파일 다운로드와 달리 압축 다운로드를 시작할 때에는 downloadCompressed 메소드를 호출한다.
var dx = dx5.get("component-id");
// downUrl 속성이 불필요하다.
// 다만 압축 작업을 해야 하는 서버에서 압축 대상을 구별하기 위한 vindex 속성값을 반드시 지정해 주어야 한다.
// vindex는 일종의 유니크한 문자열 값으로써, 가상 파일을 구별하기 위한 유일한 수단이다.
dx.addVirtualFile({ vindex: "IDX0003", name: "서강대교_509147.jpg", size: 509147 });
dx.addVirtualFile({ vindex: "IDX0004", name: "우도해변_239826.jpg", size: 239826 });
dx.addVirtualFile({ vindex: "IDX0005", name: "코스모스 (빈공간) 195779.jpg", size: 195779 });
// 압축을 처리하고 압축 파일 다운로드 경로를 반환하는 주소를 설정한다.
dx.setCompressURL("http://도메인/경로../service/compress.do");
// 플래그 값에 따라 다운로드를 수행한다.
// AUTO: 가상 파일을 다운로드한다.
// SELECTED: 선택된 가상 파일을 다운로드한다.
// CHECKED: 체크된 가상 파일을 다운로드한다.
dx.downloadCompressed("SELECTED");
파일 압축은 FileServiceController의 makeCompressedFile 메소드가 담당하며 compress.do로 매핑되어 있다.
DEXTUploadX5의 downloadCompressed 메소드를 호출하면, 압축 다운로드할 가상 파일의 vindex 속성값을 콤마(,)를 구분자로 하는 하나의 목록으로 하는 문자열 정보를 'DEXTUploadX5_VIndexes' 이름의 폼 데이터를 서버에 POST 형식으로 전송한다.
서버에서는 'DEXTUploadX5_VIndexes' 값을 얻어 콤마(,) 문자로 분리를 하여, 대상 정보를 얻게 된다.
압축이 되었다면, 반드시 대상 압축 파일을 다운로드할 수 있는 경로를 응답에 실어 클라이언트로 보내주어야 한다.
@RequestMapping(value = "/service/compress.do", method = RequestMethod.POST)
public void makeCompressedFile(@RequestParam(value = "DEXTUploadX5_VIndexes") String vindices, HttpServletRequest request, HttpServletResponse response) throws IOException {
String fileRoot = servletContext.getRealPath("/files");
List<File> files = new ArrayList<File>();
String[] tokens = vindices.split(",");
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].equals("IDX0003"))
files.add(new File(fileRoot, "attach/서강대교_509147.jpg"));
if (tokens[i].equals("IDX0004"))
files.add(new File(fileRoot, "attach/우도해변_239826.jpg"));
if (tokens[i].equals("IDX0005"))
files.add(new File(fileRoot, "attach/코스모스 (빈공간) 195779.jpg"));
}
// 임시 위치에 압축 파일을 생성한다.
CompressUtil cu = new CompressUtil();
File zipped = cu.zip(files, new File(fileRoot, "/temp/"), "UTF-8", false, false);
...
String compresskey = FileRepository.addFileEntity(target);
response.setContentType("text/plain");
// 예제에서는 동일한 매핑 주소를 GET으로 요청하면 압축된 파일을 다운로드할 수 있다.
// compresskey 쿼리스트링은 다운로드할 대상을 가리킨다.
response.getWriter().write(request.getRequestURL().append("?compresskey=".concat(compresskey)).toString());
}
파일 다운로드는 FileServiceController의 downloadCompressedFile 메소드가 담당하며 compress.do로 매핑되어 있다.
@RequestMapping(value = "/service/compress.do", method = RequestMethod.GET)
public ModelAndView downloadCompressedFile(@RequestParam(value = "compresskey") String key, HttpServletResponse response) throws IOException {
FileEntity target = FileRepository.getFileEntity(key);
if (target != null) {
DEXTUploadNJFileDownloadView dextnj = new DEXTUploadNJFileDownloadView();
dextnj.setFile(target.getFile());
dextnj.setCharsetName("UTF-8");
// 압축 다운로드는 partial content download 기능은 사용하지 않도록 한다. (디폴트)
dextnj.setAllowingWeakRange(false);
// 압축 다운로드는 클라이언트 캐시가 사용되지 않도록 한다.
dextnj.setUseClientCache(false);
// 압축 파일은 일회성 파일이므로 응답 데이터에 기록이 끝나면, 삭제한다.
dextnj.setRemoveAfterDownloading(true);
return new ModelAndView(dextnj);
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "주어진 키에 해당하는 파일 정보가 없습니다.");
return null;
}
}
파일을 압축하는 작업은 서버의 리소스(CPU, I/O)를 상당히 소모하는 작업이기 때문에, 크기가 큰 파일 또는 압축 파일의 대상이 되는 파일의 개수가 많은 경우, 서버에 상당한 오버헤드가 발생하므로, 상황에 따라 파일 압축 과정을 기다리는 시간이 길어질 수 있으며, 이는 세션이 끊기는 문제가 초래하거나, 서비스 자체가 중지되는 중대한 문제로 이어질 수 있다. 따라서 압축 다운로드을 하기 위한 정책적 제한을 수립 후, 기능을 사용하는 것을 권장한다.
DEXTUploadNJ 제품은 압축 작업을 위해서 CompressUtil이라는 클래스를 제공하며, 이 클래스는 Apache Commons Compress 라이브러리를 사용한다. 자세한 사항은 DEXTUploadNJ 제품 매뉴얼을 참고한다.
예제
|
압축 다운로드 |
|
자동 바인딩된 압축 다운로드
압축은 서버에서 진행된다. 압축이 진행되는 동안은 진행창이 표시되지만, 압축된 파일을 다운로드할 때는 단일 파일 다운로드로 전환되기 때문에 다운로드 과정에 대한 자체 진행창은 제공되지 않는다. |