SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

dataforms.jar API解説――ファイルのアップロード・ダウンロードの実装

  • このエントリーをはてなブックマークに追加

 前回の記事では単純なフォームに入力した情報をサーバーに送信する手順を解説しました。今回はファイルのアップロード・ダウンロードの実装やフォームクラス以外のJavaScriptとJavaの連携を解説していきます。

  • このエントリーをはてなブックマークに追加

対象読者

 この記事を読むのに必要な知識を以下にまとめます。

  • Java
  • JavaScript
  • jQuery、jQuery-ui
  • HTML、CSS

必要な環境

 dataforms.jarを使用した開発では、以下を使用しています。

  • JDK1.8
  • Eclipse 4.5以上
  • Tomcat 7以上

ファイルのアップロード

 前回の記事で使用したプロジェクトに新たなページ(FileUploadPage)を作成します。以下のFileUploadForm.java以外のソースは開発ツールを使用してひな形を作成し、太字の部分を追加コーディングしたものです。作成の手順は前回の記事を参照してください。

FileUploadPage.java
package pagesample.page;

import dataforms.app.page.base.BasePage;
import dataforms.dao.Dao;
import dataforms.dao.Table;


/**
 * ページクラス。
 */
public class FileUploadPage extends BasePage {
  /**
   * コンストラクタ。
   */
  public FileUploadPage() {
    this.addForm(new FileUploadForm());
  }

  /**
   * Pageが配置されるパスを返します。
   *
   * @return Pageが配置されるパス。
   */
  public String getFunctionPath() {
    return "/pagesample";
  }

  /**
   * 操作対象テーブルクラスを取得します。
   * <pre>
   * ページjavaクラス作成用のメソッドです。
   * </pre>
   * @return 操作対象テーブル。
   */
  public Class<? extends  Table> getTableClass() {
    return Table.class;
  }

  /**
   * テーブルを操作するためのDaoクラスを取得します。
   * <pre>
   * ページjavaクラス作成用のメソッドです。
   * </pre>
   * @return Daoクラス。
   */
  public Class<? extends Dao> getDaoClass() {
    return Dao.class;
  }
}
    
FileUploadForm.java
package pagesample.page;

import java.io.File;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import dataforms.annotation.WebMethod;
import dataforms.controller.Form;
import dataforms.controller.JsonResponse;
import dataforms.controller.Response;
import dataforms.dao.file.FileObject;
import dataforms.field.base.TextField;
import dataforms.field.common.FolderStoreFileField;
import dataforms.validator.RequiredValidator;
import dataforms.validator.ValidationError;

/**
 * ファイルアップロードフォーム。
 *
 */
public class FileUploadForm extends Form {
  /**
   * コンストラクタ。
   */
  public FileUploadForm() {
    super(null);
    this.addField(new TextField("text1")).setComment("テキスト");
    this.addField(new FolderStoreFileField("file1")).addValidator(new RequiredValidator());
  }
  
  /**
   * Logger.
   */
  private Logger logger = Logger.getLogger(FileUploadForm.class);
  

  /**
   * アップロードメソッド。
   * @param p POSTされた情報。
   * @return 応答情報。
   * @throws Exception 例外。
   */
  @WebMethod
  public Response upload(final Map<String, Object> p) throws Exception {
    this.methodStartLog(logger, p);
    Response result = null;
    List<ValidationError> list = this.validate(p);
    if (list.size() > 0) {
      result = new JsonResponse(JsonResponse.INVALID, list);
    } else {
      Map<String, Object> d = this.convertToServerData(p);
      String text1 = (String) d.get("text1");
      FileObject file1 = (FileObject) d.get("file1");
      File f = file1.getTempFile();
      logger.debug("text1=" + text1 + "file=" + f.getAbsolutePath());
      result = new JsonResponse(JsonResponse.SUCCESS, "");
    }
    this.methodFinishLog(logger, result);
    return result;
  }
}
    
FileUploadPage.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title></title>
  </head>
  <body>
    <div id="mainDiv">
      <form id="fileUploadForm">
        <div class="formHeader">xxx</div>
        <table class="responsive">
          <tbody>
            <tr>
              <th>テキスト</th>
              <td><input type="text" id="text1" /></td>
            </tr>
            <tr>
              <th>file1</th>
              <td><input type="file" id="file1"/></td>
            </tr>
          </tbody>
        </table>
        <button id="uploadButton" type="button">アップロード</button>
      </form>
    </div>
  </body>
</html>    
    
FileUploadForm.js
/**
 * @fileOverview {@link FileUploadForm}クラスを記述したファイルです。
 */

/**
 * @class FileUploadForm
 *
 * @extends Form
 */
FileUploadForm = createSubclass("FileUploadForm", {}, "Form");


/**
 * HTMLエレメントとの対応付けを行います。
 */
