2011年10月27日木曜日

Struts ファイルアップロード制限の方法

色々なサイトで紹介されていますが、Strutsでのファイルアップロードサイズ制限の方法を記載します。

結論から言えば、細かいvalidateの実装の仕方はともかくして、たとえば10KB以上のファイルをアップロードさせないためには、
struts-config.xmlに次の内容を<struts-config></struts-config>のなかに書いてやるだけ。

<controller maxFileSize="10K" />

ただ、最初はこの設定をすれば、こうできるよ、というように安易に受け取っていましたが、
よくよく調べてみると、所謂MVC(Model・view・controller)でのC(controller)にあたる、
コントローラでチェックしてね、ということらしいです。

そして、所謂だいたいのコントローラでチェックしたい要望を満たす為のオプションは既にStrutsが用意してくれてるよ、
と、そういうことらしいです。
つまりは、上記の設定内容は厳密に記載すると、以下のような書き方になる。

<controller
    maxFileSize="10K"
    className="org.apache.struts.config.ControllerConfig"
    multipartClass="org.apache.struts.upload.CommonsMultipartRequestHandler"
    processorClass="org.apache.struts.acrion.RequestProcessor" />

classNameはコントローラ設定情報を保持するクラス、multipartClassはMultipartRequestHandler、processorClassはprocessorClassを意味しており、省略するとそれぞれStrutsでは上記のクラスを利用することになっている。
要するに<controller>はその名の通りコントローラを定義する設定であり、「maxFileSize」は「className="org.apache.struts.config.ControllerConfig"」に設定しているだけであったりします。

【参考】
http://www.jajakarta.org/struts/struts1.1/documentation/ja/target/api/org/apache/struts/config/ControllerConfig.html

用途によってコントローラを独自のクラスに拡張したりできますが、
ここからはStrutsフレームワークと銘打っている以上はここからはStrutsでのファイルアップロードサイズ制限の方法について記載します。

**

1) struts-config.xmlに最大ファイルサイズ制限を設定します。
<controller maxFileSize="10K" />

2) struts-config.xmlにメッセージリソースを利用したい場合はメッセージリソースを設定します。
<message-resources parameter="message"/>


3) struts-config.xmlにValidatorPlugInを設定します。
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
</plug-in>

4) 独自validatorクラスを実装する。
package jp.co.sheep.validator;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.validator.Field;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.upload.MultipartRequestHandler;
import org.apache.struts.validator.Resources;

/**
 *
 * @author SHEEP
 *
 */
public final class MyValidator {

    /**
     * コンストラクタ.
     */
    private MyValidator() {
        // 生成禁止
    }

    /**
     * ファイルサイズチェック.
     * @param bean
     *            Object
     * @param va
     *            ValidatorAction
     * @param field
     *            Field
     * @param errors
     *            ActionMessages
     * @param v
     *            Validator
     * @param request
     *            HttpServletRequest
     * @return HttpServletRequest
     */
    public static boolean fileCheck(final Object bean, final ValidatorAction va,
            final Field field, final ActionMessages errors, final Validator v,
            final HttpServletRequest request) {

        boolean result = true;

        // MultipartRequestHandlerでのファイルサイズチェック
        Boolean exceeded = (Boolean) request.getAttribute(
                MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);

        if (exceeded == null || !exceeded) {
            // 妥当性チェックを妥当とする
            result = true;
        } else {

            // 妥当性チェックを不適とする
            result = false;

            // ActionMessagesにエラー内容を追加
            ActionMessage actionMessage =
                    Resources.getActionMessage(v, request, va, field);
            errors.add(field.getKey(), actionMessage);
        }


        return result;
    }
}

5) (3)で設定したvalidator-rules.xmlに(4)の独自validatorクラスをvalidationルールに設定します。
<validator name="file"
           classname="jp.co.sheep.validator.MyValidator"
           method="fileCheck"
           methodParams="java.lang.Object,
               org.apache.commons.validator.ValidatorAction,
               org.apache.commons.validator.Field,
               org.apache.struts.action.ActionMessages,
               org.apache.commons.validator.Validator,
               javax.servlet.http.HttpServletRequest"
           depends=""
           msg="errors.file"/>


6) (3)で設定したvalidation.xmlにvalidationを宣言します。
<form-validation>
  <formset>
    <form name="FormBean">
      <field property="FieldName" depends="file">
        <!-- 個別にメッセージを指定したい場合はメッセージリソースのKeyを指定 -->
        <msg name="file" key="errors.file2" resource="true" />
      </field>
    </form>
  </formset>
</form-validation>

7) メッセージリソースの登録
errors.file=ファイルサイズ制限エラーです。
errors.file2=ファイルサイズ制限エラーです。2

0 件のコメント:

コメントを投稿