Y T //new to / I N U M M O C

NetBeansを使用したWicket 1.4で N O I T C A

N

のWebアプリケーション構築 I

A V

WicketとJava EE 6を組み合わせ、マークアップをビジネス・ロジックから分離して A Webアプリケーションを容易に構築 J

チュートリアルでは、NetBeans わせる方法についても説明します。Java ションを段階的に構築し、その過程で代替 は、プロジェクトを作成し、デフォルトの 本IDEを使用したApache Wicket EE 6は現在勢いを増しているだけでな 手段についても取り上げます。 Wicketアプリケーションを作成します。 1.4によるシンプルなWebアプリケー く、学習しやすいという利点があるため 注: 本チュートリアルで説明するプロジェ このアプリケーションは、後のセクション ションの構築方法を説明します。Wicket 採用しました。さらに、WicketとJava クトのソース・コードとその他の必要な で編集します。

はコンポーネント・ベースのWebアプリ EE 6との緊密な統合を実現するという ファイルは、こちらからダウンロードでき 1. NetBeans IDEで、「File」メニュー J A V T E C H RÉGINA TEN ケーション・フレームワークであり、POJO 理由から、NetBeansを利用します。 ます(14.6MB)。 から「New Project」を選択しま BRUGGENCATE、LINDA ()、HTML、 本来であれば、Wicketを利用した す。 VAN DER PAL Ajax、Spring、、Mavenを使 Webショップ全体の構築方法を説明し プロジェクトのセットアップ 2. 「 Categories」パネルで「Java S U

用してエンタープライズ・レベルのWeb たいところですが、紙面が足りません。 本 チュ ートリア ル の 前 半 は 、J e f f Web」を選択し、「Projects」パネル BIO T

アプリケーションを構築できます。 Webショップ全体の構築方法については Schwart氏のJava EE 6とWicket で「Web Application」を選択して、 U

Wicketをテーマに選んだ理由は、 『Wicket in Action』にまとめられて に関するブログに基づいています。本 「Next」をクリックします。 O RÉGINA TEN B BRUGGENCATE マークアップとロジックを分離できる点、 いるため、こちらをお読みください。本 チュートリアルの説明では簡略的すぎる 3. 「 P r o j e c t N a m e 」フィー ルド A (@REGINATB38) は、オランダのJAVA および再利用可能なコンポーネントを構 チュートリアルでは、詳細ページへのリ と思われる場合は、Schwartz氏のブロ にD u c h e s s S t o r eと入 力し、 コンサルティング企 築できる点が非常に優れているためで ンクを含む商品リストの表示方法に的 グで言及されている一連の記事をお読 「Next」をクリックします。 業IPROFS の上級開 発者です。現在は複 す。また、WicketをJava EE 6と組み合 を絞って説明します。Webアプリケー みください。 4. サ ー バ ー として「 G l a s s F i s h 数のオープンソース・ 必要なソフトウェアとファイルのダウン Server 3」が選択されているこ プロジェクトを活用す るオランダ鉄道のプ ロード: このセクションでは、開発環境の と、およびJava EEバージョンとして ロジェクトに従事して います。DUCHESS セットアップを行います。 「Java EE 6 Web」が選択されて (JDUCHESS.ORG) 1. MySQL、NetBeans、NetBeans いることを確認し、「Next」をクリック とWOMEN IN JAVA での活動、そして複数 用Wicketプラグインのダウンロード します。 のJAVAカンファレンス とインストールを実行します。 5. 「 F r a m e w o r k s 」パ ネ ル で 、 での講演実績により、 JAVA CHAMPIONに 2. create_script_mysql.sqlを使用し 「Wicket」を選択します(Wicketが 選出されています。 LINDA VAN DER て、基盤となるデータベースを作成し フレームワークとして選択できない PALはDUCHESSの ます。create_script_mysql.sqlス 場合は、Wicketプラグインが正しく blog 設立者です。JAVAコ ミュニティ全般に積極 クリプトを実行するためには、コマン インストールされていません)。 的に参加しています。ま ドライン・ツールで次の行を実行しま 6. 「 M a i n P a c k a g e 」に o r g . た、2002年以降は、複 数の企業でJAVA 開発 動画「Set Up Project」で本プロジェ す。\.Create_script_mysql.sql duchess.example.wicketと入 者として従事してます。 クトの作成手順をご確認ください プロジェクトの作成: このセクションで 力し、「Finish」をクリックします。 19

