웹페이지에 대용량 업로드·다운로드 임베드

적용 방식

웹 컨트롤은 페이지에 스크립트와 스타일을 포함하고, 컨트롤을 렌더할 요소를 지정한 뒤 exabyter.create() 한 번으로 생성합니다. 하나의 컨트롤로 업로드·다운로드를 모두 처리할 수 있으며, transferMode로 용도를 좁힐 수 있습니다.

개요

웹 임베드란

웹페이지의 특정 요소(예: <div id="fileControl">)에 파일 전송 컨트롤을 렌더하고, exabyter.create(options)가 반환한 control 객체로 전송을 제어하는 방식입니다. 컨트롤은 브라우저에서 파일을 슬라이스 단위로 분할해 여러 세션으로 병렬 전송하므로, 브라우저 기본 업로드로는 어려운 수 GB~수십 GB 파일도 안정적으로 처리합니다.

공통 준비

리소스 포함 — 페이지 <head>에 스타일과 스크립트를 포함합니다.

html
<link rel="stylesheet" type="text/css" href="/exabyter/exabyter.css">
<script src="/exabyter/exabyter.js"></script>

컨테이너 요소 — 컨트롤이 렌더될 빈 요소를 배치합니다.

html
<div id="fileControl"></div>

컨트롤 생성exabyter.create()에 옵션 객체를 전달하면 control 인스턴스가 반환됩니다.

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setViewType: 'ListView',
    transferMode: 'both',
    setUploadURL: '/exabyter/example/upload.jsp'
  });
</script>

서버 엔드포인트 — 업로드 수신과 다운로드 스트림은 서버 스크립트가 담당합니다.

목적엔드포인트옵션
업로드 수신upload.jspsetUploadURL / uploadURL
다운로드 스트림download.jsp다운로드 목록의 downloadURL
전송 모니터(선택)transferInfo.jspmonitorURL

핵심 API

목적호출
컨트롤 생성exabyter.create(options)
파일 선택 대화상자control.openFileDialog()
폴더 선택 대화상자control.directoryDialog()
업로드 시작control.upload()
다운로드 목록 지정control.setDownloadList(items)
다운로드 시작control.download()

기본 흐름

  1. 페이지에 exabyter.css · exabyter.js 포함
  2. 컨트롤을 렌더할 컨테이너 요소 배치
  3. exabyter.create(options)로 컨트롤 생성 → control 확보
  4. (업로드) control.openFileDialog()로 파일 첨부 → control.upload()
  5. (다운로드) control.setDownloadList(items)로 목록 지정 → control.download()

적용 방식 선택

설명

하나의 컨트롤이 업로드·다운로드를 모두 지원합니다. transferMode로 용도를 정하고, setTransferStart로 첨부·목록 지정 후 전송을 자동으로 시작할지 버튼 클릭 등 수동으로 시작할지 선택합니다.

사용 옵션

옵션설명
transferMode"both" · "upload" · "download"컨트롤이 처리할 전송 방향
setTransferStart.upload"auto" · "manual"파일 첨부 후 업로드 자동/수동 시작
setTransferStart.download"auto" · "manual"목록 지정 후 다운로드 자동/수동 시작
setViewType"ListView"컨트롤 뷰 형태

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setViewType: 'ListView',
    transferMode: 'both',
    setTransferStart: {
      upload: 'auto',      // 첨부하면 바로 업로드
      download: 'manual'   // 목록 지정 후 버튼으로 시작
    },
    setUploadURL: '/exabyter/example/upload.jsp'
  });
</script>

처리 순서

  1. transferMode로 업로드 전용·다운로드 전용·양방향 결정
  2. setTransferStart로 방향별 자동/수동 시작 정책 결정
  3. 수동(manual)이면 페이지의 버튼에서 control.upload() · control.download()를 호출

업로드 UI

설명

업로드는 파일·폴더를 첨부한 뒤 control.upload()로 시작합니다. 첨부는 파일 선택 대화상자, 폴더 선택 대화상자, 드롭존(드래그 앤 드롭)으로 받을 수 있습니다.

사용 API·옵션

대상호출·옵션설명
파일 첨부control.openFileDialog()파일 선택 대화상자 열기
폴더 첨부control.directoryDialog()폴더 선택 대화상자 열기
드롭존enableDropZone: true드래그 앤 드롭 첨부 허용
폴더 추가addFolder: true폴더 단위 첨부 허용
업로드 시작control.upload()첨부된 항목 전송 시작

