www.dextsolution.com
DEXTUPLOAD
X5
menu toggle製品の説明 > 大容量ファイルのアップロード

大容量ファイルのアップロード

DEXTUpload製品群では2GB以上のファイルをアップロードすることを "大容量ファイルアップロード "と呼んでいます。DEXTUploadX5はDEXTUploadNJ(Java環境ベース)のような弊社のサーバーコンポーネント製品と連携して大容量ファイルアップロードを処理する機能を提供します。 (大容量ファイルアップロードは弊社コンポーネントとの連携でのみ可能であり、DEXTUploadX5単独ではサポートされていません)。

大容量ファイルアップロードは通常のファイルアップロードとは異なる方法で処理されます。通常のファイルアップロードは1回のリクエストで10ファイルすべてを送信することができますが、大容量ファイルアップロードは状況によって少なくとも20回、時には数千回のリクエストをサーバーに送信することができます。DEXTUploadX5の大容量ファイルアップロード機能はネイティブで連結をサポートするため、製品は事前にサーバーコンポーネントと通信し、ファイルを分割して送信するため、リクエスト数は分割(チャンク)の大きさに応じて増加します。例えば、2.5GBのファイルを10個アップロードし、約10MBずつチャンクに分けて転送する場合、約2500回のリクエストが予想されます。しかし、DEXTUploadNJのようなサーバーコンポーネントはチャンクを1つのファイルにまとめるので、開発者は合計で約10回ファイルを宛先に保存(転送)するだけです。

DEXTUploadX5一括アップロードの設定方法

大容量アップロードサービスを実施するためには、クライアントとサーバーコンポーネントの両方が大容量アップロードのために設定されなければならない。

以下はDEXTUploadX5の設定例である。

// onDX5Createdイベント関数でラージアップロードを設定します。
function onDX5Created(id) {
    var dx = dx5.get(id);

    // アップロードパスを設定します。
    dx.setUploadURL("http://domain/path/extension-upload.do");

    // アップロードモードを一括に設定する。
    dx.setUploadMode("EXTS");

    // ファイルを分割するブロックサイズをバイト単位で設定する。
    dx.setUploadBlockSize(10 * 1024 * 1024);
}
DEXTUploadNJサーバーコンポーネント製品を使用したサーバー側セットアップ

DEXTUploadNJはJava JSP/サーブレットベースでファイルアップロードを処理するサーバー専用コンポーネントです。DEXTUploadNJは、大容量アップロードのサーバーサイド処理のための機能を含み、当社のDEXTUploadX5クライアントスイートと連動します。

ExtensionFileUploadFilterクラスはjavax.servlet.Filterインターフェースの実装です。Filterクラスであるため、Javaサーブレットコンテナ(Tomcatサーバーのような)によって自動的にロードされ、コードレベルの作成や呼び出しなしで大きなファイルのアップロードを処理します。

DD(web.xml)でExtensionFileUploadFilterフィルタを設定する方法は次のとおりです。

<filter>
  <filter-name>extensionFilter</filter-name>
  <filter-class>devpia.dextuploadnj.support.common.ExtensionFileUploadFilter</filter-class>
  <!-- パラメータの設定を省略 -->
</filter>
<filter-mapping>
  <filter-name>extensionFilter</filter-name>
  <!-- 
  開発者コードレベルで最終的に大きなアップロードされたファイルを扱うためのサーブレットまたは URL マッピング
  <servlet-name>サーブレット名</servlet-name>
  <url-pattern>マッピングURL</url-pattern>
  -->
</filter-mapping>
DEXTUploadNJ(2.5.0以前)サーバーコンポーネント製品を利用したサーバーサイド処理(JSP/Servlet)

ExtensionFileUploadFilterフィルターを通してアップロード処理されるファイル情報は、開発者が記述する必要のあるサーブレットまたはJSPでHttpServletRequest#getAttributeメソッドを使用して得ることができます。

// フィルタの処理結果を含む MultipartCollection オブジェクトを取得するには、キーとして DEXTUPLOADNJ_EXTENSION_FILE_UPLOAD_RESULT を使用します。
MultipartCollection multiparts = (MultipartCollection)request.getAttribute(Definition.DEXTUPLOADNJ_EXTENSION_FILE_UPLOAD_RESULT);
try {
    FileItem item = multiparts.getFileItem(0);
    
    if (item.isEmpty()) {
        // ファイルが空の場合、通常は例外をスローする必要があります。
    }
    
    // 一時ファイルを実際の格納場所に保存(コピーまたは移動)します。
    // 引数としてディレクトリパスが与えられない場合、ExtensionFileUploadFilter の defaultRepository パラメータの値によって設定されたパスが対象となります。
    String path = item.save();
        
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/plain");
    // レスポンス・オブジェクトにはどんな値でも書き込めますが、キーやファイル名、あるいはファイル固有の値を表すパスを書き込むのが一般的です。
    response.getWriter().write(path);
} finally {
    if (multiparts != null) {
        // リソースを削除します。削除されていない一時ファイルはすべて削除されます。
        multiparts.deleteTempFiles();
        multiparts.clear();
    }
}
DEXTUploadNJ(2.5.0以降)サーバーコンポーネント製品を利用したサーバーサイド処理(JSP/Servlet)

