SAStrutsのアクションフォームのpublicフィールにリクエストパラメータをバインドさせないアノテーション

例えば

@NotRequestParam
public String test;

みたいな感じなのですが、、、

[Seasar-user:18493] [SAStruts]public フィールドにリクエスト値を入力させない

ひがさんにさくっとあしらわれていて、ちょっとあれな感じだったので、作ってみた。

まず、アノテーション

package hoge;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotRequestParam {
}

リクエストパラメータとのバインドは、S2RequestProcessorでやっているので、その部分の挙動を変更するために、サブクラスをつくる。

package hoge;

import java.lang.reflect.Field;
import java.util.Map;

import org.seasar.framework.beans.BeanDesc;
import org.seasar.framework.beans.PropertyDesc;
import org.seasar.framework.beans.factory.BeanDescFactory;
import org.seasar.struts.action.S2RequestProcessor;

public class MyS2RequestProcessor extends S2RequestProcessor {

    public MyS2RequestProcessor() {
        super();
    }

    @Override
    @SuppressWarnings("unchecked")
    protected void setSimpleProperty(Object bean, String name, Object value) {
        if (bean instanceof Map) {
            setMapProperty((Map) bean, name, value);
            return;
        }

        if (isRequestParamBindable(bean, name)) {
            super.setSimpleProperty(bean, name, value);
        }
    }

    @Override
    protected void setIndexedProperty(Object bean, String name, int[] indexes,
            Object value) {
        if (isRequestParamBindable(bean, name)) {
            super.setIndexedProperty(bean, name, indexes, value);
        }
    }

    private boolean isRequestParamBindable(Object bean, String name) {
        BeanDesc beanDesc = BeanDescFactory.getBeanDesc(bean.getClass());
        if (!beanDesc.hasPropertyDesc(name)) {
            return false;
        }
        PropertyDesc pd = beanDesc.getPropertyDesc(name);
        if (!pd.isWritable()) {
            return false;
        }

        Field field = pd.getField();
        if (field != null) {
            NotRequestParam notRequestParam = field
                .getAnnotation(NotRequestParam.class);
            if (notRequestParam != null) {
                return false;
            }
        }

        return true;
    }
}

この MyS2RequestProcessor を、struts-config.xml に登録する。

    <controller
        maxFileSize="1024K"
        bufferSize="1024"
        processorClass="hoge.MyS2RequestProcessor"
        multipartClass="org.seasar.struts.upload.S2MultipartRequestHandler"/>

これで、NotRequestParamアノテーションをつけたフィールドは、リクエストパラメータがバインドされなくなる。

で、2点。

Requiredがついていると、常に、エラーになる。

  • セッションに保持ってるDTOのpublicフィールドまでは、抑制できない。

こっちの挙動を変えようとすると、S2Container 側の挙動まで変えなければならなそうなので、ちょっとなー。というかんじ。