대용량 파일 업로드

Home > 대용량 업로드 > 예제 01

설명

대용량 파일 업로드는 개별 파일이 2GB가 넘더라도 전송할 수 있는 기능이다.

이와 달리, 업로드할 총 파일의 크기(기타 데이터 포함)가 2GB가 넘지 않는다면 굳이 대용량 파일 업로드를 사용할 필요 없다.

일반 업로드의 경우 10개의 파일 있을 때, ORAF는 한 번의 전송으로 10개의 파일을 모두 전송하며, OROF 모드로 업로드를 하면, 개별 전송이기 때문에 10회 전송한다.

이와 달리 대용량 파일 업로드는 OROF처럼 개별 파일마다 전송을 할 뿐만 아니라 개별 파일을 정해진 크기로 나눈 청크(블록) 단위로 서버에 전송하기 때문에, 최소 20회 이상의 전송 작업이 필요하다.

// 파일 업로드를 처리할 경로를 설정한다.
dx.setUploadURL("http://../service/extension-upload.do");

// 대용량 파일 업로드 방식을 사용하려면 EXTS로 설정한다.
dx.setUploadMode("EXTS");

// 파일을 쪼갤 블록 크기를 byte 단위로 설정한다.
dx.setUploadBlockSize(10 * 1024 * 1024);

DEXTUploadX5는 파일을 보내는 sender 역할을 수행한다. 이와 달리 DEXTUploadNJ는 서버 측에 파일을 받는 receiver 역할을 담당한다.

이 샘플은 파일 업로드 처리를 서블릿(ExtensionUpload 클래스)이 담당하며 web.xml에 extension-upload.do로 매핑되어 있다.

쪼개진 파일을 하나로 합쳐 서버에 임시 파일을 생성하는 것은 ExtensionFileUploadFilter 필터 클래스가 미리 처리한다. 임시파일이 생성되면, 업로드된 결과를 request 객체에 실어 ExtensionUpload 서블릿으로 전달한다.

그러므로 서블릿 코드에서는 OROF처럼 완전한 파일이 전달된 것처럼 처리하면 된다.

web.xml에 ExtensionFileUploadFilter 필터는 다음처럼 설정한다.

<!--  web.xml 설정 -->
<filter>
	<filter-name>extensionUploadFilter</filter-name>
	<filter-class>devpia.dextuploadnj.support.common.ExtensionFileUploadFilter</filter-class>
	<init-param>
		<param-name>tempRepository</param-name>
		<param-value>files/temp</param-value>
	</init-param>
	<init-param>
		<param-name>defaultRepository</param-name>
		<param-value>files/store</param-value>
	</init-param>
	<init-param>
		<param-name>autoMakingDirectory</param-name>
		<param-value>true</param-value>
	</init-param>
	<init-param>
		<param-name>enableCleaner</param-name>
		<param-value>true</param-value>
	</init-param>
	<init-param>
		<param-name>timeAgo</param-name>
		<param-value>24</param-value>
	</init-param>
	<init-param>
		<param-name>licenseFilePath</param-name>
		<param-value>WEB-INF/dextuploadnj.config</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>extensionUploadFilter</filter-name>
	<servlet-name>ExtensionUpload</servlet-name>
</filter-mapping>

ExtensionUpload 서블릿에서는 FileUpload 객체를 사용하여 업로드 정보를 받을 수 있다.

FileUpload dextnj = null;
		
try {

	dextnj = new FileUpload(request);
			
	dextnj.prepare();
  
	// 대용량 파일 업로드는 OROF 업로드 방식처럼 파일 1개만 전달된다.
	FileItem item = dextnj.getFileItem();
	
	if (item.isEmpty() == false) {
		// 대상이 올바른 파일이라면 실제 저장할 위치로 임시 파일을 저장(복사 혹은 이동)한다.
		// 인자로 주어진 디렉터리 경로가 없다면 extensionUploadFilter 필터의 defaultRepository 파라미터 값으로 설정된 경로가 대상이 된다.
		item.save();
		...
	}
	
	...
	
} finally {
	// 리소스를 제거한다. 삭제가 되지 않은 임시 파일이 있다면 모두 삭제된다.
	if (dextnj != null) dextnj.close();
}

ExtensionFileUploadFilter 필터를 통하여 서버에 대용량 임시 파일을 생성하는 것과 달리 FileItem#save 메소드를 사용하여 원하는 위치로 저장하는 과정은 매우 느릴 수 있다.

이런 이유는 서버에서 용량이 큰 파일이 대상 위치로 저장하는 과정이 '복사' 작업을 통해서 이루어지기 때문이다.

만일 임시 파일이 생성되는 위치와 최종적으로 저장할 위치가 같은 파티션이라면 '복사'가 아닌 '이동'이 되므로 매우 빠른 처리가 가능하다.

예제