デジタルチャイルド日記

コンピュータ関連のいろいろメモを残していく子供部屋です。

strutsのFormFileValidator

strutsにはファイルをアップロードするFormFileなるインターフェースが存在する。このFormFileをチェックするvalidatorがないっぽいので、それを作成した時のメモ。

 

独自のvalidatorは以前に記事を書いているのでそちらを参照するとして、具体的にソースなどを記載しておきます。

FormFileChecksクラスを作成。

まずはチェックをするロジックを作成します。作成する内容はファイルの拡張子をチェックすることにします。

注意することは、エラーが発生した場合にFormFileのメンバーをnullでクリアすることです。これを行っていないと、エラーがでたまま、再度、POSTすると異常終了するとかなんとか・・・

※FormFileのプロパティが2つ以上ある場合は、両方ともnullクリアする必要があるのかな・・・それなら、もう少し考えないといけないけど。

あとは、FormFile用のgetValueFormFileメソッドを作成していることぐらいですね。

 

package jp.digitalchild.struts.fw.validator;

import java.lang.reflect.InvocationTargetException;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.upload.FormFile;
import org.apache.struts.validator.Resources;

/**
 * ファイルチェック用のValidator
 *
 */
public class FormFileChecks {

	/**
	 * ファイルの拡張子をチェックする。
	 *
	 * @param bean
	 * @param va
	 * @param field
	 * @param errors
	 * @param v
	 * @param request
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static boolean validateFileType(Object bean,
		ValidatorAction va,
		Field field,
		ActionMessages errors,
		Validator v,
		HttpServletRequest request) {
        
        // ファイルの取得
		FormFile value = null;
		try {
			value = getValueFormFile(bean, field.getProperty());
		} catch(Exception e){
			return false;
		}
		// 値が正しく取得できた場合は、チェック処理
		if(value != null && value.getFileSize() != 0) {

			String[] fileStrings = value.getFileName().split(Pattern.quote("."));
			String extentioin = fileStrings[fileStrings.length-1];

			// 比較対象拡張子の読み込み
			String fileTypeList = field.getVarValue("FileType");
			if(fileTypeList != null) {
				String[] candidates = fileTypeList.split(",");

				for (int cnt = 0; cnt < candidates.length; cnt++) {
					if (candidates[cnt].equalsIgnoreCase(extentioin)) {
						return true;
					}
				}
			}
			// 1つもマッチしない場合は、エラー処理
			errors.add(field.getKey(),
		       Resources.getActionMessage(request, va,  field));
			value = null;
			return false;
		} else {
			return true;
		}
	}


	/**
	 * ファイルの拡張子をチェックする。(条件付き)
	 *
	 * @param bean
	 * @param va
	 * @param field
	 * @param errors
	 * @param v
	 * @param request
	 * @return
	 */
	public static boolean validateFileTypeIf(Object bean,
		ValidatorAction va,
		Field field,
		ActionMessages errors,
		Validator v,
		HttpServletRequest request) {

		Object form = v.getParameterValue("java.lang.Object");

		FormFile value = null;
		boolean required = false;

		// 値の取得
		try {
			value = getValueFormFile(bean, field.getProperty());
		} catch(Exception e){
			return false;
		}

		// 条件文の構文解析strutsの標準ロジックと同じ)
		int i = 0;
		String fieldJoin = "AND";

		if(!GenericValidator.isBlankOrNull(field.getVarValue("fieldJoin"))) {
			fieldJoin = field.getVarValue("fieldJoin");
		}

		if(fieldJoin.equalsIgnoreCase("AND")) {
			required = true;
		}

		for(; !GenericValidator.isBlankOrNull(field.getVarValue("field[" + i + "]")); ++i) {

			String dependProp = field.getVarValue("field[" + i + "]");
			String dependTest = field.getVarValue("fieldTest[" + i + "]");
			String dependTestValue = field.getVarValue("fieldValue[" + i + "]");
			String dependIndexed = field.getVarValue("fieldIndexed[" + i + "]");

			if(dependIndexed == null) {
				dependIndexed = "false";
			}

			String dependVal = null;
				boolean thisRequired = false;

				if(field.isIndexed() && dependIndexed.equalsIgnoreCase("true")) {
					String key = field.getKey();

					if(key.indexOf("[") > -1 && key.indexOf("]") > -1) {
						String ind = key.substring(0, key.indexOf(".") + 1);

						dependProp = ind + dependProp;
					}
				}

				dependVal = ValidatorUtils.getValueAsString(form, dependProp);

				if(dependTest.equals("NULL")) {
					if(dependVal != null && dependVal.length() > 0) {
						thisRequired = false;
					} else {
						thisRequired = true;
					}
				}

				if(dependTest.equals("NOTNULL")) {
					if(dependVal != null && dependVal.length() > 0) {
						thisRequired = true;
					} else {
						thisRequired = false;
					}
				}

				if(dependTest.equals("EQUAL")) {
					thisRequired = dependTestValue.equalsIgnoreCase(dependVal);
				}

				if(fieldJoin.equalsIgnoreCase("AND")) {
					required = required && thisRequired;
				} else {
					required = required || thisRequired;
				}
		}

		// 条件が成立していれば
		if(required) {
			if(value != null && value.getFileSize() != 0) {

				String[] fileStrings = value.getFileName().split(Pattern.quote("."));
				String extentioin = fileStrings[fileStrings.length-1];

				// 比較対象拡張子の読み込み
				String fileTypeList = field.getVarValue("fileType");
				if(fileTypeList != null) {
					String[] candidates = fileTypeList.split(",");

					for (int cnt = 0; cnt < candidates.length; cnt++) {
						if (candidates[cnt].equalsIgnoreCase(extentioin)) {
							return true;
						}
					}
				}
				// 1つもマッチしない場合は、エラー処理
				errors.add(field.getKey(), Resources.getActionMessage(v, request, va, field));
				value = null;
				return false;
			} else {
				return true;
			}
		} else {
			return true;
		}
	}