예시

html
<div id="fileControl"></div>

<button onclick="control.openFileDialog()">파일 선택</button>
<button onclick="control.directoryDialog()">폴더 선택</button>
<button onclick="control.upload()">업로드</button>

<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    transferMode: 'upload',
    setTransferStart: { upload: 'manual' },
    setUploadURL: '/exabyter/example/upload.jsp',
    enableDropZone: true,
    addFolder: true
  });
</script>

처리 순서

  1. 컨트롤 생성(transferMode: 'upload')
  2. openFileDialog() · directoryDialog() 또는 드롭존으로 항목 첨부
  3. control.upload() 호출 → 슬라이스 분할·병렬 세션으로 setUploadURL에 전송

다운로드 UI

설명

다운로드는 control.setDownloadList()로 대상 목록을 지정한 뒤 control.download()로 시작합니다. 각 항목은 서버의 다운로드 엔드포인트(downloadURL)와 표시 이름·크기를 가집니다.

다운로드 항목 필드

필드타입설명
downloadURLstring다운로드 스트림 엔드포인트(download.jsp?fileName=...)
displayFileNamestring목록에 표시할 파일명
fileSizenumber파일 크기(바이트)
isFolderboolean폴더 여부

예시

html
<button onclick="control.download()">다운로드</button>

<script>
  control.setDownloadList([
    {
      downloadURL: '/exabyter/example/download.jsp?fileName=500MB.dat',
      displayFileName: '500MB.dat',
      fileSize: 524288000,
      isFolder: false
    }
  ]);
</script>

처리 순서

  1. 컨트롤 생성(transferMode: 'download' 또는 'both')
  2. setDownloadList([...])로 대상 목록 지정
  3. control.download() 호출 → 각 항목을 downloadURL에서 슬라이스로 병렬 수신

경로와 정책

파일이 실제로 저장·조회되는 위치와, 어떤 파일을 얼마만큼 받을지 결정하는 정책을 다룹니다. 저장 경로는 서버 스크립트에서 결정하며, 파일 종류·개수·크기 제한은 컨트롤 옵션으로 지정합니다.

저장 경로

설명

업로드 저장 경로와 다운로드 원본 경로는 서버 스크립트에서 결정합니다. 업로드는 ExabyterUpload 생성자에 저장 디렉터리를 넘기고, 다운로드는 스트림 스크립트에서 스토리지 루트를 지정해 파일을 읽습니다. 경로는 서버에만 존재하므로 클라이언트에는 노출되지 않습니다.

서버 설정 지점

대상위치
업로드 저장 디렉터리upload.jspnew ExabyterUpload(request, response, maxPostSize, directory)예: /storage/exabyter
다운로드 원본 루트download.jspfilePath예: /storage/exabyter/
전송별 하위 폴더(선택)uploader.setDirectory(directory + "\\" + _transferId)_transferId 기준 분리

업로드 저장 경로 (JSP)

jsp
<%@ page import="com.innorix.transfer.ExabyterUpload" %>
<%
if (request.getMethod().equals("POST")) {
    String directory   = "/storage/exabyter";       // 저장 루트
    int    maxPostSize  = 2147482624;       // 최대 요청 크기(바이트)
    ExabyterUpload uploader = new ExabyterUpload(request, response, maxPostSize, directory);

    // 전송 단위로 하위 폴더를 분리하려면:
    // uploader.setDirectory(directory + "\\" + uploader.getParameter("_transferId"));

    String retval = uploader.run();         // 슬라이스 저장 처리
    uploader = null;
}
%>

다운로드 원본 경로 (JSP)

jsp
<%
// 스토리지 루트. 디렉터리 구분은 윈도우/유닉스 모두 "/" 사용 가능
//   윈도우 - C:/storage/path/data
//   유닉스 - /storage/path/data
String filePath = "/storage/exabyter/";
String fileName = request.getParameter("fileName");
File file = new File(filePath + fileName);
%>

처리 순서

  1. 업로드: ExabyterUpload 생성 시 저장 루트(directory) 지정 → run()이 슬라이스를 해당 경로에 기록
  2. (선택) setDirectory()_transferId 등 전송 단위 하위 폴더 분리
  3. 다운로드: 스트림 스크립트의 filePath(스토리지 루트) + 요청 fileName으로 원본 파일 확인 후 스트리밍

파일 정책

설명

