파일 압축 다운로드

Home > 기본 예제 > 예제 12

설명

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");

파일 압축과 다운로드는 FileCompression 서블릿이 담당하며 web.xml에 compress.do로 매핑되어 있다. DEXTUploadX5의 downloadCompressed 메소드를 호출하면, 압축 다운로드할 가상 파일의 vindex 속성값을 콤마(,)를 구분자로 하는 하나의 목록으로 하는 문자열 정보를 'DEXTUploadX5_VIndexes' 이름의 폼 데이터를 서버에 POST 형식으로 전송한다.

서버에서는 'DEXTUploadX5_VIndexes' 값을 얻어 콤마(,) 문자로 분리를 하여, 대상 정보를 얻게 된다.

압축이 되었다면, 반드시 대상 압축 파일을 다운로드할 수 있는 경로를 응답에 실어 클라이언트로 보내주어야 한다.

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	List<File> files = new ArrayList<File>();
	String vindices = request.getParameter("DEXTUploadX5_VIndexes");
	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());
}
/**
 * 파일(압축된) 다운로드를 수행한다.
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	String compresskey = request.getParameter("compresskey");
	
	// 압축된 대상을 얻는다.
	...
	
	if (target != null) {
		FileDownload dextnj = new FileDownload();
		// 압축 다운로드는 partial content download 기능은 사용하지 않도록 한다. (디폴트)
		dextnj.setAllowingWeakRange(false);
		// 압축 파일은 일회성 파일이므로 응답 데이터에 기록이 끝나면, 삭제한다.
		dextnj.setRemoveAfterDownloading(true);
		// 다운로드할 때 클라이언트 캐시가 사용되지 않도록 파라미터를 설정한다.
		dextnj.download(request, response, target.getFile(), target.getFilename(), null, false, false);
	} else {
	    response.sendError(404);
	}
}

파일을 압축하는 작업은 서버의 리소스(CPU, I/O)를 상당히 소모하는 작업이기 때문에, 크기가 큰 파일 또는 압축 파일의 대상이 되는 파일의 개수가 많은 경우, 서버에 상당한 오버헤드가 발생하므로, 상황에 따라 파일 압축 과정을 기다리는 시간이 길어질 수 있으며, 이는 세션이 끊기는 문제가 초래하거나, 서비스 자체가 중지되는 중대한 문제로 이어질 수 있다. 따라서 압축 다운로드을 하기 위한 정책적 제한을 수립 후, 기능을 사용하는 것을 권장한다.

DEXTUploadNJ 제품은 압축 작업을 위해서 CompressUtil이라는 클래스를 제공하며, 이 클래스는 Apache Commons Compress 라이브러리를 사용한다. 자세한 사항은 DEXTUploadNJ 제품 매뉴얼을 참고한다.

예제

압축 다운로드

압축은 서버에서 진행된다. 압축이 진행되는 동안은 진행창이 표시되지만, 압축된 파일을 다운로드할 때는 단일 파일 다운로드로 전환되기 때문에 다운로드 과정에 대한 자체 진행창은 제공되지 않는다.