2008/01/24からのアクセス回数 12313
Agile Web Development with Railsの例題と同じ問題をSpringを使って実装を試みたときの メモです。
もう一つの目的は、Spring-MVCプラグインがどの程度実際の問題解決に役立つかを検証することです。
mavenを使ってプロジェクトを生成します。
とします。ecliseでプロジェクトを管理できるようにeclipseプラグインも起動します。
mvn archetype:create \ -DgroupId=example.cart \ -DartifactId=cart \ -DarchetypeArtifactId=spring-mvc-archetype \ -DarchetypeGroupId=jp.co.pwv.spring-mvc-archetype \ -DarchetypeVersion=1.1.1 cd cart mvn eclipse:eclipse -DdownloadSources=true
データベースは、HsqlDBのサーバを使用するため、db.propertiesの内容を修正します。
db.url=jdbc:hsqldb:hsql://localhost
最後にeclipseでcartプロジェクトをimportし、CVSに登録します。
長くなったので別タイトルにしました。
最初にProductを管理するページを作成します。
さしあたり、管理機能として
最初にProductのドメインモデルを作成します。 ドメインモデルは、example.cart.domainパッケージ内に定義します。
eclipseで以下のように入力した後、getter/setterを自動生成してください。
package example.cart.domain; public class Product { private Integer id; private String title; private String description; private String image_url; }
GenMVCプラグインのscaffoldゴールを指定して、ProductのDao、 Controller、 View、データベーステーブル を自動生成します。
その前に、GenMVCプラグインは、Productのクラスファイルを見に行くので、mavenのpackageを実行します。
mvn package mvn GenMVC:scaffold
このコマンドで、
[INFO] ------------------------------------------------------------------------ [INFO] Building Unnamed - example.cart:cart:war:1.0-SNAPSHOT [INFO] task-segment: [GenMVC:scaffold] [INFO] ------------------------------------------------------------------------ [INFO] [GenMVC:scaffold] [INFO] pkgName:example.cart [INFO] runtime.classpath:/Users/take/Documents/workspace/cart/target/classes [INFO] cls: example.cart.domain.Member [INFO] template fullpath:velocity/IDao.vm [INFO] template fullpath:velocity/Dao.vm [INFO] template fullpath:velocity/edit_stub.vm [INFO] template fullpath:velocity/list_stub.vm [INFO] template fullpath:velocity/hbm.vm [INFO] cls: example.cart.domain.Product [INFO] template fullpath:velocity/IDao.vm [INFO] template fullpath:velocity/Dao.vm [INFO] template fullpath:velocity/Manager.vm [INFO] template fullpath:velocity/EditController.vm [INFO] template fullpath:velocity/OpsController.vm [INFO] template fullpath:velocity/edit.vm [INFO] template fullpath:velocity/edit_stub.vm [INFO] template fullpath:velocity/list.vm [INFO] template fullpath:velocity/list_stub.vm [INFO] template fullpath:velocity/hbm.vm [INFO] template fullpath:velocity/servlet-stub.vm [INFO] template fullpath:velocity/sql.vm [INFO] template fullpath:velocity/applicationContext.vm [INFO] template fullpath:velocity/form-messages.vm [INFO] template fullpath:velocity/validation.vm
と出力され、必要なファイルがすべて生成されます。 再度、mvn packageを実行してtarget/cart.warをtomcatのwebappsにコピーします。
これだけで、Productのリスト表示、編集の画面が生成されます。
scaffoldの後にProductに属性を追加したくなることはよくあります。
Product の属性を変更したときの手順は以下の通りです。
通常は、これで十分ですが、以下のファイルを修正した場合にはバックアップを取ってください。
今回は、自動生成されたファイルを全く変更していないので、テーブルの削除だけを行います。
開発の途中ではデータベースのテーブルを変更したり、値を参照します。このような用途に便利なのが Ecl,ipseのプラグインDbEditです。 DbEditのインストール方法はhttp://www.pwv.co.jp/take_public_html/DevTool/DevTool_c9.html#doc1_589 を参照してください。
DbEditのTableタグを開くと以下のようにT_MEMBERとT_PRODUCTの2つのテーブルが作られています。
GenMVCプラグインでは、クラス名の前にT_を付けたテーブルが作成されます。 T_PRODUCTを削除するには、 T_PRODUCTで右マウスクリックから削除を選択してください。
Productに価格(price)を追加します。
以下のように属性priceを追加し、getter/setterを自動生成するだけです。
private Double price;
日本では価格に小数点はないのですが、ここでは例としてDouble型を使いました。
それでは、先ほどと同様にGenMVCプラグインを起動します。
mvn package mvn GenMVC:scaffold
GenMVCプラグインが生成する画面は、属性の出力順がProductクラスの定義順に並んでいないので、実際には手で修正する必要があります。
ProductのVelocityテンプレートは、main/webapp/WEB-INF/velocity/productops/以下にあります。
が一覧を表示するテンプレートです。
list.vmを見ると
parse ( "productops/list_stub.vm" )
だけです。 これは、GenMVCプラグインがlist.vmを変更しないようするためにlist_stub.vmをインクルードする 2段階で処理しています。
従ってユーザvelocityテンプレートを変更する場合には、list_stub.vmをlist.vmにコピーして編集します。 以下に順序を入れ替えたlist.vmを示します。
<html> <head> <title>Product</title> </head> <body> <h1>Listing product</h1> <table> <tr> <td>id</td> <td>title</td> <td>description</td> <td>image_url</td> <td>price</td> </tr> #foreach (${product} in ${productList}) <tr> <td>${product.id}</td> <td>${product.title}</td> <td>${product.description}</td> <td>${product.image_url}</td> <td>${product.price}</td> #set( $editLink = "/editproduct.htm?id=${product.id}" ) <td><a href="#springUrl(${editLink})">[edit]</a></td> #set( $deleteLink = "/productops/delete.htm?id=${product.id}" ) <td><a href="#springUrl(${deleteLink})">[delete]</a></td> </tr> #end </table> <a href='#springUrl("/editproduct.htm")'>add</a> </body> </html>
同様に編集画面も順序を変え、Descriptionをtextareaに変えてます。
<html> <head> <title>Products</title> </head> <body> Edit Product <form method="post" action="#springUrl("/editproduct.htm")"> #springFormHiddenInput( "product.id" "" ) <table> <tr> <td>title:</td> <td>#springFormInput( "product.title" "size='35'" )</td> <td> #springBind("product.title") <font color="red">${status.errorMessage}</font> </td> </tr> <tr> <td>description:</td> <td>#springFormTextarea( "product.description" "rows='4' cols='40'" )</td> <td> #springBind("product.description") <font color="red">${status.errorMessage}</font> </td> </tr> <tr> <td>image_url:</td> <td>#springFormInput( "product.image_url" "size='35'" )</td> <td> #springBind("product.image_url") <font color="red">${status.errorMessage}</font> </td> </tr> <tr> <td>price:</td> <td>#springFormInput( "product.price" "size='10'" )</td> <td> #springBind("product.price") <font color="red">${status.errorMessage}</font> </td> </tr> <tr> <td colspan="3"> <input type="submit" value="Save Changes"/> </td> </tr> </table> </form> </html> </body>
現在の入力フォームは、各フィールドが必須だけのチェックしかしていません。 priceに文字を入力して、Save Chageボタンを押すと
が出力されます。