받을 파일의 종류·개수·크기를 컨트롤 옵션으로 제한합니다. 허용/차단 확장자, 파일 수, 개별·총합 크기 상한을 지정할 수 있으며, 서버는 maxPostSize로 요청 본문 크기를 이중으로 제한합니다.

사용 옵션

옵션타입설명
allowTypestring[]허용 확장자 목록 (예: ["zip","pdf"])
denyTypestring[]차단 확장자 목록 (예: ["exe","bat"])
maxFileCountnumber최대 첨부 파일 수
maxFileSizenumber개별 파일 최대 크기(바이트)
maxTotalSizenumber전체 합계 최대 크기(바이트)
setAttachDuplicateboolean동일 파일 중복 첨부 허용 여부

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    allowType: ['zip', 'pdf', 'xlsx'],   // 허용 확장자
    denyType: null,                       // 차단 확장자(허용과 택일)
    maxFileCount: 100,
    maxFileSize: 21474836480,             // 20 GB
    maxTotalSize: 107374182400            // 100 GB
  });
</script>

서버 측 요청 크기 제한은 업로드 스크립트에서 지정합니다.

jsp
int maxPostSize = 2147482624; // 서버가 허용하는 최대 요청 본문 크기(바이트)
ExabyterUpload uploader = new ExabyterUpload(request, response, maxPostSize, directory);

처리 순서

  1. allowType 또는 denyType 중 하나로 확장자 정책 지정
  2. maxFileCount · maxFileSize · maxTotalSize로 수량·용량 상한 지정
  3. 서버 maxPostSize로 요청 본문 크기를 이중 제한

접근 권한

설명

컨트롤은 페이지 세션의 쿠키를 전송 요청에 함께 실어 보내고, 서버 스크립트는 세션·커스텀 파라미터로 요청 주체를 식별합니다. 사용자 식별자나 임의 값을 postData·custom으로 실어 보내 서버에서 권한을 검증할 수 있습니다.

사용 옵션·파라미터

옵션설명
cookie요청에 포함할 쿠키(기본 document.cookie)
postData업로드 요청에 함께 보낼 커스텀 POST 데이터 객체
custom커스텀 인자 객체
userid · UserPart업로드 시 사용자 식별 값

업로드 스크립트가 받는 커스텀/식별 파라미터:

서버 파라미터설명
type커스텀 POST 파라미터 1
part커스텀 POST 파라미터 2
el컨트롤 엘리먼트 ID
_transferId전송 식별자

예시

클라이언트 — 사용자 식별 값 전달:

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    userid: 'user-1024',
    postData: { type: 'report', part: 'q3' }
  });
</script>

서버 — 값 확인 후 권한 검증:

jsp
<%
String userType = uploader.getParameter("type");   // "report"
String part     = uploader.getParameter("part");   // "q3"
String el       = uploader.getParameter("el");
// session.getId(), userType 등으로 접근 권한 검증
%>

처리 순서

  1. postData·custom·userid로 요청 주체·맥락 값을 실어 전송
  2. 컨트롤이 세션 쿠키와 함께 서버로 요청
  3. 서버가 세션·커스텀 파라미터로 권한을 확인하고, 필요 시 커스텀 오류로 차단

만료·보안

설명

전송 구간 암호화와 서버 측 접근 차단으로 보안을 강화합니다. 컨트롤은 전송 데이터·메타데이터 암호화 옵션을 제공하며, 서버는 커스텀 오류로 특정 요청을 만료·차단할 수 있습니다. CORS 자격 증명 헤더로 세션 기반 접근을 유지합니다.

사용 옵션·API

대상옵션·API설명
전송 데이터 암호화useEncrypt: true파일 데이터 암호화 전송
메타데이터 암호화useEncryptMeta: true파일명 등 메타데이터 암호화
서명 URL 사용isPresignedUrl: true서명된 URL 방식
요청 차단(서버)uploader.showCustomError(code, msg, detail, bool)조건부 만료·거부
다운로드 없음(서버)InnorixCustomError.set(code, msg, detail, bool)404 등 커스텀 오류

예시

클라이언트 — 암호화 전송:

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    useEncrypt: true,
    useEncryptMeta: true
  });
</script>

서버 — 조건에 따라 업로드 거부(만료 처리 예):

jsp
<%
if (uploader.getParameter("_action").equals("attachFileCompleted")
        && !isAuthorized(session)) {
    uploader.showCustomError("1500", "expired", "권한이 만료되었습니다.", false);
    return;
}
%>