ORACLE.COM/JAVAMAGAZINE /////////////// MAY/JUNE 2012 //new to java / リスト1 リスト2 リスト3 注: 上記手順の実際の操作を動画「Set Up Connection」を選択します。 @Override

Project」で確認できます。 6. 「Driver」リストで「 MySQL (Connector/ COMMUNITY protected void init() { JavaEE Injectライブラリの追加: Wicket J Driver)」を選択し、「Next」をクリックし super.init(); にはJava EEサポートが含まれていませんが、 ます。 addComponentInstantiationListener(new Java EEサポート機能を追加するためのライブ 7. 「 Database」フィールドにduchess_ JavaEEComponentInjector(this)); ラリが存在します。このJava EE用のライブラリ storeと入力し、MySQLのインストール時 } に関する詳細は、GitHubを参照してください。 に作成したユーザー名とパスワードを入力し このライブラリはMavenと組み合わせて動作 て、「Finish」をクリックします。 するように作成されたものですが、本チュートリ 8. 「 Add All」をクリックしてすべての表をエンティ

アルではMavenを使用しません。そのために必 ティとして追加し、「Next」をクリックします。 ACTION IN JAVA 要となるJARファイルをSchwartz氏が特定し 9. 「 Package」フィールドにorg.duchess. てくださっています。Schwartz氏 example.entitiesと入力し、 にご提供いただいた、これらのJAR 優れた技術の融合 「Next」をクリックします。 ファイルをまとめたzipファイルが、 NetB eans によ 10. 「Collection Type」リストで ダウンロードに含まれています。 り、 Java EE 6 「java.util.List」を選択し、 1. libraries.zipファイルを解凍 と Wicket との緊 「Finish」をクリックします。 し、含まれている3つのJAR 密な統合が実現 注: 上記手順の実際の操作を動画 JAVA TECH ファイルをプロジェクトにイ します。 「Create Entities」で確認でき ンストールします。詳細は、 ます。 動画「Add Java EE Inject ヒント: データベース接続を削除 全てのリストのテキストをダウンロード Library」をご確認ください。 する必要が生じた場合、削除の 2. この3つのJARファイルを正常 操作をglassfish-resources. に動作させるために、リスト1に示すメソッドを xmlファイル(jdbc-connection-poolおよ For Entity Classes」を選択し、「Next」 ルシートを、最初に追加します。

Application.javaファイルに追加します。 びjdbc-resourceの削除)と「Services」 をクリックします。 1. images.zipファイルをwicketディレクトリに US ABOUT エンティティの作成: このセクションでは、デー タブのデータベースの両方で実行する必要 4. 「 Add All」をクリックし、「Next」をクリック 解凍します。正常に解凍できた場合、wicket タベースのデータを表すエンティティを作成しま があります。それでも接続が削除されない場 します。 ディレクトリ内にimagesディレクトリが作成 す。エンティティは、旧バージョンのJava EEで 合は、「Services」タブからサーバーを起動 5. 「 Package」フィールドにorg.duchess. されます。 はEJBと呼ばれていました。 し、「Servers」→「GlassFish Server」 example.beansと入力し、「Finish」をク 2. stylesheet.cssファイルもwicketディレク 1. NetBeans IDEで、「File」メニューから →「Resources」→「JDBC」→「JDBC リックします。 トリ内に配置します。 「New File」を選択します。 Resources」を確認して、接続の登録を解除し 注: 上記手順の実際の操作を動画「Create 次に、コードを編集します。現在のペー 2. 「Categories」リストで「 Persistence」を ます。 Session Beans」で確認できます。 ジの外観を変更するため、B a s e P a g eと 選択します。 セッションBeanの作成: このセクションでは、 HeaderPanelを変更し、FooterPanelを削 3. 「File Types」リストで「Entity Classes データベースのデータの入出力処理に関するア Wicketを使用した開発の開始 除します。 from Database」を選択し、「Next」をク プリケーションのビジネス・ロジックが含まれる 以上で、Wicketプロジェクトが実行できる状態 1. org.duchess.example.wicket パッ リックします。 セッションBeanを作成します。 になりました。もちろん、このプロジェクトはまだ ケージ内にあるBasePage.htmlファイルの 4. 「Data Source」リストで「New Data 1. NetBeans IDEで、「File」メニューから 何も実現していないため、本セクションで変更を 内容をリスト2のコードに置き換えます。この blog Source」を選択します。 「New File」を選択します。 加えていきます。はじめに、データベース内の商 BasePage.htmlがすべてのHTMLページ 5. 「 JNDI Name」フィールドにduchess_ 2. 「Categories」リストで「 Persistence」を 品のリストを表示するようにアプリケーションを の基礎となります。 s t o r e と入力し、「Database 選択します。 変更します。 2. org.duchess.example.wicketパッケー Connection」リストで「New Database 3. 「File Types」リストで「Session Beans 商品リストの作成: 後で必要となる画像とスタイ ジ内には、BasePage.javaファイルもあ 20

ORACLE.COM/JAVAMAGAZINE /////////////// MAY/JUNE 2012 //new to java / リスト4 リスト5 リスト6 リスト7 リスト8 ります。このファイルをリスト3と比較して の起動時に最初に表示されるページです。こ

みます。BasePageからFooterPanel のファイルのコードを、リスト6のコードに置 COMMUNITY HeaderPanelに渡すStringが1つ削除され されます。この表には、ヘッダーと単一の行 ています。BasePage.javaのコードをリスト3 があります。行にはwicket:idがあります。 の新しいコードに置き換えます。コンパイル・エ wicket:idは、行をRepeatingViewに関連 ラーが発生するため、次の2つの手順で修正し 付けるために使用します。また、行の3つの列 ます。 には、表示するデータを格納します。 3. org.duchess.example.wicket パッ 6. org.duchess.example.wicketパッケー

ケージ内にHeaderPanel.htmlファイル ジ内には、HomePage.javaファイルもあ ACTION IN JAVA があります。このファイルの内容をリスト ります。このファイルのコードをリスト7の 4のコードに置き換える必要があります。 コードに置き換えます。HomePageクラ

リスト4では、HeaderPanelにスタイル スでは、リスト6で示した行のwicket:idを シートとロゴの画像を追加しています。ま パラメータとして渡し、RepeatingView

た、表示されるテキストも変更しています。 インスタンスを作成しています。作成した
HeaderPanelは、BasePageを継承する RepeatingViewインスタンスをページに追 すべてのページの最上部に表示されます。 加します。次に、データベースからすべての JAVA TECH 4. 最後に、HeaderPanel.javaファイルのコー 商品を取得し、ループ処理を実行します。 ドをリスト5のコードに置き換えます。これに 各 項 目 に 対 し て 、W e b M a r k u p より、手順2に起因するコンパイル・エラーが C o n t a i n e r を作成します。『Wicket 解決されます。 in Action』で説明されているように、 いよいよ、本題の作業に移ります。データ WebMarkupContainerは汎用コンポーネ ベースに存在するすべての商品を表示するた ントであり、それ自体はほとんど何も実行しませ

めに、Wicketに用意されている、繰り返し項目 ん。ただし、子コンポーネントを含めることがで US ABOUT のリストを作成できるもっとも単純なコンポー きるため、コンポーネントをグループ化するため ネントの RepeatingViewを使 用します 。 には便利なツールです。また、1つのコンポーネ RepeatingViewコンポーネントは、すべての子要 ントに対して多くのマークアップをグループ化 素をデータベースから取得した順に表示します。 する必要がある場合に、中間レイヤーとして使 5. org.duchess.example.wicket パッ 用することもできます。リスト7のループ処理で ケージ内に、HomePage.htmlファイルが WebMarkupContainerを使用しない場合、複 全てのリストのテキストをダウンロード あります。このファイルは、アプリケーション 数の商品をページに追加しようとすると、IDの nameが重複するため例外 が発生します。ここでアプリ ンの見栄えが悪くなります。この問題を解決する ト8に示すとおり、コードは少しシンプルに ケーションを実行すると、図 ために、ページングを追加します。そのためには、 なります。項目のループ処理はListView 1のようなページが表示さ RepeatingViewをPageableListViewに が実行するため、HomePage.javaファ れます。 変更します。 イルに記述する必要はありません。また、 blog ページングの追加: データ 1. まず、 RepeatingViewをListView WebMarkupContainerも不要です。 ベースにある商品の数が増 に変更します。変更する必要があるのは、 必要な作業は、populateItemメソッドを えて、単一画面に収まらなく HomePage.javaファイルのみです。 オーバーライドして実装することのみです。 図1 なった場合、本ソリューショ HTMLファイルに変更はありません。リス HomePageのコードをリスト8のコードに 21

ORACLE.COM/JAVAMAGAZINE /////////////// MAY/JUNE 2012 //new to java / リスト9 リスト10 リスト11 リスト12 リスト13 置き換えます。 PagerFactoryを作成します。また、独自のナ package org.duchess.example.wicket;

次の手順は、ページングの追加です。この ビゲータとそのプロパティを作成する必要もあ COMMUNITY 手順も、比較的単純です。ただし、今度はJava ります。 import java.util.List; とHTMLの両方を変更する必要があります。 4. まず、新しいナビゲータ・クラスのための import javax.ejb.EJB; HomePage.javaファイルはリスト9に、 org.duchess.example.wicket. import org.apache.wicket.markup.html.basic.Label; HomePage.htmlファイルはリスト10に従って components.navigatorパッケージを新 import org.apache.wicket.markup.html.list.ListItem; 変更します。 規に作成します。 import org.apache.wicket.markup.html.list.PageableListView; 2. リ スト 9 に 示 す と おり、L i s t V i e w を 5. 最初に作成する必要のあるクラスは import org.apache.wicket.markup.html.navigation.paging. PagingNavigator; PageableListViewに変更し、リストに PagerFactory です。PagerFactoryクラス import org.duchess.example.beans.ProductFacade;

表示する要素数を示すパラメータをコン のコードをリスト11に示します。このコードで ACTION IN JAVA import org.duchess.example.entities.Product; ストラクタに追加することが必要です。ま は複数のコンパイル・エラーが発生しますが、後 た、ページ間のナビゲーションを処理する で修正します。 public class HomePage extends BasePage { PagingNavigatorも追加する必要があり 次の手順として、表示されるページが5ページ ます。それでは、HomePage.javaファイル を超える場合に使用するページャを作成します。 @EJB(name = "ProductFacade") のコードをリスト9のコードに置き換えます。 6. HighNumberNavigator という名前の新しい private ProductFacade productFacade; 3. リスト10 に示すとおり、HTMLファイルの変更 Wicket Pageを作成します。 public HomePage() { 部分はごくわずかで、ナビゲーション用のマー 7. 新規作成されたHTMLファイルのコードを、リ JAVA TECH List products = productFacade.findAll(); クアップを追加するだけです。リスト10の強調 スト12のコードに置き換えます。 PageableListView productList = 表示されたコードをHomePage.htmlファイ 8. 新規作成されたJavaファイルのコードを、リ new PageableListView("productList", ルに追加します。 スト13のコードに置き換えます。リスト13の products, 5) { 以上により、ページは図2のように表示されます。 コードは、フォーマット上の制約により不完全 @Override リストに含まれる商品の数が増えるにつれ な状態となっています。適宜インポート部を protected void populateItem(ListItem item) { Product product = item.getModelObject(); て、商品を表示するために必要なページ数も増 記述し、可読性を高めるために調整する必要

// name US ABOUT えていきますが、PagingNavigatorは拡張性 があります。 item.add(new Label("name", product.getName())); にあまり優れていません。最大でも10ページ 次の手順として、表示されるページが5ページ // description しか表示できず、残りのページ数を確認するこ 以下の場合に使用するページャを作成します。 item.add(new Label("description", product.getDescription())); ともできません。ページ数が多い場合は別のナ 9. LowNumberNavigator という名前の新 // price ビゲータを表示し、また、1ページしかない場合 しいWicket Pageを作成します。 item.add(new Label("price", product.getPrice().toString())); はナビゲ ータを表示しないようにすることで、機 10. 新規作成されたHTMLファイルのコード } }; 能性が改善します。このような変更を行うため を、リスト14のコードに置き換えます。 add(productList); には、商品数に応じて異なるナビゲータを返す 11. 新規作成されたJavaファイルのコード add(new PagingNavigator("navigator", productList)); を 、 リスト15 の コ ードに 置 き } 換えます。リスト15について } も、インポート部を適宜記述す る必要があります。この手順に より、PagerFactoryのコン blog パイル・エラーが解決します。

全てのリストのテキストをダウンロード 図2 22

ORACLE.COM/JAVAMAGAZINE /////////////// MAY/JUNE 2012 //new to java / リスト14 リスト15 リスト16 リスト17 リスト18 リスト19 12. ページャで使用される は、データ・プロバイダの作成で 構築が容易

テ キ スト を 設 定 す る た す。 COMMUNITY Wicket はコンポー "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> め に 、application. 1. org.duchess.example. ネント・ベースの xml:lang="en" propertiesという名前の wicket.dataproviders Web アプリケー xmlns:wicket="http://wicket.apache.org/"> プロパティ・ファイルをorg. という名前のパッケージを作 duchess.example. ション・フレーム 成します。 wicketパッケージに追 ワークエであり、 2. 作成したパッケージ内に、 加する必要があります。 ンタープライズ・レ IEjbDataProviderという

application.properties ベルの Web アプリ 名前のインタフェースを作成

ファイルの内容を、リスト ケーションを容易 します。 ACTION IN JAVA 16の内容に置き換えます。 に構築できます。 3. IEjbDataProviderインタ 13. HomePage.javaファイルの フェースのコードを、リスト コードをリスト17のとおりに 19に示すように記述します。 編集する必要があります。 4. 同じorg.duchess. 14. HomePage.htmlファイルのコードをリス example.wicket. ト18のとおりに編集する必要があります。 dataproviders DataProviderの作成: リストに含まれる パ ッ ケ ー ジ 内 に JAVA TECH 商品の数が多くなりすぎた場合、リスト全体 ProductDataProvider 5 を毎回取り扱う方法は負荷が高くなります。 という名前のクラスを作成し PageableListViewを使用する場合でも、 ます。 ページ上に項目が表示される前にリスト全体が 5. ProductDataProviderクラスのコードをリ

メモリに読み込まれます。 スト20に示すように記述します。また、イン
この問題を解決するためには、 a t a V i e w ポート部を適宜記述します。

US ABOUT を使用する必要があります。DataViewでは、 ProductDataProviderを作成した後は、 IDataProvider の実装が、データベースと 商品リストを専用のPanel内に配置して、商 DataViewの間のインタフェースとして利用されます。 品リストを完成させます。この方法の利点は、 DataViewを実装するための最初の手順 後にリストの再利用や移動が必要になった場 合に、容易に実行できることです。 P a n e lは独自のマークアップを含 むWicketコンポーネントです。し たがってProductsPanel.javaと ProductsPanel.htmlの両方を作成 する必要がありますが、この2つのファ イルはNetBeansによって自動的に生 成されます。 1. org.duchess.example.wicket blog パッケージを右クリックします。 2. 「 N e w 」メニュー から「 J a v a 動画「Add Java EE Inject Library」で Package」を選択します。 全てのリストのテキストをダウンロード WicketのJavaEE Injectライブラリに 3. 「 Package」フィールドにorg. ついてご確 認ください 23

ORACLE.COM/JAVAMAGAZINE /////////////// MAY/JUNE 2012 //new to java / リスト20 リスト21 リスト22 リスト23 リスト24 duchess.example.wicket. 10. ProductsPanel.javaファイルのコード package org.duchess.example.wicket.dataproviders;

productと入力し、「Finish」をク を、リスト22に示すように記述します。 COMMUNITY リックします。 11. 最後に、作成したPanelをHomePageに追 // imports 4. 作成されたorg.duchess.example.wicket. 加するため、HomePage.javaファイルをリ productパッケージを右クリックします。 スト23のように変更し、HomePage.html abstract public class ProductDataProvider implements IEjbDataProvider { 5. 「 New」メニューから「Other」を選択します。 ファイルをリスト24のように変更します。

6. 「Categories」リストで「 Web」を選択します。 商品の詳細情報を表示するページの作成: 次 @Override 7. 「File Types」リストで「Wicket Panel」を に、商品の詳細情報を表示するページを作成し public Iterator iterator(int first, int count) { 選択し、「Next」をクリックします。 ます。最初にProductDetailPageを作成す // to make sure we are not going to get a negative number of values // to retrieve, we need to reset the count

8. 「 F i l e N a m e 」フ ィ ー ル ド に る必要があります。これは次の手順で行います。 ACTION IN JAVA if (count < first) { ProductsPanelと入力し、「Finish」をク 1. org.duchess.example.wicket.product count += first; リックします。 パッケージを右クリックします。 } 9. ProductsPanel.htmlファイルのコードを、 2. 「 New」メニューから「Other」を選択します。 int[] range = {first, count}; リスト21に示すように記述します。 3. 「Categories」リストで「 Web」を選択します。 List products = getFacade().findRange(range); return products.iterator(); 4. 「File Types」リストで「Wicket } Page」を選択し、「Next」をクリッ

クします。 @Override JAVA TECH 5. 「 F i l e N a m e 」フィー ルドに public IModel model(final Product object) { final Long id = object.getProductId(); ProductDetailPageと入力し、 LoadableDetachableModel ldm = new 「Finish」をクリックします。 LoadableDetachableModel(object) { 6. ProductDetailPage.htmlファイ @Override ルのコードを、リスト25に示すよう protected Product load() { に記述します。コードは可読性を高 return getFacade().find(id);

} US ABOUT めるために適宜調整してください。 }; 7. ProductDetailPage.javaファイ return ldm; 動画「Create Entities」でエンティティ ルのコードを、リスト26に示すよう } の作成手順をご確認ください に記述します。また、インポート部を @Override 適宜記述します。 public int size() { 8. org.duchess.example. return getFacade().count(); wicket.productパッケージ内に } ImagesViewという名前のクラス @Override を作成します。 public void detach() { 9. ImagesView.javaファイルのコードを、 } リスト27に示すように記述します。 } 10. 次に、ProductsPanelにある productListに、各商品に対す blog るリンクを追加します。そのために は、JavaファイルとHTMLファイル 動画「Create Session Beans」でセッ の両方を変更します。リスト28に 全てのリストのテキストをダウンロード ションB ean の作成手順をご確認ください ProductsPanel.htmlファイルの内 24

ORACLE.COM/JAVAMAGAZINE /////////////// MAY/JUNE 2012 //new to java / リスト25 リスト26 リスト27 リスト28 リスト29 容を、リスト29にProductsPanel.

javaファイルの内容の一部を示しま COMMUNITY す。置き換える必要があるコードは、 Duchess store 強調表示された部分のみです。 11. 最後に、images_products.zipをディレ クトリorg\duchess\example\wicket\

クリプトを実行して、アプリケーションを完 成させます。 JAVA IN ACTION IN JAVA 本チュートリアルでは、ユーザー登録、ログオン、 ログオフ 、ユーザー・プロファイルの表示などの GIVE BACK! 方法は紙面の都合上説明できませんでした。す べてのコードについては、プロジェクトの完成 ADOPT A JSR 版でご確認ください。Wicketで実現できること や、WicketとNetBeansを使用したWebアプ 示してこれたのではないかと考えています。

LEARN MORE

Back

blog

全てのリストのテキストをダウンロード 25

ORACLE.COM/JAVAMAGAZINE /////////////// MAY/JUNE 2012