FileUploadForm.prototype.attach = function() {
  Form.prototype.attach.call(this);
  var thisForm = this;
  this.find("#uploadButton").click(function() {
    thisForm.upload();
  });
};

/**
 * アップロードボタンの処理。
 */
FileUploadForm.prototype.upload = function() {
  // エラー情報をクリアする。
  currentPage.resetErrorStatus();
  if (this.validate()) {
    var thisForm = this;
    this.submit("upload", function(r) {
      if (r.status == ServerMethod.INVALID) {
        // サーバーのバリデーション結果を表示する。
        currentPage.setErrorInfo(thisForm.getValidationResult(r), thisForm);
      } else if (r.status == ServerMethod.SUCCESS) {
        // TODO:成功時の処理を実装。
        logger.log("json=" + JSON.stringify(r));
      }
    });
  }  
};
    
    

 今回使用したFolderStoreFileFieldクラスは、アップロードしたファイルをサーバー中のフォルダーに保存し、そのパスをデータベースのフィールドに記録するためのフィールドです。このページから「IMG_7021.JPG」というファイルをアップロードすると、サーバーのログは以下の通りになります。

FileUploadForm.js
2018-02-26 17:29:15,110  INFO DataFormsServlet - context=/pagesample, uri=/pagesample/pagesample/page/FileUploadPage.df
2018-02-26 17:29:15,110  INFO DataFormsServlet - classname=pagesample.page.FileUploadPage
2018-02-26 17:29:15,180  INFO DataFormsServlet - method=fileUploadForm.upload
2018-02-26 17:29:15,180 DEBUG Page - csrfToken=Vz2uGN96hkJrM6sbDojL0ZwsyXGrXB2WpGQvCaXQIBYIuXUA8pntnQ==
2018-02-26 17:29:15,181  INFO FileUploadForm - pagesample.page.FileUploadForm.upload start param={csrfToken=Vz2uGN96hkJrM6sbDojL0ZwsyXGrXB2WpGQvCaXQIBYIuXUA8pntnQ%3D%3D, text1=入力したテキスト, file1_fn=, file1=name=IMG_7021.JPG, StoreLocation=\tmp\upload__42259447_161d13aec07__8000_00000001.tmp, size=1599499bytes, isFormField=false, FieldName=file1}
2018-02-26 17:29:15,189 DEBUG FileObject - fileName=IMG_7021.JPG,fnPattern=(?i).*\.jpg$,contentType=image/jpeg
2018-02-26 17:29:15,189 DEBUG FileUploadForm - text1=入力したテキストfile=D:\uploadData\null\file1\-1\20180226172915181_IMG_7021.JPG
2018-02-26 17:29:15,190  INFO FileUploadForm - pagesample.page.FileUploadForm.upload finish result=dataforms.controller.JsonResponse@3bd8501a
2018-02-26 17:29:15,190 DEBUG JsonResponse - json={
  "contentType": "text/plain; charset=utf-8",
  "result": "",
  "status": 0
}
    

 FolderStoreFileFieldに対応したデータはFileObject型のデータとなっており、そのgetTempFile()メソッドでサーバーにアップロードされたファイルのパスを取得することができます。このログからアップロードされたファイルは、「D:\uploadData\null\file1\-1\20180226172915181_IMG_7021.JPG」というファイルに保存されていることがわかります。FolderStoreFileFieldに指定されたファイルは、サーバーの以下のパスに保存されます。

FolderStoreFileFieldのファイル保存パス
[web.xmlのupload-data-folderに設定されたパス]/[テーブル名]/[フィールドID]/[ユーザID]/[アップロード日時]_[ファイル名]
    

 今回は、テーブルに配置したフィールドではないためテーブル名がnullとなっており、ログインせずにファイルをアップロードしたためユーザIDが-1となっています。FolderStoreFileFieldをテーブルに配置すると、そのテーブルに対するinsert/updateの実行でこのパスがテーブルに登録されます。

 通常ファイルをアップロードするフォームには「enctype="multipart/form-data"」等の設定が必要になります。しかし今回作成したhtmlにはこの記述がありません。これでなぜファイルがサーバーにアップロードされるかというと、フォームのsubmitメソッドがフォーム中にファイルフィールドが存在した場合、自動的に「enctype="multipart/form-data"」を設定してからPOSTしているからです。さらにサーバーサイドではcommons-fileuploadを使用してサーバー中にファイルを展開し、その情報をFileObjectに設定します。このように、dataforms.jarはファイル送信の特殊な作法を意識する必要が無い構造をしています。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
ファイルのダウンロード

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

高柳 正彦(タカヤナギ マサヒコ)

経験年数30年を超えた、システムエンジニアです。一応管理職のはずですが、未だにコードを書いています。この仕事を長々とやっていると、それなりにノウハウがたまってきます。そのノウハウをまとめたものができないかと思い、独自のフレームワークを作り始めました。そのフレームワークもそれなりに使えるようになってき...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10708 2018/04/16 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング