• SAStrutsのHTML5対応 その3

    2015年06月18日 01時04分
    taglib-html5_1_2_9_2.zip

    ナウなHTML5で必要な属性が足りていなかったのでいくらか足しました。
    • textareaタグ
      • maxlength属性
      • wrap属性

    やはり無条件に全て受け入れてそのまま出すというのが正解だった気がしますが今更後には引けない。

    というか、これJava1.3のソースをtarget=Java1.2で作っているのですが、
    Java9以降は3バージョンくらい古いバージョンしかサポートしてくれない予定のようなので
    さすがにそろそろ延命措置も厳しい気がします。
  • SAStrutsのHTML5対応 その2

    2013年08月01日 23時15分
    taglib-html5_1_2_9_1.zip

    旧バージョンからさらに属性を追加しています。
    HTML5の仕様を見つつ追加したので必要な物は大体フォローされているかと思います。

    これだけ属性が多いので
    書かれた属性をそのまま全部出力するようにした方が良いのではないかと
    思ったりもしましたがとりあえず素直に追加しました。

    旧バージョンではFormTagは付属せず元の物を使うようにしていたのですが
    formタグにも属性を追加するため新たに作成しています。

    それに伴いSAStrutsとの連携部分で不都合が起きたため
    SAStrutsのタグを改造した物も付けました。

    今更このバージョンのStrutsを使うということは
    ほぼSAStrutsだと思いますので利用頻度は高いと思います。
  • SAStrutsのHTML5対応

    2012年08月21日 23時16分
    SAStrutsはStrutsベースなのでフォームを作るときはtaglibを使うわけですが、
    これがもうだいぶ古いプログラムなのでHTML5なんて知らないのです。

    しかし、最近ブラウザでも実装され始め、にわかに便利な
    emailとかrequiredとかpatternとかを使いたい!


    というわけでHTML5対応してみました。
    taglib-html5_1_2_9_0.zip


    対応といっても基本的にはTextTagをコピペして各種inputタグを作成し、
    TLDに新しい属性を書きまくっただけです。

    しばらく使ってみていますが、一応動いているので大丈夫な気がします。
  • SAStrutsとmultipart/form-data

    2012年05月19日 16時38分
    SAStrutsを使っていて、formをsubmitしたら何故か404エラーという現象で困ったのでメモって置きます。

    RoutingFilterがHttpServletRequestのパラメータ名とActionのMethod名との一致をチェックしていますが、
    formがmultipart/form-dataだとHttpServletRequestのパラメータが空なので
    <s:submit/>で指定したMethod名が見つからずNot foundとなるようです。

    「index」というメソッドを実装しておくと、これがデフォルトで選ばれてforwardされるので、
    multipart/form-dataのフォームを受け取るActionには「index」という名前のメソッドを作って置こう。
  • 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を付けるので一応やっておくかなと。


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