서버 — 다운로드 대상이 없을 때:

jsp
<%
if (!file.exists()) {
    response.setStatus(404);
    InnorixCustomError customError = new InnorixCustomError(response);
    customError.set("1016", "not Found", "file don't exist", false);
    customError.run();
    return;
}
%>

CORS 자격 증명 헤더(업로드·다운로드 공통):

jsp
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");

처리 순서

  1. 전송 보안이 필요하면 useEncrypt·useEncryptMeta로 암호화 전송
  2. 서버가 세션·권한을 확인하고, 만료·거부 조건에서 커스텀 오류 반환
  3. CORS 자격 증명 헤더로 교차 출처에서도 세션 기반 접근 유지

웹페이지 적용

실제 페이지에 컨트롤을 붙이는 전체 과정을 다룹니다. 리소스 포함과 컨트롤 생성(코드 생성), 업로드·다운로드 서버 연결, 그리고 뷰·버튼 등 UI 구성으로 나뉩니다.

코드 생성

설명

exabyter.create(options)가 컨트롤 생성의 진입점입니다. 렌더 대상 요소(setElementID)와 서버 엔드포인트, 전송 정책을 옵션으로 넘기면 control 인스턴스가 반환됩니다.

주요 생성 옵션

옵션설명
setElementID컨트롤을 렌더할 요소 선택자 (예: '#fileControl')
setViewType뷰 형태 (예: 'ListView')
transferMode"both" · "upload" · "download"
setUploadURL업로드 수신 엔드포인트
monitorURL전송 모니터 엔드포인트(선택)
controlLang컨트롤 UI 언어 (예: 'en', 'ko')
charset문자셋 (기본 "UTF-8")

최소 구성 예시

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" type="text/css" href="/exabyter/exabyter.css">
  <script src="/exabyter/exabyter.js"></script>
</head>
<body>
  <div id="fileControl"></div>
  <script>
    var control = exabyter.create({
      setElementID: '#fileControl',
      setViewType: 'ListView',
      transferMode: 'both',
      setUploadURL: '/exabyter/example/upload.jsp',
      monitorURL: '/exabyter/example/transferInfo.jsp',
      controlLang: 'en'
    });
  </script>
</body>
</html>

처리 순서

  1. exabyter.css · exabyter.js 포함
  2. 렌더 대상 컨테이너 요소 배치
  3. exabyter.create(options) 호출 → control 확보

업로드 연결

설명

컨트롤의 업로드 요청을 받아 슬라이스를 저장하는 서버 엔드포인트를 setUploadURL로 연결합니다. 서버는 ExabyterUpload로 요청을 처리하며, 요청은 _action 플래그로 단계가 구분됩니다.

업로드 요청 _action 플래그

단계
speedCheck전송 속도 측정
getServerInfo서버 정보 확인
getFileInfo파일 정보 확인
attachFile파일(슬라이스) 전송 진행
attachFileCompleted파일 전송 완료

주요 요청 파라미터: _orig_filename(원본 파일명), _new_filename(저장 파일명), _filesize, _start_offset · _end_offset(슬라이스 구간), _filepath, _transferId.

클라이언트 연결

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    transferMode: 'upload',
    setUploadURL: '/exabyter/example/upload.jsp'   // ← 업로드 서버 연결
  });
</script>

서버 (upload.jsp)

jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="com.innorix.transfer.ExabyterUpload" %>
<%
// CORS 프리플라이트(OPTIONS)가 오므로 POST일 때만 처리
if (request.getMethod().equals("POST")) {
    String directory   = "/storage/exabyter";
    int    maxPostSize  = 2147482624;
    ExabyterUpload uploader = new ExabyterUpload(request, response, maxPostSize, directory);

    String action = uploader.getParameter("_action");   // 단계 플래그
    uploader.run();                                      // 슬라이스 저장 처리

    if ("attachFileCompleted".equals(action)) {
        uploader.setCustomValue("_fileSize", uploader.getParameter("_filesize"));
    }
    uploader = null;
}

// CORS 헤더
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
response.setHeader("Access-Control-Allow-Headers",
    "Authorization,DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, html5");
%>