	/**
	 * FormFile型でFormから値を取得
	 *
	 * @param bean
	 * @param property
	 * @return
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	public static FormFile getValueFormFile(Object bean, String property) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		Object value = null;

		try {
			value = PropertyUtils.getProperty(bean, property);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw e;
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			throw e;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
			throw e;
		}
		return value == null?null:(value instanceof FormFile?(FormFile)value:null);
	}
}

※条件付きのチェックについても、同様に作成しています。(validateFileTypeIf)

validator-rules.xmlへの追加

 

validator-rules.xmlに以下を追加します。内容についての説明は割愛。

<?xml version="1.0" encoding="UTF-8" ?>

<form-validation>
	<global>
	<-- ここから下追加  -->
	<validator name="fileTypeCheck" classname="jp.digitalchild.struts.fw.validator.FormFileChecks" method="validateFileType" 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.fileTypeError"></validator>

    <validator name="fileTypeCheckIf" classname="jp.digitalchild.struts.fw.validator.FormFileChecks" method="validateFileTypeIf" 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.fileTypeError">%lt;/validator>
	<-- ここまで追加  -->

    </global>
</form-validation>
    

 

validation.xmlへの追加

 

validation.xmlに以下を追加します。内容についての説明は割愛。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE form-validation PUBLIC
    "-//Apache Software Foundation//
    DTD Commons Validator Rules Configuration 1.1.3//EN"
    "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">

<form-validation>
	<formset>
		<form name="sampleForm">
			<field property="file" depends="fileTypeCheckIf">
        		<!-- ファイルタイプ -->
				<var>
					<var-name>fileType</var-name>
					<var-value>jpg,png,gif</var-value>
				</var>
                <!-- 条件:dependsをfileTypeCheckの場合、不要 -->
				<var>
					<var-name>field[0]</var-name>
					<var-value>checkbox1</var-value>
				</var>
				<var>
					<var-name>fieldTest[0]</var-name>
					<var-value>EQUAL</var-value>
				</var>
                <var>
                    <var-name>fieldValue[0]</var-name>
                    <var-value>1</var-value>
                </var>
			</field>
		</form>
	</formset>
</form-validation>

その他

フォームの作成は、特に記載することはありません。プロパティとして、fileをFormFile型で定義すること、getter,setterを準備すること。

あとは、struts-config.xmlで、sampleFormのFormを定義すること。

この辺りは、strutsの基本なので、ここでは割愛します。

 

以上、簡単なメモでした。