Struts2とアップロード
Struts2は標準でファイルアップロードの機能が使えます。特に設定アイルを編集することがなく、その受け口となるActionクラスに受け取り用のフィールドを用意するだけです。
なお、公式のサンプルコードでは単一のファイルアップロード方法は記載していますが、複数のファイルアップロードにも対応しています。
アップロードに必要なこと
Struts2でファイルアップロードを実装するためには次の手順で行います。
- 送信フォームをマルチパートにするか、HTML5のFileAPIを利用する
- 受け取りActionにアップロードファイルのフィールドを設定する
あと、アップロードしたファイルを保存する仕組みは、各自で実装します。
Struts2のアップロード機能は、アップロードしたファイルを中間ファイルのFileオブジェクトに格納するところまで担います。
フォーム
送信フォームでは、通常のHTMLでも構いません(=strutsタグは必須ではありません)
たとえばHTML5のFileAPIとjQueryを利用した場合は以下のようになります。
<script>
$(function() {
if (!window.FileReader) {
alert("File APIがサポートされていません。");
return false;
}
// アップロードのdiv要素
var filedrop = $("#filedrop");
// デフォルトイベントのキャンセルを関数化
var eventCancel = function(event) {
event.preventDefault();
event.stopPropagation();
return false;
}
// ドロップイベントを関数化
var dropfileHandler = function(event) {
event.preventDefault();
var files = event.originalEvent.dataTransfer.files;
uploadFiles(files);
};
// イベントを関連付け
filedrop.bind("dragenter" , eventCancel);
filedrop.bind("dragover" , eventCancel);
filedrop.bind("drop" , dropfileHandler);
});
var uploadFiles = function(files) {
var formData = new FormData();
var filesLength = files.length;
for ( i=0; i<filesLength; i++ ) {
formData.append("uploadfile" , files[i]);
};
uploadProgress();
$.ajax({
url: 'upload' ,
type: 'POST' ,
data: formData ,
processData: false ,
contentType: false ,
success: function(data) {
// アップロード成功
} ,
failure : function(data) {
// アップロード失敗
}
});
};
</script>
<form id="filedropform" method="POST">
<div id="filedrop" class="filedrop">
<p>アップロードするjpegまたはpngファイルをドロップしてください</p>
</div>
</form>
ファイルを<div id="filedrop">
にドラッグ&ドロップすると、ファイルアップロードを行います。
Action
先ほどのjQuery.ajaxで送信した内容を受け取るActionクラスでは、アップロードしたファイルを受け取るためのフィールドを追加します。
フィールド追加のルールとして、アップロード時のパラメータ名がフィールド名になります。
先ほどの例では、formData.append("uploadfile" , files[i]);
で指定していますので、フィールド名は uploadfileになります。
なお、アップロードしたファイルについては、次の情報も取得できます。
内容 | フィールド名 | フィールド名の例 |
---|---|---|
アップロードしたファイルのFileオブジェクト | アップロード時のパラメータ | uploadfile |
ファイル名 | アップロード時のパラメータ+FileName | uploadfileFileName |
ファイルのコンテンツタイプ | アップロード時のパラメータ+ContentType | uploadfileContentType |
以下は実装例です。
@Namespace("/")
@Results({
@Result(name = ActionSupport.SUCCESS, type="json" , params={"root","result"}),
})
@Controller
@Scope("prototype")
@Log4j2
public class UploadAction extends ActionSupport {
/**
* デフォルトアクション。
*/
@Action("upload")
public String start() throws Exception {
// アップロードしたファイルの保管などをここに。。
return SUCCESS;
}
/**
* アップロードファイルのFileオブジェクト
*/
@Getter @Setter
private File[] uploadfile;
/**
* アップロードしたファイルのコンテンツタイプ
*/
@Getter @Setter
private String[] uploadfileContentType;
/**
* アップロードしたファイルの元ファイル名
*/
@Getter @Setter
private String[] uploadfileFileName;
/**
* Ajaxレスポンスの文字列
*/
@Getter @Setter
private Map<String, Object> result;
}
ファイルアップロード用に追加したフィールドは、配列が指定できます。
…そう、複数のファイルアップロードもこれだけで可能です。例えば2つのファイルをドラッグ&ドロップで選択した場合は、配列の長さは自動的に2としてくれます。
サンプルコード
SpringとMybatisを使ってアップロードしたファイルを保存するサンプルをgithubに公開しております。