これまではこんな感じで週ごとに振り返ってきましたが、なかなか現実に追いつかず、また記憶があいまいな部分もあったりして、ちょっと書くのがしんどくなってきました。
これからはその日やったことを、HOTな状態のまま書いていきたいと思います。
画面部品
- マスタ系テーブルから項目取得
- セレクトボックスで表示
こんな画面部品をつくりたいと考えました。
参考リンク
その1: 画面部品 - C/pHeR Memo - Java とか。Eclipse とか。
その2:Cubby - Tips 集
ひと月前にこれらの記事を見たときはさっぱり意味がわかりませんでした。が、あらためてサンプルを見なおしてみたところ、作れそうな気がしてきたので実践してみることに。
よくある従業員テーブルから、idとnameでセレクトボックスを作る場合を例にしてみます。
失敗例
上記リンクその2のサンプルを参考にして、S2JDBCのServiceを利用した形で書いてみます。
<%@pageimport="java.util.List"%> <%@pageimport="org.seasar.framework.container.SingletonS2Container"%> <%@pageimport="test.entity.Employee"%> <%@pageimport="test.service.EmployeeService"%> <% EmployeeService employeeService = SingletonS2Container .getComponent(EmployeeService.class); List<Employee> employeeItems = employeeService.findAll(); pageContext.setAttribute("employeeItems", employeeItems); %> <html:select property="employeeId"> <c:forEach var="e" items="${employeeItems}"> <html:option value="${e.id}">${e.id} ${e.name}</html:option> </c:forEach> </html:select>
実行すると、「<html:option value="${e.id}">${e.id} ${e.name}</html:option>」の行でエラーが出ます。
javax.el.PropertyNotFoundException: Property 'id' not found on type test.entity.Employee
「プロパティが見つからない」といわれます。ここで参考記事を読み返してみます。
画面部品 - C/pHeR Memo - Java とか。Eclipse とか。
どうやら、型がBeanMapである必要があるらしいです。エンティティそのままではダメなようです。公式リファレンスにも、そのような記述がありました。
ActionやActionFormのプロパティは、 publicフィールドをELやStrutsが参照できるようにするために、 JavaBeansはMapに、配列はListにラップされています。
Super Agile Struts - Feature Reference
「プロパティ」とは
どうも、PHPの影響でプロパティとフィールドを混同してしまっていることに気づきました。ので、あらためて理解しようと調べてみました。
プロパティはフィールドとメソッドの中間的な存在と考えることができ、また高水準なカプセル化の実現にも使われる。
プロパティ - Wikipedia
プロパティとは、JavaBeansの属性を表すものです。一言でいえば、「Javaクラスのフィールド(インスタンス変数)をカプセル化したもの」です。
カプセル化するとインスタンス変数は賢くなる (1/1) - @IT
Javaでは純粋なメンバ変数は「フィールド」が正しく、アクセス可能な状態であれば「プロパティ」と言い換えられる、というように解釈しました。
成功例
Beans#createAndCopy()を用いて、取得したエンティティをBeanMapに変換します。複数件のListなので、繰り返す必要があります。
<%@pageimport="java.util.ArrayList"%> <%@pageimport="java.util.List"%> <%@pageimport="org.seasar.framework.beans.util.BeanMap"%> <%@pageimport="org.seasar.framework.beans.util.Beans"%> <%@pageimport="org.seasar.framework.container.SingletonS2Container"%> <%@pageimport="test.entity.Employee"%> <%@pageimport="test.service.EmployeeService"%> <% EmployeeService employeeService = SingletonS2Container .getComponent(EmployeeService.class); List<Employee> employeeList = employeeService.findAll(); List<BeanMap> employeeItems = new ArrayList<BeanMap>(); for (Employee employee : employeeList) { BeanMap map = Beans.createAndCopy(BeanMap.class, employee).execute(); employeeItems.add(map); } pageContext.setAttribute("employeeItems", employeeItems); %> <html:select property="employeeId"> <c:forEach var="e" items="${employeeItems}"> <html:option value="${e.id}">${e.id} ${e.name}</html:option> </c:forEach> </html:select>
これでうまくいきました。
あとは部品を使う側のJSPに、以下のように記述します。
<c:import url="/WEB-INF/view/test/parts/selectEmployee.jsp"/>
ところで、2つめの例で
- エンティティのリスト
- xxxList (employeeList)
- Mapのリスト
- xxxItems (employeeItems)
って変数名をつけてみたのですが、一般的にはどういう風につけるものなのか、ふと疑問に思ったりしました。