처리 순서

  1. 클라이언트 setUploadURL을 서버 스크립트 경로로 지정
  2. 컨트롤이 파일을 슬라이스로 나눠 attachFile 요청을 반복 전송
  3. 서버 uploader.run()이 슬라이스를 저장 경로에 기록, attachFileCompleted로 마무리
  4. OPTIONS 프리플라이트 대응을 위해 CORS 헤더 반환

다운로드 연결

설명

다운로드 대상은 setDownloadList()로 지정하고, 각 항목의 downloadURL이 서버 스트림 엔드포인트를 가리킵니다. 서버는 요청 구간(_StartOffset · _EndOffset)만큼을 스트리밍합니다.

다운로드 스트림 요청 파라미터

파라미터설명
fileName다운로드 파일명
_StartOffset · _EndOffset슬라이스 구간(범위 요청)
_IsSliceTransfer슬라이스 전송 여부
_OrigStartOffset원본 슬라이스 시작 오프셋
_Integrity무결성(MD5) 요청 여부
_ActionDownloadStart · DownloadComplete 단계 신호

클라이언트 연결

html
<script>
  control.setDownloadList([
    {
      downloadURL: '/exabyter/example/download.jsp?fileName=500MB.dat',
      displayFileName: '500MB.dat',
      fileSize: 524288000,
      isFolder: false
    }
  ]);
  control.download();
</script>

서버 (download.jsp, 요지)

jsp
<%@ page contentType="application/octet-stream" trimDirectiveWhitespaces="true" %>
<%@ page import="com.innorix.transfer.InnorixCustomError" %>
<%@ page import="java.io.*" %>
<%@ page import="java.net.URLEncoder" %>
<%
// 바이너리 스트림이 JSP 템플릿 공백으로 오염되지 않도록 버퍼를 비운다.
out.clear();
out = pageContext.pushBody();

String storageRoot = "/storage/exabyter/";            // 스토리지 루트 (실제 경로로 교체)
String fileName    = request.getParameter("fileName");
// 필요 시 fileName 경로 이탈(../) 검증을 추가한다.
File   file        = new File(storageRoot, fileName);

if (!file.exists()) {
    response.setStatus(404);
    InnorixCustomError customError = new InnorixCustomError(response);
    customError.set("1016", "not Found", "file don't exist", false);
    customError.run();
    return;
}

long fileLength  = file.length();
long startOffset = request.getParameter("_StartOffset") == null
        ? 0 : Long.parseLong(request.getParameter("_StartOffset"));
long endOffset   = request.getParameter("_EndOffset") == null
        ? fileLength - 1 : Long.parseLong(request.getParameter("_EndOffset"));
long contentLength = endOffset - startOffset + 1;

// 한글 등 비ASCII 파일명 대응
String encodedName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");

response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedName);
response.setHeader("Content-Length", String.valueOf(contentLength));
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");

RandomAccessFile raf = null;
OutputStream os = null;
try {
    raf = new RandomAccessFile(file, "r");
    raf.seek(startOffset);                            // 요청 구간으로 정확히 이동
    os  = response.getOutputStream();
    byte[] buf = new byte[8192];
    while (contentLength > 0) {
        int read = raf.read(buf, 0, (int) Math.min(buf.length, contentLength));
        if (read == -1) break;
        os.write(buf, 0, read);
        contentLength -= read;
    }
    os.flush();
} finally {
    if (raf != null) raf.close();
    if (os != null)  os.close();
}
%>

처리 순서

  1. setDownloadList([...])로 대상과 downloadURL 지정
  2. control.download() 호출 → 컨트롤이 구간별(_StartOffset·_EndOffset) 병렬 요청
  3. 서버가 Accept-Ranges·Content-Length로 해당 구간만 스트리밍
  4. 없는 파일은 404 + 커스텀 오류로 응답

UI 설정

설명

컨트롤의 뷰·버튼·부가 UI를 옵션으로 구성합니다. 드롭존, 전송 창, QR 코드, 진행 그래프 등을 켜고 끌 수 있으며, 전송 시작·첨부 버튼은 페이지에서 컨트롤 메서드로 연결합니다.

사용 옵션

옵션설명
setViewType"ListView"목록 뷰 형태
enableDropZoneboolean드래그 앤 드롭 영역
showTransferWindowboolean전송 진행 창 표시
showGraph / useSmoothGraphboolean진행 그래프 표시
showQrCodeboolean모바일 연동 QR 표시
showTransferStatusIconboolean상태 아이콘 표시
hideClientPathboolean클라이언트 경로 숨김
transferWindowTitlestring전송 창 제목
boxWidth · boxHeightnumber컨트롤 크기

