[java][seasar] EL で Session の属性値にアクセス

SAStruts のアクションフォームのチュートリアルを使って実験。JSP にて Session に格納したオブジェクトの値を、EL式 を使って表示できるかどうか。

@Component(instance = InstanceType.SESSION)
public class FormDto implements Serializable {

	private static final long serialVersionUID = 1L;

	@Required
	public String first;

	@Required(target = "goThird")
	public String second;
}

というアクションフォームがあるので、JSP で次のようにすれば、値を表示できるはず。(sessionScope は冗長だけど、明示的にセッションのなかにアクセスするという意味で書いてます)

${sessionScope.formDto.first}

ところが、これはダメ。

javax.el.PropertyNotFoundException: Property 'first' not found on type tutorial.dto.FormDto

プロパティとして認識してもらえない。えー。

Seasar2はpublicフィールドをプロパティとみなすことができるので、 getter,setterは記述する必要はありません。 publicフィールドは、ELやStrutsからでも認識できるようになっています。そのからくりに興味のある方は、org.seasar.struts.actionのソースを眺めてください。

公式ドキュメントにあるように SAStruts では、public なフィールドでも、EL式でアクセスが可能なはず。BeanWrapper クラスあたりで、ごにょごにょやっているのだと思うけど、これが sessionScope のなかを見る際には、動いていないっぽい。

上述の FormDto に getter/setter を追加することで、うまくいきました。

めんどいので PropertyInterType で

セッションに格納したときのために Dto に getter/setter を定義していくのが面倒に思って、PropertyInterType を使ってやってみた。結論から言うと、うまくいかず。うーむ。

customizer.dicon

    <component name="dtoCustomizer"
        class="org.seasar.framework.container.customizer.CustomizerChain">
        <initMethod name="addCustomizer">
            <arg>
             <component class="org.seasar.framework.container.customizer.InterTypeCustomizer">
                 <property name="interTypeName">"propertyInterType"</property>
             </component>              
            </arg>
        </initMethod>
    </component>

として

@Property
@Component(instance = InstanceType.SESSION)
public class FormDto implements Serializable {
    // 中略
}

とすることで

DEBUG 2008-02-24 14:21:14,781 [http-8080-1] クラス(tutorial.dto.FormDto[formDto])のコンポーネント定義を登録します
DEBUG 2008-02-24 14:21:14,781 [http-8080-1] [PropertyInterType] Introducing... tutorial.dto.FormDto
DEBUG 2008-02-24 14:21:14,781 [http-8080-1] [PropertyInterType] Creating getter tutorial.dto.FormDto#getFirst
DEBUG 2008-02-24 14:21:14,843 [http-8080-1] [PropertyInterType] Creating setter tutorial.dto.FormDto#setFirst
DEBUG 2008-02-24 14:21:14,875 [http-8080-1] [PropertyInterType] Creating getter tutorial.dto.FormDto#getSecond
DEBUG 2008-02-24 14:21:14,906 [http-8080-1] [PropertyInterType] Creating setter tutorial.dto.FormDto#setSecond

という感じでアクセッサが自動で作られたんだけど、JSP を開いたら、

javax.servlet.ServletException: javax.servlet.jsp.JspException: Bean org.seasar.struts.action.ActionFormWrapper のプロパティ first に対するゲッターメソッドがありません

というオチ。ELでのアクセスってリフレクションでやっているわけじゃないのかなあ。それとも、何かの順番の問題なのかな。

めんどいので eclipse

原因究明も楽しいのだけど、ラインも進めないといけないので、黙って eclipse で getter/setter を自動生成することで一件落着。本意ではないけれども、こうして苦しくなったときに、ゴリゴリ書いていけば思うように動かせる点で、SAStruts の薄さはとても気に入っている。SMART deploy や DI の恩恵を受けながら、自由度も高いという、トレードオフの壁を破っているところが良いんです。