• SAStrutsのAction

    2012年03月29日 21時52分
    前回の続きでもう1パターン考えてみました。

    やっぱり一々getter作るのは、書くのも読むのも面倒だよね。
    ということで、publicフィールドで行く方向で考えます。

    要するにリクエストパラメータのセットから特定のフィールドを除外してやれば良いわけです。
    「特定のフィールド」を指定するにはやはりアノテーションが良いでしょう。
    以下のアノテーションを作成します。
    1@Target(ElementType.FIELD)
    2@Retention(RetentionPolicy.RUNTIME)
    3public @interface Readonly
    4{
    5}



    リクエストパラメータのセットはS2RequestProcessorで行っているので、これを改造してしまいます。
    1public class RequestProcessor extends S2RequestProcessor
    2{
    3    @SuppressWarnings({"unchecked""rawtypes"})
    4    @Override
    5    protected void setSimpleProperty(Object bean, String name, Object value)
    6    {
    7        if (bean instanceof Map)
    8        {
    9            setMapProperty((Map)bean, name, value);
    10            return;
    11        }
    12
    13        BeanDesc beanDesc = BeanDescFactory.getBeanDesc(bean.getClass());
    14        if (!beanDesc.hasPropertyDesc(name))
    15            return;
    16
    17        PropertyDesc pd = beanDesc.getPropertyDesc(name);
    18        if (!pd.isWritable())
    19            return;
    20
    21        // @Readonlyアノテーションが有ったらセットしない
    22        Field f = pd.getField();
    23        if (f != null && f.getAnnotation(Readonly.class) != null)
    24            return;
    25        
    26        if (pd.getPropertyType().isArray())
    27            pd.setValue(bean, value);
    28        else if (List.class.isAssignableFrom(pd.getPropertyType()))
    29        {
    30            List<String> list = ModifierUtil.isAbstract(pd.getPropertyType()) ? new ArrayList<String>() : (List<String>)ClassUtil.newInstance(pd.getPropertyType());
    31            list.addAll(Arrays.asList((String[]) value));
    32            pd.setValue(bean, list);
    33        }
    34        else if (value == null)
    35            pd.setValue(bean, null);
    36        else if (value instanceof String[])
    37        {
    38            String[] values = (String[]) value;
    39            pd.setValue(bean, values.length > 0 ? values[0] : null);
    40        }
    41        else
    42        pd.setValue(bean, value);
    43    }
    44}


    struts-config.xmlを書き換えてセットします。
    <controller
            maxFileSize="1024K"
            bufferSize="1024"
            processorClass="jp.ku6.seasar.struts.action.RequestProcessor"
            multipartClass="org.seasar.struts.upload.S2MultipartRequestHandler"/>



    使い方は、publicなフィールドに@Readonlyを付けるだけです。
    1@Readonly
    2public List<Homu> homus;



    あと、publicにするとAutoBindingの対象になるので、一応ActionのAutoBindingDefを変更してみました。
    <component name="actionCreator" class="org.seasar.framework.container.creator.ActionCreator">
    		<initMethod name="setAutoBindingDef">
    			<arg>@org.seasar.framework.container.assembler.AutoBindingDefFactory@SEMIAUTO</arg>
    		</initMethod>
    	</component>


    別に対象になっても実際に設定されることはまず無いとは思うのですが、
    どうせ設定したい物には明示的に@Resourceを付けるので一応やっておくかなと。


    何かだめなところが見つかるまではこれで行ってみます。

    コメントを書く

    名前
    本文
    編集用パスワード
    管理者のみ閲覧