예시

html
<div id="fileControl"></div>

<div style="margin-top: 20px;">
  <button onclick="control.openFileDialog()">파일 선택</button>
  <button onclick="control.directoryDialog()">폴더 선택</button>
  <button onclick="control.upload()">업로드</button>
  <button onclick="control.download()">다운로드</button>
</div>

<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setViewType: 'ListView',
    transferMode: 'both',
    setUploadURL: '/exabyter/example/upload.jsp',
    enableDropZone: true,
    showTransferWindow: true,
    showQrCode: true,
    hideClientPath: true,
    transferWindowTitle: 'Exabyter'
  });
</script>

처리 순서

  1. setViewType과 표시 옵션으로 컨트롤 외형 구성
  2. 페이지 버튼에 openFileDialog() · directoryDialog() · upload() · download() 연결
  3. 필요 시 boxWidth·boxHeight로 크기, transferWindowTitle로 창 제목 조정

상태와 결과

전송 진행 상태를 표시하고, 완료·실패 결과를 콜백으로 받아 후속 처리하는 방법을 다룹니다. 컨트롤은 진행 UI를 자체 렌더하며, 주요 시점은 이벤트 콜백으로 통지합니다.

진행 상태

설명

전송 중 진행률·속도는 컨트롤의 전송 창과 그래프로 표시됩니다. 표시 요소는 옵션으로 켜고 끌 수 있으며, 컨트롤 준비 완료 시점은 notifyReadyEvent로 확인합니다.

사용 옵션·콜백

옵션·콜백설명
showTransferWindow진행 창 표시
showGraph / alwaysShowTransferGraph진행 그래프 표시
useSmoothGraph그래프 부드럽게 표시
showTransferStatusIcon상태 아이콘 표시
notifyReadyEvent컨트롤 초기화 완료 콜백

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    showTransferWindow: true,
    showGraph: true,
    useSmoothGraph: true,
    notifyReadyEvent: function () {
      // 컨트롤 준비 완료 — 버튼 활성화 등
      console.log('control ready');
    }
  });
</script>

처리 순서

  1. 진행 표시 옵션(showTransferWindow·showGraph 등)으로 UI 구성
  2. notifyReadyEvent에서 준비 완료 확인 후 조작 허용
  3. 전송 중 컨트롤이 진행률·속도를 자동 갱신

완료 결과

설명

업로드·다운로드가 끝나면 각각 uploadCompletedEvent · downloadCompletedEvent 콜백이 호출됩니다. 콜백 인자로 전달되는 결과로 완료 파일·전송 식별자를 확인하고 후속 로직(저장 기록, 화면 갱신 등)을 실행합니다.

완료 콜백

콜백시점
uploadCompletedEvent업로드 전체 완료
downloadCompletedEvent다운로드 전체 완료

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    uploadCompletedEvent: function (result) {
      // 업로드 완료 후 처리 (예: 서버에 메타 등록, 목록 갱신)
      console.log('upload completed', result);
    },
    downloadCompletedEvent: function (result) {
      console.log('download completed', result);
    }
  });
</script>

서버는 완료 단계에서 커스텀 값을 실어 결과에 포함할 수 있습니다.

jsp
<%
if ("attachFileCompleted".equals(uploader.getParameter("_action"))) {
    uploader.setCustomValue("_fileSize", uploader.getParameter("_filesize"));
}
%>

처리 순서

  1. 생성 옵션에 uploadCompletedEvent · downloadCompletedEvent 등록
  2. 전송 완료 시 콜백 인자로 결과 수신
  3. 서버가 setCustomValue로 넘긴 값을 포함해 후속 처리

결과 이벤트

설명

컨트롤은 전송 수명 주기 동안 시작·진행·완료·취소·오류 이벤트를 발생시킵니다. 위 완료 콜백 외에도 각 방향의 시작·진행·취소·오류 시점을 다룰 수 있습니다.

이벤트 목록

방향시작진행완료취소오류
업로드uploadStartuploadProgressuploadCompleteuploadCanceluploadError
다운로드downloadStartdownloadProgressdownloadCompletedownloadCanceldownloadError
전송(공통)transferCompletetransferCanceltransferError