バージョン2.5.0からは、煩雑な前段階を減らし、FileUploadクラスを使ってファイルアイテムを取得することができます。

FileUpload dextnj = null;
try {
    dextnj = new FileUpload(request);
    dextnj.prepare();

    FileItem item = dextnj.getFileItem();
    if (item.isEmpty()) {
        // ファイルが空の場合、通常は例外を発生させる必要があります。
    }
  
    String path = item.save();
  
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/plain");
    response.getWriter().write(path);
} finally {
    if (dextnj != null) dextnj.close();
}
DEXTUploadNJ(2.6.0以前)サーバーコンポーネント製品を用いたサーバーサイド処理(Spring Web Framework)

Spring環境では、DD(web.xml)にExtensionFileUploadFilterを設定するだけでなく、DispatcherServletオブジェクトの設定を担当するXMLファイルにMultipartResolverビーンを設定する必要がある。

# web.xml
<servlet>
  <servlet-name>defaultDispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
  </init-param>
</servlet>

DEXTUploadNJMultipartResolverビーンを宣言するために、dispatcher-servlet.xmlファイルを開いてください。

# dispatcher-servlet.xml
<bean id="multipartResolver" class="devpia.dextuploadnj.support.spring.DEXTUploadNJMultipartResolver"/>

CommonMultipartResolverまたはStandardServletMultipartResolver(Springが提供)を設定している場合は、それらを削除する必要があります。これらのBeanはDEXTUploadNJMultipartResolver Beanと同じタスクを実行するので、同時に設定するとエラーになる可能性があります。

ExtensionFileUploadFilter フィルタで処理された一時ファイル情報は、 コントローラにマッピングされたメソッドで MultipartFile オブジェクトとして受け取ることができます。

@RequestMapping(value = "/extension-upload.do", method = RequestMethod.POST)
public void upload(
    // これがDEXTUploadX5製品の場合、"DEXTUploadX5_FileData "として渡される。
    @RequestParam(value = "DEXTUploadX5_FileData") MultipartFile file, 
    HttpServletResponse response) throws IOException {
    
    // FileItem インターフェースにキャストします。
    FileItem item = (FileItem)file;	
    
    if (item.isEmpty()) {
        // ファイルが空の場合、通常は例外がスローされます。
        // DEXTUploadX5 のようなクライアントは、 // ファイルがない状態でサーバにリクエストを送信しないからです。
    }  
    
    String path = item.save();
    
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/plain");
    response.getWriter().write(path);
}
DEXTUploadNJ(2.6.0以降)サーバーコンポーネント製品によるサーバーサイド処理(Spring Web Framework)

バージョン2.6.0から、DEXTUploadNJはSpring環境で使用するための専用フィルターDEXTUploadNJSpringExtensionUploadFilterを提供します。このフィルターを使って、DEXTUploadNJMultipartResolverの設定を省略することができる。

# web.xml
<filter>
  <filter-name>extensionUploadFilter</filter-name>
  <filter-class>devpia.dextuploadnj.support.spring.DEXTUploadNJSpringExtensionUploadFilter</filter-class>
  <!-- パラメータの設定は省略 -->
</filter>

# dispatcher-servlet.xml
<!-- DEXTUploadNJMultipartResolverの設定は省略できます。 -->
サーバーから受信した応答データの処理

サーバー側の処理が完了すると、DEXTUploadX5は結果をレスポンスデータとして返します。このレスポンスデータはコンポーネントのgetResponses関数を使用して取得できます。サーバー上では、ファイルの数だけコードが呼び出されますが、onDX5UploadCompletedイベント関数は、アップロード完了イベントが1回しか発生しないため、1回しか呼び出されません。

// onDX5UploadCompleted関数は、アップロードが完了したとき(サーバー側のファイルアップロード処理が完了したとき)に呼び出されるイベント関数です。
function onDX5UploadCompleted(id) {
    var responses = dx5.get(id).getResponses();
    for (var i = 0, len = responses.length; i < len; i++) {
        console.log(responses[i]);
    }
}