주요 완료·준비 시점은 생성 옵션의 콜백(uploadCompletedEvent · downloadCompletedEvent · notifyReadyEvent)으로 직접 연결합니다.

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    notifyReadyEvent: function () { /* 준비 완료 */ },
    uploadCompletedEvent: function (result) { /* 업로드 완료 */ },
    downloadCompletedEvent: function (result) { /* 다운로드 완료 */ }
  });
</script>

처리 순서

  1. 준비·완료 시점은 생성 옵션 콜백으로 연결
  2. 시작·진행·취소 시점이 필요하면 해당 방향 이벤트를 함께 처리
  3. 이벤트 인자로 받은 결과로 화면·기록 갱신

오류 처리

설명

전송 실패는 업로드·다운로드 오류 이벤트로 통지되며, 서버는 커스텀 오류 코드로 실패 원인을 내려보냅니다. 컨트롤은 재시도·자동 복구 정책에 따라 일시적 오류를 스스로 회복합니다.

사용 옵션·API

대상옵션·API설명
업로드 오류 이벤트uploadError업로드 실패 통지
다운로드 오류 이벤트downloadError다운로드 실패 통지
재시도 횟수retryCount (기본 5)실패 시 재시도 횟수
재시도 간격retryDelay (기본 3초)재시도 대기 시간
최대 오류 허용maxErrorCount초과 시 전송 중단
서버 커스텀 오류showCustomError(code, msg, detail, bool) · InnorixCustomError.set(...)실패 코드 전달

예시

서버 — 업로드 조건부 오류:

jsp
<%
if (invalidRequest) {
    uploader.showCustomError("1003", "invalid request", "요청이 올바르지 않습니다.", false);
    return;
}
%>

서버 — 다운로드 파일 없음(404):

jsp
<%
if (!file.exists()) {
    response.setStatus(404);
    InnorixCustomError customError = new InnorixCustomError(response);
    customError.set("1016", "not Found", "file don't exist", false);
    customError.run();
    return;
}
%>

클라이언트 — 재시도 정책:

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    retryCount: 5,
    retryDelay: 3,
    maxErrorCount: 9999
  });
</script>

처리 순서

  1. retryCount · retryDelay로 일시적 오류의 자동 재시도 정책 설정
  2. 서버가 실패 조건에서 커스텀 오류 코드를 반환
  3. 재시도로도 회복되지 않으면 오류 이벤트로 통지, maxErrorCount 초과 시 중단

대용량 전송

수 GB~수십 GB 파일을 안정적으로 전송하기 위한 슬라이스 분할·병렬 세션, 중단 지점 복구, 자동 재시도, 무결성 검증을 다룹니다. 이 기능들은 대부분 옵션으로 켜고 값을 조정합니다.

대용량 전송

설명

컨트롤은 파일을 슬라이스(청크) 단위로 분할해 여러 세션으로 병렬 전송하고, 고속 모드로 처리량을 높입니다. 슬라이스 크기·세션 수를 조정해 네트워크 환경에 맞게 튜닝합니다.

사용 옵션

옵션기본설명
sliceSize2097152 (2 MB)슬라이스 크기(바이트)
uploadSliceSize · downloadSliceSize0(=sliceSize)방향별 슬라이스 크기
sessionCount15병렬 세션 수
uploadSessionCount · downloadSessionCount0(=sessionCount)방향별 세션 수
highSpeedMode / isHighSpeedtrue고속 전송
largeAcceleratorfalse대용량 가속

서버는 업로드 요청 본문 크기를 maxPostSize로 허용해야 합니다.

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    isHighSpeed: true,
    sliceSize: 2097152,          // 2 MB 슬라이스
    uploadSessionCount: 16,      // 병렬 세션 16개
    downloadSessionCount: 16
  });
</script>

처리 순서

  1. 파일을 sliceSize 단위 슬라이스로 분할
  2. sessionCount(방향별 세션 수)만큼 병렬로 슬라이스 전송
  3. 고속 모드·가속 옵션으로 처리량 최적화, 서버 maxPostSize로 요청 크기 수용

중단 복구

설명

네트워크 단절이나 창 종료로 전송이 끊겨도, 이미 저장된 슬라이스 이후 지점부터 이어받습니다. 업로드는 슬라이스 오프셋(_start_offset) 기준으로 재개하고, 다운로드는 범위 요청(Accept-Ranges)으로 남은 구간을 이어받습니다. 중복 처리 정책으로 이어받기·덮어쓰기 등을 지정합니다.

사용 옵션

옵션설명
resumeTypeoverwrite · relay · nosend · numbering · confirm업로드 재개 방식
uploadDuplicateboolean / 정책업로드 중복 처리
downloadDuplicateresume다운로드 중복·이어받기 처리
resumeConditionboolean재개 조건 사용
attachIncompleteFilesboolean미완료 파일 재첨부
autoRecoveryboolean자동 복구
enableAutoReattachboolean자동 재첨부(재연결)

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    resumeType: 'relay',           // 저장된 지점부터 이어받기
    downloadDuplicate: 'resume',
    autoRecovery: true,
    attachIncompleteFiles: true,
    enableAutoReattach: true
  });
</script>

다운로드 서버는 범위 요청을 지원해야 합니다(슬라이스 구간만 스트리밍).

jsp
<%
response.setHeader("Accept-Ranges", "bytes");
long contentLength = endOffset - startOffset + 1;   // 남은 구간
response.setHeader("Content-Length", String.valueOf(contentLength));
if (startOffset != 0) in.skip(startOffset);          // 저장된 지점 이후부터
%>

처리 순서

  1. 전송 중 슬라이스별 완료 지점을 추적
  2. 중단 후 재개 시 마지막 완료 슬라이스 이후부터 전송(_start_offset / 범위 요청)
  3. resumeType · downloadDuplicate 정책으로 이어받기·덮어쓰기 결정

자동 재시도

설명

일시적 네트워크 오류가 발생한 슬라이스는 설정한 횟수·간격으로 자동 재시도합니다. 재시도로 회복되면 전송이 계속되고, 허용 오류 수를 넘으면 전송을 중단합니다.

사용 옵션

옵션기본설명
retryCount5슬라이스 실패 시 재시도 횟수
retryDelay3재시도 간격(초)
maxErrorCount9999누적 허용 오류 수
autoRecoverytrue자동 복구 사용
timeout.minSeconds60최소 소켓 타임아웃(초)
timeout.bytes / timeout.seconds0바이트당 타임아웃 계산

예시

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    retryCount: 5,
    retryDelay: 3,
    maxErrorCount: 9999,
    autoRecovery: true,
    timeout: { minSeconds: 60, bytes: 0, seconds: 0 }
  });
</script>

처리 순서

  1. 슬라이스 전송 실패 시 retryDelay 간격으로 retryCount만큼 재시도
  2. 재시도 성공 시 전송 계속, timeout 기준으로 응답 지연 감지
  3. 누적 오류가 maxErrorCount를 넘으면 전송 중단·오류 통지

무결성 검증

설명

전송 후 파일이 손상 없이 도착했는지 슬라이스 단위 해시로 검증합니다. 다운로드 무결성이 켜지면 컨트롤이 구간별 MD5를 서버에 요청하고, 서버는 해당 슬라이스의 MD5를 반환해 대조합니다.

사용 옵션·API

대상옵션·API설명
다운로드 무결성downloadIntegrity: true다운로드 무결성 검증 사용
검증 모드setVerification'disable' 등 검증 모드
무결성 요청(서버 파라미터)_Integrity=trueMD5 요청 신호
슬라이스 MD5(서버)Integrity.getMD5FromFileSlice(path, start, end)구간 MD5 계산

예시

클라이언트 — 무결성 검증 사용:

html
<script>
  var control = exabyter.create({
    setElementID: '#fileControl',
    setUploadURL: '/exabyter/example/upload.jsp',
    downloadIntegrity: true,
    setVerification: 'enable'
  });
</script>

서버 — 무결성 요청 시 슬라이스 MD5 반환:

jsp
<%@ page import="com.innorix.integrity.Integrity" %>
<%
if ("true".equalsIgnoreCase(request.getParameter("_Integrity"))) {
    long start = Long.parseLong(request.getParameter("_StartOffset"));
    long end   = Long.parseLong(request.getParameter("_EndOffset"));

    Integrity integrity = new Integrity();
    String md5 = integrity.getMD5FromFileSlice(filePath + fileName, start, end);

    response.setStatus(200);
    response.getWriter().write(md5);
    response.getWriter().flush();
    response.getWriter().close();
    return;
}
%>

처리 순서

  1. downloadIntegrity · setVerification으로 검증 사용
  2. 컨트롤이 구간별 _Integrity=true 요청으로 서버 MD5 조회
  3. 서버가 getMD5FromFileSlice로 계산한 MD5와 수신 슬라이스를 대조해 손상 여부 판정