Apache-tapestry-quick-guide

提供:Dev Guides
移動先:案内検索

Apacheタペストリー-概要

Apache Tapestryは、Javaで書かれたオープンソースのWebフレームワークです。 *コンポーネントベースのWebフレームワーク*です。 タペストリーコンポーネントはJavaクラスです。 これらは、フレームワーク固有の基本クラスやインターフェースの実装から継承されたものではなく、単なるPOJO(プレーンな古いJavaオブジェクト)です。

タペストリーで使用されるJavaの重要な機能は*注釈*です。 Tapestry Webページは、それぞれが多くのTapestryの注釈で装飾されたXMLベースのテンプレートとコンポーネントクラスを持つ1つ以上のコンポーネントを使用して構築されます。 Tapestryは、小さな単一ページのWebアプリケーションから数百ページで構成される大規模なアプリケーションまで、あらゆるものを作成できます。

タペストリーの利点

タペストリーによって提供される利点のいくつかは-

  • 拡張性の高いWebアプリケーション。
  • アダプティブAPI。
  • 高速で成熟したフレームワーク。
  • 永続的な状態ストレージ管理。
  • ビルトイン制御の反転。

タペストリーの特徴

タペストリーには次の機能があります-

  • ライブクラスのリロード
  • 明確で詳細な例外報告
  • 静的構造、動的動作。
  • Plain Old Java Object(POJO)の広範な使用
  • コードを少なくして、より多くを提供します。

タペストリーを選ぶ理由

すでにJavaには、JSP、Strutsなどのような多くのWebフレームワークがありますが、なぜ別のフレームワークが必要なのでしょうか? 今日のJava Webフレームワークのほとんどは複雑であり、急な学習曲線を持っています。 これらは古く、更新ごとにコンパイル、テスト、展開のサイクルが必要です。

一方、Tapestryは live class reloading を提供することにより、Webアプリケーションプログラミングへの最新のアプローチを提供します。 他のフレームワークが多くのインターフェース、抽象クラスおよび基本クラスを導入している一方で、Tapestryはほんのわずかな注釈セットを導入するだけで、豊富なAJAXサポートを備えた大規模アプリケーションを作成する機能を提供します。

Apacheタペストリー-アーキテクチャ

Tapestryは、可能な限りJavaの利用可能な機能を使用しようとします。 たとえば、すべてのTapestryページは単なるPOJOです。 アプリケーションを作成するためのカスタムインターフェイスや基本クラスを強制しません。 代わりに、アノテーション(Javaクラスの機能を拡張するための軽量オプション)を使用して機能を提供します。 バトルテスト済みの Java Servlet API に基づいており、サーブレットフィルターとして実装されています。 Webアプリケーションに新しい次元を提供し、プログラミングは非常にシンプルで、柔軟で、理解しやすく、堅牢です。

ワークフロー

タペストリーページが要求されたときに行われる一連のアクションについて説明します。

ワークフロー

ステップ1 *- *Java Servlet はページ要求を受け取ります。 このJavaサーブレットは、着信要求がタペストリーに転送されるように構成されています。 設定は、次のプログラムで指定されている web.xml で行われます。 フィルターおよびフィルターマッピングタグは、すべてのリクエストを_Tapestry Filter_にリダイレクトします。

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
   "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
   <display-name>My Tapestry Application</display-name>
   <context-param>
      <param-name>tapestry.app-package</param-name>
      <param-value>org.example.myapp</param-value>
   </context-param>
   <filter>
      <filter-name>app</filter-name>
      <filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>app</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

ステップ2 *- *Tapestry Filter は、* Service()メソッドによって *HttpServletRequestHandler サービスを呼び出します。

ステップ3 *- *HttpServletRequestHandler は、リクエストとレスポンスを RequestGlobals に保存します。 また、要求と応答をRequest and Responseオブジェクトとしてラップし、RequestHandlerに送信します。

ステップ4 *- *RequestHandler は、Servlet APIの HttpServletRequest を抽象化したものです。 タペストリーの顕著な特徴のいくつかは RequestHandler セクションで行われます。 タペストリーの機能は、RequestHandlerにフィルターを記述することで拡張できます。 RequestHandlerは、以下を含むいくつかの組み込みフィルターを提供します-

  • CheckForUpdates Filter -ライブクラスのリロードを担当します。 このフィルターは、Javaクラスの変更を確認し、必要に応じてアプリケーションを更新します。
  • ローカリゼーションフィルター-ユーザーの場所を特定し、アプリケーションのローカリゼーションサポートを提供します。
  • StaticFiles Filter -静的リクエストを特定し、プロセスを中止します。 プロセスが中止されると、Javaサーブレットが制御を取得してリクエストを処理します。
  • エラーフィルター-キャッチされなかった例外をキャッチし、例外レポートページを表示します。

RequestHandlerは、RequestQlobal内の要求と応答を変更および保存し、MasterDispatcherサービスを呼び出します。

ステップ5 *- *MasterDispatcher は、特定の順序で複数のディスパッチャを呼び出してページをレンダリングします。 MasterDispatcherによって呼び出される4つの主要なディスパッチャは次のとおりです-

  • RootPath Dispatcher -要求のルートパス「/」を認識し、開始ページと同じものをレンダリングします。
  • Asset Dispatcher -URLパターン/assets/を確認することでアセット(Javaアセット)リクエストを認識し、リクエストされたアセットをバイトストリームとして送信します。
  • PageRender Dispatcher -タペストリー操作の大部分はPageRender Dispatcherおよび次のディスパッチャコンポーネントDispatcherで実行されます。 このディスパッチャは、そのリクエストの特定のページとそのアクティベーションコンテキスト(追加情報)を認識します。 次に、その特定のページをレンダリングし、クライアントに送信します。 たとえば、リクエストURLが/product/12123434の場合、ディスパッチャはproduct/12123434という名前のクラスが使用可能かどうかを確認します。 見つかった場合は、product/12123434クラスを呼び出し、応答を生成してクライアントに送信します。 そうでない場合、製品クラスをチェックします。 見つかった場合は、追加情報121234434を使用して製品クラスを呼び出し、応答を生成してクライアントに送信します。 この追加情報は、アクティベーションコンテキストと呼ばれます。 クラスが見つからない場合、要求はコンポーネントディスパッチャに転送されます。
  • コンポーネントディスパッチャー-コンポーネントディスパッチャーは、パターンのページのURLと一致します-/<class_name>/<component_id>:<event_type>/<activation_context>。 たとえば、/product/grid:sort/ascは、製品クラス、グリッドコンポーネント、sorteventタイプ、ascアクティベーションコンテキストを表します。 ここで、event_typeはオプションであり、何も指定されていない場合、デフォルトのイベントタイプアクションがトリガーされます。 通常、コンポーネントディスパッチャーの応答は、リダイレクトをクライアントに送信することです。 ほとんどの場合、リダイレクトは次のリクエストでPageRender Dispatcherと一致し、適切な応答がクライアントに送信されます。

Apache Tapestry-インストール

この章では、マシンにTapestryをインストールする方法について説明します。

前提条件

Tapestryの唯一の依存関係は Core Java です。 Tapestryは、サードパーティのライブラリ/フレームワークを使用せずに独立して開発されています。 タペストリーで使用されるIoCライブラリでさえ、ゼロから開発されています。 タペストリーで記述されたWebアプリケーションは、コンソール自体から構築および展開できます。

*Maven、Eclipse* 、および *Jetty* を使用して、開発エクスペリエンスを改善できます。 Mavenは、Javaの事実上の開発サーバーであるJettyでアプリケーションをホストするためのクイックスタートアプリケーションテンプレートとオプションを提供します。 Eclipseは、広範なプロジェクト管理機能を提供し、Mavenとうまく統合します。

理想的なタペストリーのアプリケーション開発には、次のものが必要です-

  • Java 1.6以降
  • Apache Maven
  • Eclipse IDE
  • Jettyサーバー

Mavenインストールの検証

マシンにMavenがインストールされていることを願っています。 Mavenのインストールを確認するには、以下のコマンドを入力します-

mvn --version

次のように応答を確認できます-

Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-1110T22:11:47+05:30)
Maven home:/Users/workspace/maven/apache-maven-3.3.9
Java version: 1.8.0_92, vendor: Oracle Corporation
Java home:/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.4", arch: "x86_64", family: "mac"

Mavenがインストールされていない場合は、https://maven.apache.org/[Maven] Webサイトにアクセスして、mavenの最新バージョンをダウンロードしてインストールします。

タペストリーをダウンロード

タペストリーの最新バージョンは5.4で、https://tapestry.apache.org/[Tapestry] Webサイトからダウンロードできます。 binaryパッケージをダウンロードするだけで十分です。 Mavenクイックスタートテンプレートを使用する場合、Tapestryを個別にダウンロードする必要はありません。 Mavenは必要なタペストリージャーを自動的にダウンロードし、アプリケーションを構成します。 次の章では、Mavenを使用して基本的なTapestryアプリケーションを作成する方法について説明します。

Apacheタペストリー-クイックスタート

Tapestryのインストール後、以下に示すようにMavenを使用して新しい初期プロジェクトを作成しましょう-

$ mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org

次のように応答を確認できます-

[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ---------------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.4:generate (default-cli) >
generatesources @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.4:generate (default-cli)
< generatesources @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart
(org.apache.maven.archetypes:maven-archetype-quickstart:1.0)

Mavenがすべての操作をビルドした後、アーキタイプを選択して、次のように Tapestry 5 QuickStart プロジェクトを作成します-

アーキタイプを選択-

  • [[1]] 5クイックスタートプロジェクト)
  • [[2]] 4.1.6アーキタイプ)

番号を選択するか、フィルターを適用します(形式:[groupId:] artifactId、大文字と小文字を区別して含む)::1

これで、以下に示すような応答が得られます-

Choose org.apache.tapestry:quickstart version:
1: 5.0.19
2: 5.1.0.5
3: 5.2.6
4: 5.3.7
5: 5.4.1

次のようにQuickStartのバージョン番号を抽出します-

Choose a number: 5: 5

ここでは、QuickStartプロジェクトはオプション5「5.4.1」のバージョンを使用します。 さて、タペストリーの原型は次のように次の情報を一つずつ尋ねます-

  • 5.1 groupId -プロパティ 'groupId’の値を定義します::com.example
  • 5.2 artifactId -プロパティ 'artifactId’の値を定義::Myapp
  • * 5.3バージョン*-プロパティ 'version’の値を定義:1.0-SNAPSHOT::
  • * 5.4パッケージ名*-プロパティ「package」の値を定義:com.example::com.example.Myapp

今、あなたの画面はあなたから確認を求めます-

プロパティ構成の確認-

  • groupId -com.example
  • artifactId -Myapp
  • バージョン-1.0-SNAPSHOT
  • パッケージ-com.example.Myapp

すべてのプロパティを確認し、以下に示すオプションを使用して変更を確認します-

 Y: : Y

次のような画面が表示されます。

[INFO] ---------------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: quickstart:5.4.1
[INFO] ---------------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: Myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.example.Myapp
[INFO] Parameter: packageInPathFormat, Value: com/example/Myapp
[INFO] Parameter: package, Value: com.example.Myapp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: Myapp
[WARNING] Don't override file/Users/workspace/tapestry/Myapp/src/test/java
[WARNING] Don't override file/Users/workspace/tapestry/Myapp/src/main/webapp
[WARNING] Don't override file/Users/workspace/tapestry/Myapp/src/main/resources/com/
example/Myapp
[WARNING] Don't override file/Users/workspace/tapestry/Myapp/src/test/resource
[WARNING] Don't override file/Users/workspace/tapestry/Myapp/src/test/conf
[WARNING] Don't override file/Users/workspace/tapestry/Myapp/src/site
[INFO] project created from Archetype in dir:/Users/workspace/tapestry/Myapp
[INFO] ---------------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ---------------------------------------------------------------------------------
[INFO] Total time: 11:28 min
[INFO] Finished at: 2016-09-14T00:47:23+05:30
[INFO] Final Memory: 14M/142M
[INFO] ---------------------------------------------------------------------------------

これで、Tapestryクイックスタートプロジェクトが正常にビルドされました。 次のコマンドを使用して、新しく作成された Myapp ディレクトリの場所に移動し、コーディングを開始します。

cd Myapp

アプリケーションを実行

スケルトンプロジェクトを実行するには、次のコマンドを使用します。

mvn jetty:run -Dtapestry.execution-mode=development

このような画面が表示されます

[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------------------------------------------------------------------
[INFO] Building Myapp Tapestry 5 Application 1.0-SNAPSHOT
[INFO] ---------------------------------------------------------------------------------
........
........
........
Application 'app' (version 1.0-SNAPSHOT-DEV) startup time: 346 ms to build IoC
Registry, 1,246 ms overall.
 ______                  __             ____
/_  __/__ ____  ___ ___//_______ __ /__/
///_ `/_ \/-_|_-</__/__/////__ \
/_/ \_,_/.__/\__/___/\__/_/ \_,//____/
       /_/                 /___/ 5.4.1 (development mode)
[INFO] Started [email protected]:8080
[INFO] Started Jetty Server

現在、Tapestryで基本的なクイックスタートプロジェクトを作成しています。 Webブラウザで実行中のアプリケーションを表示するには、アドレスバーに次のURLを入力し、Enterキーを押します-

*https://localhost:8080/myapp*

ここで、 myapp はアプリケーションの名前であり、開発モードでのアプリケーションのデフォルトポートは8080です。

Eclipseを使用する

前の章では、CLIでTapestryクイックスタートアプリケーションを作成する方法について説明しました。 この章では、 Eclipse IDE でのスケルトンアプリケーションの作成について説明します。

Mavenアーキタイプを使用してスケルトンアプリケーションを作成しましょう。 新しいアプリケーションを構成するには、以下の手順を実行できます。

ステップ1:Eclipse IDEを開く

次のスクリーンショットに示すように、Eclipseを開き、ファイル→新規→プロジェクト…→オプションを選択します。

Open Eclipse

ここで、Maven→Mavenプロジェクトオプションを選択します。

-Mavenが構成されていない場合は、プロジェクトを構成および作成します。

Mavenプロジェクトを選択した後、「次へ」をクリックし、もう一度「次へ」ボタンをクリックします。

Mavenプロジェクト

その後、構成オプションを選択する画面が表示されます。 構成が完了すると、次の画面が表示されます。

Configure Option

ステップ2:カタログの構成

最初の手順が完了したら、[リモートカタログの追加]をクリックする必要があります。 次に、次のスクリーンショットに示すように、次の変更を追加します。

リモートカタログ

現在、Apache Tapestryカタログが追加されています。 次に、以下に示すようにフィルターオプションorg.apache.tapestryクイックスタート5.4.1を選択します。

カタログを追加

次に[次へ]をクリックすると、次の画面が表示されます。

グループIDフィールド

ステップ3:GroupId、ArtifactId、バージョン、およびパッケージを構成する

Tapestryカタログの構成に次の変更を追加します。

構成の変更

次に、[完了]ボタンをクリックします。これで、最初のスケルトンアプリケーションが作成されました。 Mavenを初めて使用するときは、MavenがMaven、Jetty、Tapestryの多くのJAR依存関係をダウンロードするため、プロジェクトの作成に時間がかかる場合があります。 Mavenが終了すると、パッケージエクスプローラービューに新しいディレクトリMyFirstApplicationが表示されます。

ステップ4:Jettyサーバーを使用してアプリケーションを実行する

Mavenを使用して、Jettyを直接実行できます。 パッケージエクスプローラービューでMyFirstApplicationプロジェクトを右クリックし、[実行]→[Mavenビルド…​]を選択します。以下の画面が表示されます。

Jetty Server

構成ダイアログボックスで、ゴールオプションに「jetty:run」と入力し、[実行]ボタンをクリックします。

ゴールオプション

Jettyが初期化されると、コンソールに次の画面が表示されます。

Jetty Initialized

ステップ5:Webブラウザーで実行する

次のURLを入力して、Webブラウザーでアプリケーションを実行します–

*https://loclhost:8080/MyFirstApplication*

Webブラウザの実行

ステップ6:Jettyサーバーを停止する

Jettyサーバーを停止するには、以下に示すようにコンソールの赤い四角アイコンをクリックします。

サーバーの停止

Apacheタペストリー-プロジェクトレイアウト

以下は、 Maven Quickstart CLI によって作成されたソースコードのレイアウトです。 また、これは標準のTapestryアプリケーションの推奨レイアウトです。

├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── MyFirstApplication
│   │   │               ├── components
│   │   │               ├── data
│   │   │               ├── entities
│   │   │               ├── pages
│   │   │               └── services
│   │   ├── resources
│   │   │   ├── com
│   │   │   │   └── example
│   │   │   │       └── MyFirstApplication
│   │   │   │           ├── components
│   │   │   │           ├── logback.xml
│   │   │   │           └── pages
│   │   │   │               └── Index.properties
│   │   │   ├── hibernate.cfg.xml
│   │   │   └── log4j.properties
│   │   └── webapp
│   │       ├── favicon.ico
│   │       ├── images
│   │       │   └── tapestry.png
│   │       ├── mybootstrap
│   │       │   ├── css
│   │       │   │   ├── bootstrap.css
│   │       │   │   └── bootstrap-theme.css
│   │       │   ├── fonts
│                   ├── glyphicons-halflings-regular.eot
│   │       │   │   ├── glyphicons-halflings-regular.svg
│   │       │   │   ├── glyphicons-halflings-regular.ttf
│   │       │   │   ├── glyphicons-halflings-regular.woff
│   │       │   │   └── glyphicons-halflings-regular.woff2
│   │       │   └── js
│   │       └── WEB-INF
│   │           ├── app.properties
│   │           └── web.xml
│   ├── site
│   │   ├── apt
│   │   │   └── index.apt
│   │   └── site.xml
│   └── test
│       ├── conf
│       │   ├── testng.xml
│       │   └── webdefault.xml
│       ├── java
│       │   └── PLACEHOLDER
│       └── resources
│           └── PLACEHOLDER
└── target
   ├── classes
   │   ├── com
   │   │   └── example
   │   │       └── MyFirstApplication
   │   │           ├── components
   │   │           ├── data
   │   │           ├── entities
   │   │           ├── logback.xml
   │   │           ├── pages
   │   │           │   └── Index.properties
   │   │           └── services
   │   ├── hibernate.cfg.xml
   │   └── log4j.properties
   ├── m2e-wtp
   │   └── web-resources
   │       └── META-INF
   │           ├── MANIFEST.MF
   │           └── maven
   │               └── com.example
   │                   └──MyFirstApplication
   │                     ├── pom.properties
   │                       └── pom.xml
   ├── test-classes
   │   └── PLACEHOLDER
   └── work
      ├── jsp
      ├── sampleapp.properties
      └── sampleapp.script

デフォルトのレイアウトは、 WAR Internal File Format のように配置されます。 WAR形式を使用すると、パッケージ化およびデプロイせずにアプリケーションを実行できます。 このレイアウトは単なる提案ですが、展開中に適切なWAR形式にパッケージ化されている場合、アプリケーションは任意の形式で配置できます。

ソースコードは、次の4つの主要なセクションに分割できます。

  • * Javaコード*-すべてのJavaソースコードは /src/main/java フォルダーに配置されます。 Tapestryページクラスは「Pages」フォルダーの下に配置され、Tapestryコンポーネントクラスはcomponentsフォルダーの下に配置されます。 タペストリーサービスクラスは、servicesフォルダーの下に配置されます。
  • * ClassPathリソース*-Tapestryでは、ほとんどのクラスにリソース(XMLテンプレート、JavaScriptファイルなど)が関連付けられています。 これらのリソースは /src/main/resources フォルダーの下に配置されます。 Tapestryページクラスには「Pages」フォルダーの下に関連リソースがあり、TapestryコンポーネントクラスにはComponentsフォルダーの下に関連リソースがあります。 これらのリソースは、WARの WEB-INF/classes フォルダーにパッケージ化されています。
  • コンテキストリソース-画像、スタイルシート、JavaScriptライブラリなどのWebアプリケーションの静的リソース /モジュール。 それらは通常/src/main/webapp フォルダーの下に置かれ、 Context Resources と呼ばれます。 また、(Javaサーブレットの)Webアプリケーション記述ファイルweb.xmlは、コンテキストリソースの WEB-INF フォルダーの下に配置されます。
  • テストコード-これらはアプリケーションのテストに使用されるオプションのファイルで、 src/test/java および* src/test/ * Resourcesフォルダーの下に配置されます。 それらはWARにパッケージ化されていません。

構成より規約

Apache Tapestryは、プログラミングのあらゆる面で Convention over Configuration に従います。 フレームワークのすべての機能には、適切なデフォルトの規則があります。

たとえば、プロジェクトレイアウトの章で学習したように、すべてのページを /src/main/java/«package_path»/pages/ フォルダーに配置して、Tapestry Pagesと見なす必要があります。

別の意味では、特定のJavaクラスをTapestryページとして構成する必要はありません。 事前定義された場所にクラスを配置するだけで十分です。 場合によっては、Tapestryのデフォルトの規則に従うのは奇妙です。

たとえば、Tapestryコンポーネントには、レンダリングフェーズの開始時に起動されるメソッド setupRender を含めることができます。 開発者は、 initializeValue などの独自の省略名を使用する場合があります。 この状況では、Tapestryは*注釈*を提供して、次のコードブロックに示すように規則をオーバーライドします。

void setupRender() {
  //initialize component
}
@SetupRender
void initializeValue() {
  //initialize component
}

タペストリーでは、両方のプログラミング方法が有効です。 要するに、Tapestryのデフォルト設定はごくわずかです。 アプリケーションを適切に動作させるには、「Web.xml」で* Apache Tapestry Filter(Java Servlet Filter)*のみを構成する必要があります。

Tapestryはアプリケーションを構成する別の方法を提供し、 AppModule.java として呼び出されます。

Apacheタペストリー-注釈

注釈は、Webアプリケーション開発を簡素化するためにTapestryによって活用される非常に重要な機能です。 タペストリーは多くのカスタムアノテーションを提供します。 クラス、メソッド、およびメンバーフィールドの注釈があります。 前のセクションで説明したように、アノテーションを使用して、機能のデフォルトの規則をオーバーライドすることもできます。 タペストリーの注釈は4つの主要なカテゴリに分類され、次のとおりです。

コンポーネント注釈

Pages、Components、Mixinsクラスで使用されます。 便利な注釈のいくつかは次のとおりです-

  • @ Property -フィールドに適用可能です。 フィールドをタペストリープロパティに変換するために使用されます。
  • @ Parameter -フィールドに適用されます。 コンポーネントのパラメーターとしてフィールドを指定するために使用されます。
  • @ Environmental -フィールドに適用されます。 異なるコンポーネント間でプライベートフィールドを共有するために使用されます。
  • @ import -クラスおよびフィールドに適用できます。 アセット、CSS、およびJavaScriptを含めるために使用されます。
  • @ Path -パスに基づいてアセットを注入するために@Injectアノテーションと組み合わせて使用​​されます。
  • @ Log -クラスとフィールドに適用されます。 デバッグ目的で使用されます。 イベントの開始、イベントの終了などのコンポーネントのイベント情報を出力するために使用できます。

IoCアノテーション

IoCコンテナにオブジェクトを注入するために使用されます。 便利な注釈のいくつかは次のとおりです-

  • @ Inject -フィールドに適用できます。 IoCコンテナーに注入する必要があるパラメーターをマークするために使用されます。 コンポーネントに挿入するフィールドをマークします。
  • @ Value -フィールドに適用されます。 @injectアノテーションとともに使用して、サービス(@Injectアノテーションのデフォルトの動作)の代わりにリテラル値を注入します。

データ保持クラスの注釈

次のような高レベルのコンポーネントのクラス(通常はモデルまたはデータ保持クラス)でコンポーネント固有の情報を指定するために使用されます

  • グリッド(レポート、ギャラリーなどの高度な表形式データの作成に使用)
  • BeanEditForm (高度なフォームの作成に使用)
  • Hibernate (高度なデータベースアクセスで使用)など

これらの注釈は集約され、タペストリーに依存せずに別のjarにパッケージ化されます。 注釈のいくつかは-

  • @ DataType -これは、フィールドのデータ型を指定するために使用されます。 Tapestryコンポーネントは、この情報を使用して、プレゼンテーションレイヤーでデザインまたはマークアップを作成できます。
  • @ Validate -フィールドの検証ルールを指定するために使用されます。

これらの分離により、Tapestryアプリケーションは Multi-Tier Design を使用できます。

Apacheタペストリー-ページとコンポーネント

Tapestry Applicationは、Tapestry Pagesの単なるコレクションです。 これらは連携して、明確に定義されたWebアプリケーションを形成します。 各ページには、対応するXMLテンプレートとゼロ、1つ以上のコンポーネントがあります。 ページがルートコンポーネントであり、通常はアプリケーション開発者によって作成されることを除いて、ページとコンポーネントは同じです。

  • コンポーネントはルートPagecomponent *の子です。 Tapestryには多くの組み込みコンポーネントがあり、カスタムコンポーネントを作成するオプションがあります。

ページコンポーネント

ページ数

前に説明したように、ページはタペストリーアプリケーションの構成要素です。 ページは、- /src/main/java/«package_path»/pages/ フォルダーの下に配置された単純なPOJOです。 すべてのページには対応する* XMLテンプレート*があり、そのデフォルトの場所は- /src/main/resources/«package_name»/pages/ です。

ここでは、テンプレートが Resource Folder にあることを除いて、ページとテンプレートのパス構造が似ていることがわかります。

たとえば、パッケージ名を持つTapestryアプリケーションのユーザー登録ページ- com.example.MyFirstApplication には、次のページおよびテンプレートファイルがあります-

  • * Javaクラス*- +/src/main/java/com/example/MyFirstApplication/pages/index.java
  • * XMLテンプレート*- +/src/main/resources/com/example/MyFirstApplication/pages/index.tml

簡単な Hello World ページを作成しましょう。 まず、「/src/main/java/com/example/MyFirstApplication/pages/HelloWorld.java」に* Javaクラス*を作成する必要があります。

package com.example.MyFirstApplication.pages;
public class HelloWorld {
}

次に、次の場所でXMLテンプレートを作成します–

「/src/main/resources/com/example/MyFirstApplication/pages/helloworldl」。

<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <head>
      <title>Hello World Page</title>
   </head>
   <body>
      <h1>Hello World</h1>
   </body>
</html>

これで、このページに [[3]] からアクセスできます。 これはシンプルなタペストリーのページです。 Tapestryには、動的Webページを開発するためのより多くの機能があります。これについては、次の章で説明します。

Apacheタペストリー-テンプレート

このセクションのTapestry XMLテンプレートについて考えてみましょう。 XMLテンプレートは整形式のXMLドキュメントです。 ページのプレゼンテーション(ユーザーインターフェイス)レイヤーはXMLテンプレートです。 XMLテンプレートには、以下に示す項目に加えて、通常のHTMLマークアップがあります-

  • タペストリー名前空間
  • 拡張
  • 要素
  • コンポーネント

それらについて詳しく説明しましょう。

タペストリー名前空間

Tapestry名前空間は、XML名前空間に他なりません。 名前空間は、テンプレートのルート要素で定義する必要があります。 テンプレートにタペストリーコンポーネントとコンポーネント関連の情報を含めるために使用されます。 最も一般的に使用される名前空間は次のとおりです-

  • xmlns:t =“ [[4]] — Tapestryの要素、コンポーネント、属性を識別するために使用されます。
  • xmlns:p =“ tapestry:parameter” —コードの任意のチャンクをコンポーネントに渡すために使用されます。

タペストリー名前空間の例は次のとおりです-

<html xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_3.xsd"
   xmlns:p = "tapestry:parameter">

   <head>
      <title>Hello World Page</title>
   </head>
   <body>
      <h1>Hello World</h1>
      <t:eventlink page = "Index">refresh page</t:eventlink>
   </body>
</html>

拡張

拡張は、ページのレンダリング段階でXMLテンプレートを動的に変更するためのシンプルで効率的な方法です。 展開では、$ \ {<name>}構文を使用します。 XMLテンプレートで展開を表現する多くのオプションがあります。 最も一般的に使用されるオプションのいくつかを見てみましょう-

プロパティの拡張

対応するPageクラスで定義されたプロパティをマップします。 Javaクラスのプロパティ定義については、Java Bean仕様に準拠しています。 プロパティ名のケースを無視することで、さらに一歩進んでいます。 プロパティ展開を使用して「Hello World」の例を変更しましょう。 次のコードブロックは、変更されたPageクラスです。

package com.example.MyFirstApplication.pages;
public class HelloWorld {
  //Java Bean Property
   public String getName {
      return "World!";
   }
}

次に、対応するXMLテンプレートを次のように変更します。

<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <head>
      <title>Hello World Page</title>
   </head>
   <body>
      <!-- expansion -->
      <h1>Hello ${name}</h1>
   </body>
</html>

ここでは、Pageクラスで nameJava Bean Property として定義し、拡張 $ \ {name} を使用してXMLテンプレートで動的に処理しました。

メッセージ拡張

各ページクラスには、リソースフォルダーに*«page_name».properties *というプロパティファイルが関連付けられている場合とない場合があります。 プロパティファイルは、1行に1つのキー/値のペア(メッセージ)を持つプレーンテキストファイルです。 HelloWorld Pageのプロパティファイルを次の場所に作成します。

「/src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties」に「Greeting」メッセージを追加します。

Greeting = Hello
*Greeting* メッセージは、XMLテンプレートで *$ \ {message:greeting}* として使用できます。
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <head>
      <title>Hello World Page</title>
   </head>
   <body>
      <!-- expansion -->
      <h1>${message:greeting} ${name}</h1>
   </body>
</html>

要素

Tapestryには、XMLテンプレートで使用される要素の小さなセットがあります。 要素はTapestry名前空間の下で定義された事前定義されたタグです-

https://tapestry.apache.org/schema/tapestry_5_4.xsd

各要素は特定の目的のために作成されます。 利用可能なタペストリーの要素は次のとおりです-

<t:body>

2つのコンポーネントがネストされている場合、親コンポーネントのテンプレートは子コンポーネントのテンプレートをラップする必要があります。 <t:body>要素は、この状況で役立ちます。 <t:body>の用途の1つは、テンプレートレイアウトです。

一般に、Webアプリケーションのユーザーインターフェイスには、共通ヘッダー、フッター、メニューなどがあります。 これらの共通項目はXMLテンプレートで定義され、テンプレートレイアウトまたはレイアウトコンポーネントと呼ばれます。 Tapestryでは、アプリケーション開発者が作成する必要があります。 レイアウトコンポーネントは別のコンポーネントであり、 src/main/«java | resources»/«package_name»/components というパスを持つコンポーネントフォルダの下に配置されます。

*MyCustomLayout* という単純なレイアウトコンポーネントを作成しましょう。 MyCustomLayoutのコードは次のとおりです-
<!DOCTYPE html>
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <head>
      <meta charset = "UTF-8"/>
      <title>${title}</title>
   </head>
   <body>
      <div>Sample Web Application</div>
      <h1>${title}</h1>
      <t:body/>

      <div>(C) 2016 finddevguides.</div>
   </body>
</html>
package com.example.MyFirstApplication.components;

import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.BindingConstants;

public class MyCustomLayout {
   @Property
   @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
      private String title;
}

MyCustomLayoutコンポーネントクラスでは、タイトルフィールドを宣言し、アノテーションを使用して必須フィールドにしました。 次に、HelloWorldlテンプレートを変更して、以下のコードブロックに示すようにカスタムレイアウトを使用します。

<html>
   t:type = "mycustomlayout" title = "Hello World Test page"
      xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <h1>${message:greeting} ${name}</h1>
</html>

ここでは、XMLテンプレートにheadタグとbodyタグがないことがわかります。 Tapestryはこれらの詳細をレイアウトコンポーネントから収集し、レイアウトコンポーネントの<t:body>はHelloWorldテンプレートに置き換えられます。 すべてが完了すると、Tapestryは以下に指定されているのと同様のマークアップを出力します-

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "UTF-8"/>
      <title>Hello World Test Page</title>
   </head>
   <body>
      <div>Sample Web Application</div>
      <h1>Hello World Test Page</h1>
      <h1>Hello World!</h1>
      <div>(C) 2016 finddevguides.</div>
   </body>
</html>

レイアウトはネストできます。 たとえば、管理機能を含めることでカスタムレイアウトを拡張し、以下で指定するように管理セクションで使用できます。

<html t:type = "MyCommonLayout"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">

   <div><!-- Admin related items --><div>
   <t:body/>

</html>

<t:container>

<t:container>はトップレベルの要素であり、タペストリー名前空間が含まれています。 これは、コンポーネントの動的セクションを指定するために使用されます。

たとえば、グリッドコンポーネントには、HTMLテーブル内で行(tr(および列td))をレンダリングする方法を識別するテンプレートが必要な場合があります。

<t:container xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <td>${name}</td>
   <td>${age}</td>
</t:container>

<t:block>

<t:block>は、テンプレート内の動的セクションのプレースホルダーです。 通常、ブロック要素はレンダリングされません。 のみ、テンプレートで定義されたコンポーネントはブロック要素を使用します。 コンポーネントはデータをブロック要素に動的に注入し、レンダリングします。 一般的な使用例の1つは AJAX です。

ブロック要素は、レンダリングされる動的データの正確な位置とマークアップを提供します。 すべてのブロック要素には、対応するJavaプロパティが必要です。 その後のみ、動的にレンダリングできます。 ブロック要素のidは、Java変数識別子規則に従う必要があります。 部分的なサンプルを以下に示します。

@Inject
private Block block;
<html t:type = "mycustomlayout" title = "block example"
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
<h1>${title}</h1>
<!--
   ...
   ...
-->
<t:block t:id = "block">
   <h2>Highly dynamic section</h2>
   I'v been updated through AJAX call
   The current time is: <strong>${currentTime}</strong>
</t:block>
<!--
   ...
   ...
-->
</html>

<t:content>

<t:content>要素は、テンプレートの実際のコンテンツを指定するために使用されます。 一般に、すべてのマークアップはテンプレートの一部と見なされます。 <t:content>が指定されている場合、その中のマークアップのみが考慮されます。 この機能は、レイアウトコンポーネントなしでページを設計するためにデザイナーによって使用されます。

<t:remove>

<t:remove>は、コンテンツ要素の反対です。 remove要素内のマークアップは、テンプレートの一部とは見なされません。 サーバーのみのコメントおよび設計目的に使用できます。

資産

アセットは、スタイルシート、画像、JavaScriptファイルなどの静的リソースファイルです。 通常、アセットはWebアプリケーションのルートディレクトリ /src/main/webapp に配置されます。

<head>
   <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>

Tapestryは、* Javaクラスパス*に保存されているファイルもアセットとして扱います。 Tapestryには、拡張オプションを使用してアセットをテンプレートに含めるための高度なオプションが用意されています。

  • コンテキスト-Webコンテキストで利用可能なアセットを取得するオプション。
<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>
*asset* -コンポーネントは通常、Javaクラスとともにjarファイル内に独自のアセットを保存します。 Tapestry 5.4以降、クラスパスにアセットを保存する標準パスは *META-INF/assets* です。 ライブラリの場合、アセットを保存する標準パスは* META-INF/assets/«library_name»/です。 asset:*は、* context:*拡張を呼び出して、Webコンテキストからアセットを取得することもできます。
<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>

アセットは、InjectおよびPathアノテーションを使用してTapestryページまたはコンポーネントに挿入できます。 Pathアノテーションのパラメーターは、アセットの相対パスです。

@Inject
@Path("images/edit.png")
private Asset icon;
  • Pathパラメーター*には、 AppModule.java セクションで定義されたTapestryシンボルを含めることもできます。

たとえば、値context:skins/basicを使用してシンボルskin.rootを定義し、以下に示すように使用できます-

@Inject
@Path("${skin.root}/style.css")
private Asset style;

ローカライゼーション

タペストリーを介してリソースを含めると、追加機能が提供されます。 そのような機能の1つが「ローカリゼーション」です。 Tapestryは現在のロケールをチェックし、適切なリソースを含めます。

たとえば、現在のロケールが de に設定されている場合、edit.pngの代わりに edit_de.png が含まれます。

CSS

Tapestryには組み込みのスタイルシートのサポートがあります。 Tapestryは、 tapestry.css をコアJavaScriptスタックの一部として挿入します。 Tapestry 5.4以降、tapestryには bootstrap css framework も含まれています。 通常のリンクタグを使用して、独自のスタイルシートを含めることができます。 この場合、スタイルシートはWebルートディレクトリ( /src/main/webapp/ )にある必要があります。

<head>
   <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>

先に説明したように、Tapestryには拡張オプションによりスタイルシートをテンプレートに含めるための高度なオプションが用意されています。

<head>
   <link href = "${context:css/site.css}" rel = "stylesheet" type = "text/css"/>

Tapestryは、スタイルシートをJavaクラスに直接含めるためのインポートアノテーションも提供します。

@Import(stylesheet="context:css/site.css")
public class MyCommonLayout {
}

Tapestryには、AppModule.javaを介してスタイルシートを管理するための多くのオプションが用意されています。 重要なオプションのいくつかは次のとおりです-

  • タペストリーのデフォルトのスタイルシートは削除できます。
@Contribute(MarkupRenderer.class)

public static void
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) {
   configuration.override("InjectDefaultStyleheet", null);
}
  • ブートストラップは、パスをオーバーライドすることで無効にすることもできます。
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
*アセット(CSSおよびJavaScript)の動的な最小化を有効にします。* tapestry-webresources *依存関係(pom.xml内)も含める必要があります。
@Contribute(SymbolProvider.class)
@ApplicationDefaults

public static void contributeApplicationDefaults(
   MappedConfiguration<String, String> configuration) {

   configuration.add(SymbolConstants.MINIFICATION_ENABLED, "true");
}

<dependency>
   <groupId>org.apache.tapestry</groupId>
   <artifactId>tapestry-webresources</artifactId>
   <version>5.4</version>
</dependency>

クライアント側のJavaScript

現在の世代のWebアプリケーションは、豊富なクライアントサイドエクスペリエンスを提供するためにJavaScriptに大きく依存しています。 Tapestryはそれを認め、JavaScriptのファーストクラスのサポートを提供します。 JavaScriptのサポートはタペストリーに深く根付いており、プログラミングのあらゆる段階で利用できます。

以前、TapestryはPrototypeとScriptaculousのみをサポートしていました。 しかし、バージョン5.4から、タペストリーはJavaScriptレイヤーを完全に書き直して、可能な限り汎用的にし、JavaScriptのデファクトライブラリであるJQueryのファーストクラスサポートを提供しています。 また、タペストリーはモジュールベースのJavaScriptプログラミングを推奨し、AMDの一般的なクライアント側実装であるRequireJSをサポートします(非同期モジュール定義-モジュールとその依存関係を非同期でサポートするJavaScript仕様)。

ロケーション

JavaScriptファイルはTapestryアプリケーションのアセットです。 アセットルールに従って、JavaScriptファイルはWebコンテキスト /sr/main/webapp/ の下に配置されるか、jar内の META-INF/assets/location の下に配置されます。

JavaScriptファイルのリンク

XMLテンプレートでJavaScriptファイルをリンクする最も簡単な方法は、scriptタグを直接使用することです。これは、 <script language = "javascript" src = "relative/path/to/js"> </script> です。 しかし、タペストリーはこれらのアプローチを推奨していません。 Tapestryには、ページ/コンポーネント自体でJavaScriptファイルをリンクするためのオプションがいくつか用意されています。 これらのいくつかを以下に示します。

  • * @ importアノテーション*-@importアノテーションは、コンテキスト式を使用して複数のJavaScriptライブラリをリンクするオプションを提供します。 Pageクラスとそのメソッドの両方に適用できます。 Pageクラスに適用される場合、すべてのメソッドに適用されます。 ページのメソッドに適用された場合、そのメソッドにのみ適用され、メソッドが呼び出されたときにのみTapestryはJavaScriptライブラリをリンクします。
@Import(library = {"context:js/jquery.js","context:js/myeffects.js"})

public class MyComponent {
  //...
}
  • * JavaScriptSupportインターフェイス*-JavaScriptSupportはタペストリーで定義されたインターフェイスで、JavaScriptファイルをインポートする importJavaScriptLibrary メソッドがあります。 JavScriptSupportオブジェクトは、@ Environmental注釈を宣言して注釈を付けるだけで簡単に作成できます。
@Inject @Path("context:/js/myeffects.js")
private Asset myEffects;

@Environmental
private JavaScriptSupport javaScriptSupport;
void setupRender() {
   javaScriptSupport.importJavaScriptLibrary(myEffects);
}
  • JavaScripSupportは、 @ Environmental アノテーションを使用してのみコンポーネントに注入できます。 サービスについては、 @ Inject アノテーションを使用するか、サービスコンストラクターメソッドの引数として追加する必要があります。
@Inject
private JavaScriptSupport javaScriptSupport;
public MyServiceImpl(JavaScriptSupport support) {
  //...
}
  • * addScriptメソッド*-これはJavaScriptSupportインターフェイスに似ていますが、 addScript メソッドを使用し、ページの下部の出力にコードが直接追加される点が異なります。
void afterRender() {
   javaScriptSupport.addScript(
      "$('%s').observe('click', hideMe());", container.getClientId());
}

JavaScriptスタック

Tapestryでは、JavaScriptファイルのグループと関連するスタイルシートを組み合わせて、1つのエンティティとして使用できます。 現在、TapestryにはPrototypeベースおよびJQueryベースのスタックが含まれています。

開発者は、 JavaScriptStack インターフェイスを実装して独自のスタックを開発し、 AppModule.java に登録できます。 登録したら、 @ import アノテーションを使用してスタックをインポートできます。

@Contribute(JavaScriptStackSource.class)
public static void addMyStack(
   MappedConfiguration<String, JavaScriptStack> configuration) {

   configuration.addInstance("MyStack", myStack.class);
}

@Import(stack = "MyStack")
public class myPage {
}

Apacheタペストリー-コンポーネント

前述のように、コンポーネントとページは同じです。ただし、ページはルートコンポーネントであり、1つ以上の子コンポーネントが含まれます。 コンポーネントは常にページ内に常駐し、ページのほぼすべての動的機能を実行します。

Tapestryコンポーネントは、*インタラクティブAJAX *を使用して、複雑なグリッド機能への単純なHTMLリンクをレンダリングします。 コンポーネントには別のコンポーネントも含めることができます。 タペストリーのコンポーネントは、次の項目で構成されています-

  • Component Class -コンポーネントのメインJavaクラス。
  • * XMLテンプレート*-XMLテンプレートはページテンプレートに似ています。 コンポーネントクラスは、テンプレートを最終出力としてレンダリングします。 一部のコンポーネントにはテンプレートがありません。 この場合、出力は MarkupWriter クラスを使用してコンポーネントクラス自体によって生成されます。
  • Body -ページテンプレート内で指定されたコンポーネントにはカスタムマークアップが含まれている場合があり、「コンポーネントボディ」と呼ばれます。 コンポーネントテンプレートに <body/> 要素がある場合、<body/>要素はコンポーネントの本文に置き換えられます。 これは、前述のXMLテンプレートセクションで説明したレイアウトに似ています。
  • レンダリング-レンダリングは、XMLテンプレートとコンポーネントの本体をコンポーネントの実際の出力に変換するプロセスです。
  • パラメータ-コンポーネントとページ間の通信を作成し、それらの間でデータを渡すために使用されます。
  • イベント-コンポーネントからコンテナ/親(ページまたは別のコンポーネント)に機能を委任します。 ページナビゲーションの目的で広く使用されています。

レンダリング

コンポーネントのレンダリングは、一連の事前定義されたフェーズで行われます。 コンポーネントシステムの各フェーズには、コンポーネントクラスの規則または注釈によって定義された対応するメソッドが必要です。

//Using annotaion
@SetupRender
void initializeValues() {
  //initialize values
}

//using convention
boolean afterRender() {
  //do logic
   return true;
}

フェーズ、そのメソッド名、および注釈を以下にリストします。

Annotation Default Method Names
@SetupRender setupRender()
@BeginRender beginRender()
@BeforeRenderTemplate beforeRenderTemplate()
@BeforeRenderBody beforeRenderBody()
@AfterRenderBody afterRenderBody()
@AfterRenderTemplate afterRenderTemplate()
@AfterRender afterRender()
@CleanupRender cleanupRender()

各フェーズには特定の目的があり、次のとおりです-

SetupRender

SetupRenderは、レンダリングプロセスをキックスタートします。 通常、コンポーネントのパラメーターを設定します。

BeginRender

BeginRenderは、コンポーネントのレンダリングを開始します。 通常、コンポーネントの開始/開始タグをレンダリングします。

BeforeRenderTemplate

BeforeRenderTemplateは、XMLテンプレートを装飾するために使用され、テンプレートの周りに特別なマークアップを追加します。 また、テンプレートのレンダリングをスキップするオプションも提供します。

BeforeRenderBody

BeforeRenderTemplateには、コンポーネントのbody要素のレンダリングをスキップするオプションがあります。

AfterRenderBody

AfterRenderBodyは、コンポーネントのボディがレンダリングされた後に呼び出されます。

AfterRenderTemplate

AfterRenderTemplateは、コンポーネントのテンプレートがレンダリングされた後に呼び出されます。

AfterRender

AfterRenderはBeginRenderの対応物であり、通常は終了タグをレンダリングします。

CleanupRender

CleanupRenderは、SetupRenderに対応しています。 レンダリングプロセス中に作成されたすべてのオブジェクトを解放/破棄します。

レンダリングフェーズのフローは順方向だけではありません。 フェーズの戻り値に応じて、フェーズ間を行き来します。

たとえば、SetupRenderメソッドがfalseを返す場合、レンダリングはCleanupRenderフェーズにジャンプし、その逆も同様です。 異なるフェーズ間のフローを明確に理解するには、下の図のフローを確認してください。

注釈リスト

単純なコンポーネント

「Hello、Tapestry」という出力メッセージを持つ単純なコンポーネントHelloを作成しましょう。 Helloコンポーネントとそのテンプレートのコードは次のとおりです。

package com.example.MyFirstApplication.components;
public class Hello {
}
<html
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <div>
      <p>Hello, Tapestry (from component).</p>
   </div>

</html>

Helloコンポーネントは、ページテンプレートで次のように呼び出すことができます-

<html title = "Hello component test page"
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
<t:hello/>
</html>

同様に、コンポーネントは、次に示すように、テンプレートの代わりにMarkupWriterを使用して同じ出力をレンダリングする場合があります。

package com.example.MyFirstApplication.components;

import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.BeginRender;

public class Hello {
   @BeginRender
   void renderMessage(MarkupWriter writer) {
      writer.write("<p>Hello, Tapestry (from component)</p>");
   }
}

コンポーネントテンプレートを変更し、次のコードブロックに示すように<body/>要素を含めます。

<html>
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <div>
      <t:body/>
   </div>
</html>

これで、以下に示すように、ページテンプレートのコンポーネントマークアップに本文が含まれることがあります。

<html title = "Hello component test page"
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <t:hello>
      <p>Hello, Tapestry (from page).</p>
   </t:hello>
</html>

出力は次のようになります-

<html>
   <div>
      <p>Hello, Tapestry (from page).</p>
   </div>
</html>

パラメーター

これらのパラメーターの主な目的は、コンポーネントのフィールドとページのプロパティ/リソース間の接続を作成することです。 パラメータを使用して、コンポーネントとその対応するページが相互に通信し、データを転送します。 これは Two Way Data Binding と呼ばれます。

たとえば、ユーザー管理ページで年齢を表すために使用されるテキストボックスコンポーネントは、パラメーターを通じてその初期値(データベースで利用可能)を取得します。 繰り返しますが、ユーザーの年齢が更新されて送信された後、コンポーネントは同じパラメーターを使用して更新された年齢を送り返します。

コンポーネントクラスで新しいパラメーターを作成するには、フィールドを宣言し、 @ Parameter アノテーションを指定します。 この@Parameterには2つのオプションの引数があります。

  • 必須-パラメータを必須として設定します。 タペストリーが提供されない場合、例外が発生します。
  • -パラメータのデフォルト値を指定します。

パラメータは、ページテンプレートでコンポーネントタグの属性として指定する必要があります。 属性の値は、前の章で説明したバインディング式/拡張を使用して指定する必要があります。 以前に学んだ拡張の一部は次のとおりです-

  • プロパティ展開(prop:«val»)-ページクラスのプロパティからデータを取得します。
  • メッセージ展開(message:«val»)-index.propertiesファイルで定義されたキーからデータを取得します。
  • コンテキスト展開(context:«val»)-Webコンテキストフォルダ/src/main/webappからデータを取得します。
  • アセットの展開(asset:«val»)-jarファイル/META-INF/assetsに埋め込まれたリソースからデータを取得します。
  • シンボル展開(シンボル:«val»)-AppModule.javafileで定義されているシンボルからデータを取得します。

タペストリーには、より多くの便利な拡張機能があり、その一部を以下に示します-

  • リテラル展開(literal:«val»)-リテラル文字列。
  • 変数展開(var:«val»)-コンポーネントのレンダー変数の読み取りまたは更新を許可します。
  • * Validate expansion(validate:«val»)*-オブジェクトの検証ルールを指定するために使用される特殊な文字列。 たとえば、validate:required、minLength = 5。
  • * Translate(translate:«val»)*-入力検証でTranslatorクラス(クライアント側からサーバー側への変換)を指定するために使用されます。
  • * Block(block:«val»)*-テンプレート内のブロック要素のID。
  • * Component(component:«val»)*-テンプレート内の別のコンポーネントのID。

プロパティの展開とVarの展開を除き、上記の展開はすべて読み取り専用です。 それらは、ページとデータを交換するためにコンポーネントによって使用されます。 属性値として展開を使用する場合、 $ \ {…​} は使用しないでください。 代わりに、ドル記号とブレース記号なしの展開を使用します。

パラメータを使用するコンポーネント

コンポーネントクラスに name パラメータを追加し、それに応じてコンポーネントテンプレートとページテンプレートを変更することにより、メッセージを動的にレンダリングするようにHelloコンポーネントを変更して、新しいコンポーネントHelloWithParameterを作成しましょう。

  • 新しいコンポーネントクラス HelloWithParameter.java を作成します。
  • プライベートフィールドを追加し、 @ Parameter アノテーションを付けて名前を付けます。 必須の引数を使用して必須にします。
@Parameter(required = true)
private String name;
  • @ Propery アノテーションを使用して、プライベートフィールドを追加します。 結果のプロパティは、コンポーネントテンプレートで使用されます。 コンポーネントテンプレートは、 @ Parameter アノテーションが付けられたフィールドにはアクセスできず、 @ Property アノテーションが付けられたフィールドにのみアクセスできます。 コンポーネントテンプレートで使用できる変数は、レンダリング変数と呼ばれます。
@Property
 private String result;
  • RenderBodyメソッドを追加し、nameパラメーターの値をresultプロパティにコピーします。
@BeginRender
void initializeValues() {
   result = name;
}
  • 新しいコンポーネントテンプレート HelloWithParamter.tml を追加し、resultプロパティを使用してメッセージをレンダリングします。
<div> Hello, ${result} </div>
  • テストページ(testhello.java)に新しいプロパティUsernameを追加します。
public String getUsername() {
   return "User1";
}
  • ページテンプレートで新しく作成されたコンポーネントを使用し、 HelloWithParameter コンポーネントのnameパラメーターでUsernameプロパティを設定します。
<t:helloWithParameter name = "username"/>

完全なリストは次のとおりです-

package com.example.MyFirstApplication.components;

import org.apache.tapestry5.annotations.*;
public class HelloWithParameter {
   @Parameter(required = true)
   private String name;

   @Property
   private String result;

   @BeginRender
   void initializeValues() {
      result = name;
   }
}
<html
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <div> Hello, ${result} </div>

</html>
package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.*;
public class TestHello {
   public String getUsername() {
      return "User1";
   }
}
<html title = "Hello component test page"
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
   <t:helloWithParameter name = "username"/>

</html>

結果は次のようになります-

<div> Hello, User1 </div>

拡張パラメーター

前の章では、カスタムコンポーネントで単純なパラメーターを作成して使用する方法を分析しました。 拡張パラメータには、完全なマークアップも含まれる場合があります。 この場合、ページテンプレートのサブセクションなどのコンポーネントタグ内でマークアップを指定する必要があります。 組み込みのifコンポーネントには、成功条件と失敗条件の両方のマークアップがあります。 成功のマークアップはコンポーネントタグの本体として指定され、失敗のマークアップは elseparameter を使用して指定されます。

*if* コンポーネントの使用方法を見てみましょう。 ifコンポーネントには2つのパラメータがあります-
  • test -単純なプロパティベースのパラメーター。
  • Else -条件が失敗した場合に代替マークアップを指定するために使用される高度なパラメーター

Tapestryは、次のロジックを使用してテストプロパティの値をチェックし、trueまたはfalseを返します。 これは Type Coercion と呼ばれ、あるタイプのオブジェクトを同じコンテンツを持つ別のタイプに変換する方法です。

  • データ型が String の場合、リテラル文字列「False」ではなく、空白でない場合は「True」(大文字と小文字は区別されません)。
  • データ型が Number の場合、ゼロ以外の場合はTrue。
  • データ型が Collection の場合、空でない場合はTrue。
  • データ型が Object の場合、True(nullでない場合)。

条件が満たされると、コンポーネントはその本体をレンダリングします。それ以外の場合は、elseパラメーターの本体をレンダリングします。

完全なリストは次のとおりです-

package com.example.MyFirstApplication.pages;
public class TestIf {
   public String getUser() {
      return "User1";
   }
}
<html title = "If Test Page"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <body>
      <h1>Welcome!</h1>
      <t:if test = "user">
         Welcome back, ${user}
         <p:else>
            Please <t:pagelink page = "login">Login</t:pagelink>
         </p:else>
      </t:if>
   </body>

</html>

コンポーネントイベント/ページナビゲーション

タペストリーアプリケーションは、相互作用する*ページのコレクション*です。 これまで、個々のページ間で通信を行わずにページを作成する方法を学びました。 コンポーネントイベントの主な目的は、サーバー側イベントを使用してページ間(ページ内でも)の対話を提供することです。 コンポーネントイベントのほとんどは、クライアント側のイベントから発生します。

たとえば、ユーザーがページ内のリンクをクリックすると、Tapestryはターゲットページを呼び出すのではなく、ターゲット情報を使用して同じページ自体を呼び出し、サーバー側イベントを発生させます。 タペストリーページはイベントをキャプチャし、ターゲット情報を処理し、ターゲットページへのサーバー側のリダイレクトを行います。

タペストリーは、ページナビゲーションの* Post/Redirect/Get(RPG)デザインパターン*に従います。 RPGでは、ユーザーがフォームを送信して投稿要求を行うと、サーバーは投稿されたデータを処理しますが、応答を直接返しません。 代わりに、別のページへのクライアント側のリダイレクトを行い、結果を出力します。 RPGパターンは、ブラウザーの戻るボタン、ブラウザーの更新ボタンなどによるフォームの重複送信を防ぐために使用されます。Tapestryは、次の2種類のリクエストを提供することでRPGパターンを提供します。

  • コンポーネントイベントリクエスト-このタイプのリクエストは、ページ内の特定のコンポーネントを対象とし、コンポーネント内でイベントを発生させます。 このリクエストはリダイレクトのみを行い、レスポンスは出力しません。
  • リクエストのレンダリング-これらのタイプのリクエストはページを対象とし、クライアントにレスポンスをストリーミングします。

コンポーネントイベントとページナビゲーションを理解するには、タペストリーリクエストのURLパターンを知る必要があります。 両方のタイプのリクエストのURLパターンは次のとおりです-

  • コンポーネントイベントリクエスト-
/<<page_name_with_path>>.<<component_id|event_id>>/<<context_information>>
  • リクエストのレンダリング-
/<<page_name_with_path>>/<<context_information>>

URLパターンの例のいくつかは次のとおりです-

  • インデックスページは、 [[5]] でリクエストできます。
  • インデックスページがサブフォルダ管理者の下で利用できる場合、 [[6]] によってリクエストできます。
  • ユーザーがインデックスページで id test の* ActionLinkコンポーネントをクリックすると、URLは* [[7]]

イベント

デフォルトでは、Tapestryはすべてのリクエストに対して OnPassivate および OnActivate イベントを発生させます。 コンポーネントイベントリクエストタイプの場合、tapestryはコンポーネントに応じて追加の1つ以上のイベントを発生させます。 ActionLinkコンポーネントはActionイベントを発生させ、Formコンポーネントは Validate、Success などの複数のイベントを発生させます。

イベントは、対応するメソッドハンドラーを使用してページクラスで処理できます。 メソッドハンドラーは、メソッドの命名規則または @ OnEvent アノテーションを使用して作成されます。 メソッドの命名規則の形式は、* On«EventName»From«ComponentId»*です。

  • idテスト*を持つActionLinkコンポーネントのアクションイベントは、次のいずれかの方法で処理することができます-
void OnActionFromTest() {
}
@OnEvent(component = "test", name = "action")
void CustomFunctionName() {
}

メソッド名に特定のコンポーネントがない場合、一致するイベントを持つすべてのコンポーネントに対してメソッドが呼び出されます。

void OnAction() {
}

OnPassivateおよびOnActivateイベント

OnPassivateは、OnActivateイベントハンドラーのコンテキスト情報を提供するために使用されます。 一般に、Tapestryはコンテキスト情報を提供し、OnActivateeventハンドラーの引数として使用できます。

たとえば、コンテキスト情報がint型の3である場合、OnActivateイベントは次のように呼び出すことができます-

void OnActivate(int id) {
}

シナリオによっては、コンテキスト情報が利用できない場合があります。 この状況では、OnPassivateイベントハンドラーを使用して、コンテキスト情報をOnActivateイベントハンドラーに提供できます。 OnPassivateイベントハンドラの戻り値の型は、OnActivateイベントハンドラの引数として使用する必要があります。

int OnPassivate() {
   int id = 3;
   return id;
}
void OnActivate(int id) {
}

イベントハンドラーの戻り値

Tapestryは、イベントハンドラーの戻り値に基づいてページリダイレクトを発行します。 イベントハンドラは、次の値のいずれかを返す必要があります。

  • ヌル応答-ヌル値を返します。 Tapestryは現在のページURLを作成し、リダイレクトとしてクライアントに送信します。
public Object onAction() {
   return null;
}
  • 文字列応答-文字列値を返します。 Tapestryは、値に一致するページのURLを構築し、リダイレクトとしてクライアントに送信します。
public String onAction() {
   return "Index";
}
  • クラス応答-ページクラスを返します。 Tapestryは、返されたページクラスのURLを構築し、リダイレクトとしてクライアントに送信します。
public Object onAction() {
   return Index.class
}
  • ページ応答-@InjectPageで注釈されたフィールドを返します。 Tapestryは、挿入されたページのURLを作成し、リダイレクトとしてクライアントに送信します。
@InjectPage
private Index index;

public Object onAction(){
   return index;
}
  • HttpError -HTTPErrorオブジェクトを返します。 Tapestryはクライアント側のHTTPエラーを発行します。
public Object onAction(){
   return new HttpError(302, "The Error message);
}
  • リンク応答-リンクインスタンスを直接返します。 Tapestryは、LinkオブジェクトからURLを構築し、リダイレクトとしてクライアントに送信します。
  • Stream Response - StreamResponse オブジェクトを返します。 Tapestryは、クライアントブラウザーに直接応答としてストリームを送信します。 レポートと画像を直接生成し、クライアントに送信するために使用されます。
  • Url Response - java.net.URL オブジェクトを返します。 Tapestryは、オブジェクトから対応するURLを取得し、リダイレクトとしてクライアントに送信します。
  • オブジェクト応答-上記の指定値以外の値を返します。 タペストリーはエラーを発生させます。

イベントコンテキスト

一般に、イベントハンドラーは引数を使用してコンテキスト情報を取得できます。 たとえば、コンテキスト情報がタイプintの3である場合、イベントハンドラは次のようになります-

Object onActionFromTest(int id) {
}

Tapestryはコンテキスト情報を適切に処理し、引数を介してメソッドに提供します。 場合によっては、プログラミングの複雑さのためにTapestryが適切に処理できないことがあります。 その時点で、完全なコンテキスト情報を取得し、自分で処理する場合があります。

Object onActionFromEdit(EventContext context) {
   if (context.getCount() > 0) {
      this.selectedId = context.get(0);
   } else {
      alertManager.warn("Please select a document.");
      return null;
   }
}

Apache Tapestry-組み込みコンポーネント

この章では、Tapestryに組み込まれているコンポーネントについて、適切な例を使用して説明します。 Tapestryは65以上の組み込みコンポーネントをサポートしています。 カスタムコンポーネントを作成することもできます。 注目すべきコンポーネントのいくつかを詳細に説明しましょう。

Ifコンポーネント

ifコンポーネントは、ブロックを条件付きでレンダリングするために使用されます。 条件はテストパラメーターによってチェックされます。

以下に示すように、 IfSample.java ページを作成します-

package com.example.MyFirstApplication.pages;

public class Ifsample {
   public String getUser() {
      return "user1";
   }
}

今、次のように対応するテンプレートファイルを作成します-

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <h3>If-else component example </h3>
   <t:if test = "user">
      Hello ${user}
      <p:else>
         <h4> You are not a Tapestry user </h4>
      </p:else>
   </t:if>
</html>

ページをリクエストすると、次のように結果がレンダリングされます。

結果-http://localhost:8080/MyFirstApplication/ifsample

Ifコンポーネントの結果

除外コンポーネントと委任コンポーネント

  • unlessコンポーネント*は、上記で説明したifコンポーネントのちょうど反対です。 一方、* delegateコンポーネント*はそれ自体ではレンダリングを行いません。 代わりに、通常、マークアップをブロック要素に委任します。 コンポーネントがデリゲートとブロックを使用して動的コンテンツを条件付きで交換できる場合を除きます。

次のようにページ Unless.java を作成します。

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.Block;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Persist;

public class Unless {
   @Property
   @Persist(PersistenceConstants.FLASH)
   private String value;
   @Property
   private Boolean bool;
   @Inject
   Block t, f, n;

   public Block getCase() {
      if (bool == Boolean.TRUE ) {
         return t;
      } else {
         return f;
      }
   }
}

今、次のように対応するテンプレートファイルを作成します-

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <h4> Delegate component </h4>
   <div class = "div1">
      <t:delegate to = "case"/>
   </div>
   <h4> If-Unless component </h4>

   <div class = "div1">
      <t:if test = "bool">
         <t:delegate to = "block:t"/>
      </t:if>
      <t:unless test = "bool">
         <t:delegate to = "block:notT"/>
      </t:unless>
   </div>

   <t:block id = "t">
      bool == Boolean.TRUE.
   </t:block>

   <t:block id = "notT">
      bool = Boolean.FALSE.
   </t:block>

   <t:block id = "f">
      bool == Boolean.FALSE.
   </t:block>
</html>

ページをリクエストすると、次のように結果がレンダリングされます。

結果-http://localhost:8080/MyFirstApplication/unless

デリゲートコンポーネント

ループコンポーネント

ループコンポーネントは、コレクションアイテムをループ処理し、値/反復ごとにボディをレンダリングする基本コンポーネントです。

以下に示すように、ループページを作成します-

Loop.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
public class Loop {
   @Property
   private int i;
}

次に、対応するテンプレートLoop.tmlを作成します

Loop.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <p>This is sample parameter rendering example...</p>
   <ol>
      <li t:type = "loop" source = "1..5" value = "var:i">${var:i}</li>
   </ol>
</html>

ループコンポーネントには次の2つのパラメータがあります-

  • source -コレクションのソース。 1…5は、指定された範囲の配列を作成するために使用されるプロパティ拡張です。
  • var -レンダリング変数。 テンプレートの本文に現在の値をレンダリングするために使用されます。

ページを要求すると、以下に示すように結果がレンダリングされます-

ループコンポーネント

PageLinkコンポーネント

PageLinkコンポーネントは、あるページから別のページにページをリンクするために使用されます。 以下のようにPageLinkテストページを作成します- PageLink.java

package com.example.MyFirstApplication.pages;
   public class PageLink {
}

次に、以下に示すように、対応するテンプレートファイルを作成します-

PageLink.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <body>
      <h3><u>Page Link</u> </h3>
      <div class = "page">
         <t:pagelink page = "Index">Click here to navigate Index page</t:pagelink>
         <br/>
      </div>
   </body>

</html>

PageLinkコンポーネントには、ターゲットのタペストリーページを参照するページパラメーターがあります。

結果-http://localhost:8080/myFirstApplication/pagelink

ページリンク

EventLinkコンポーネント

EventLinkコンポーネントは、URLを介してイベント名と対応するパラメーターを送信します。 以下に示すように、EventsLinkページクラスを作成します。

EventsLink.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
public class EventsLink {
   @Property
   private int x;
   void onActivate(int count) {
      this.x = x;
   }
   int onPassivate() {
      return x;
   }
   void onAdd(int value) {
      x += value;
   }
}

次に、対応する「EventsLink」テンプレートファイルを次のように作成します-

EventsLink.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <h3> Event link example </h3>
   AddedCount = ${x}. <br/>
   <t:eventlink t:event = "add" t:context = "literal:1">
      Click here to add count
   </t:eventlink><br/>
</html>

EventLinkには次の2つのパラメータがあります-

  • Event -EventLinkコンポーネントでトリガーされるイベントの名前。 デフォルトでは、コンポーネントのIDを指します。
  • コンテキスト-オプションのパラメータです。 リンクのコンテキストを定義します。

結果-http://localhost:8080/myFirstApplication/EventsLink

イベントリンク

カウント値をクリックすると、次の出力スクリーンショットに示すように、ページのURLにイベント名が表示されます。

イベントリンク結果

ActionLinkコンポーネント

ActionLinkコンポーネントはEventLinkコンポーネントに似ていますが、ターゲットコンポーネントIDのみを送信します。 デフォルトのイベント名はactionです。

以下に示すページ「ActivationLinks.java」を作成します。

ActivationLinks.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
public class ActivationLinks {
   @Property
   private int x;
   void onActivate(int count) {
      this.x = x;
   }
   int onPassivate() {
      return x;
   }
   void onActionFromsub(int value) {
      x -= value;
   }
}

次に、以下に示すように、対応するテンプレートファイルを作成します-

ActivationLinks.tml

<html t:type = "Newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <div class = "div1">
      Count = ${count}. <br/>
      <t:actionlink t:id = "sub" t:context = "literal:1">
         Decrement
      </t:actionlink><br/>
   </div>

</html>

ここで、ActionLinkコンポーネントをクリックすると、 OnActionFromSub メソッドが呼び出されます。

結果-http://localhost:8080/myFirstApplication/ActivationsLink

アクションリンク

アラートコンポーネント

警告ダイアログボックスは、主にユーザーに警告メッセージを表示するために使用されます。 たとえば、入力フィールドに必須のテキストが必要であるが、ユーザーが入力を提供しない場合、検証の一部として、警告ボックスを使用して警告メッセージを表示できます。

次のプログラムに示すように、ページ「アラート」を作成します。

Alerts.java

package com.example.MyFirstApplication.pages;

public class Alerts {
   public String getUser() {
      return "user1";
   }
}

次に、次のように対応するテンプレートファイルを作成します-

Alerts.tml

<html t:type = "Newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <h3>Alerts</h3>
   <div class = "alert alert-info">
      <h5> Welcome ${user} </h5>
   </div>

</html>

アラートには3つの重大度レベルがあります。

  • Info
  • Warn *エラー

上記のテンプレートは、情報アラートを使用して作成されます。* alert-info *として定義されています。 必要に応じて、他の重大度を作成できます。

ページを要求すると、次の結果が生成されます-

*http://localhost:8080/myFirstApplication/Alerts*

アラート

フォームと検証コンポーネント

*Form Component* は、ユーザー入力用のタペストリーページにフォームを作成するために使用されます。 フォームには、テキストフィールド、日付フィールド、チェックボックスフィールド、選択オプション、送信ボタンなどを含めることができます。

この章では、いくつかの重要なフォームコンポーネントについて詳しく説明します。

チェックボックスコンポーネント

チェックボックスコンポーネントは、相互に排他的な2つのオプションから選択するために使用されます。 以下に示すように、チェックボックスを使用してページを作成します-

Checkbox.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;

public class Checkbox {
   @Property
   private boolean check1;

   @Property
   private boolean check2;
}

次に、以下に示すように、対応するテンプレート Checkbox.tml を作成します-

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <h3> checkbox component</h3>
   <t:form>
      <t:checkbox t:id = "check1"/> I have a bike <br/>
      <t:checkbox t:id = "check2"/> I have a car
   </t:form>

</html>

ここでは、チェックボックスパラメータIDは、対応するブール値と一致します。

結果-ページ、http://localhost:8080/myFirstApplication/checkboxをリクエストすると、次の結果が生成されます。

チェックボックス

TextFieldコンポーネント

TextFieldコンポーネントを使用すると、ユーザーは1行のテキストを編集できます。 以下に示すように、ページ*テキスト*を作成します。

Text.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.TextField;public class Text {
   @Property
   private String fname;
   @Property
   private String lname;
}

次に、以下に示すように対応するテンプレートを作成します– Text.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
   <p> Form application </p>

   <body>
      <h3> Text field created from Tapestry component </h3>
      <t:form>
         <table>
            <tr>
               <td>
                  Firstname: </td> <td><t:textfield t:id = "fname"/>
               </td>
               <td>Lastname: </td> <td> <t:textfield t:id = "lname"/> </td>
            </tr>
         </table>
      </t:form>
   </body>

</html>

ここでは、テキストページに fname および lname という名前のプロパティが含まれています。 コンポーネントIDは、プロパティによってアクセスされます。

ページを要求すると、次の結果が生成されます-

*http://localhost:8080/myFirstApplication/Text*

テキストフィールド

PasswordFieldコンポーネント

PasswordFieldは、パスワード用の特殊なテキストフィールドエントリです。 以下に示すようにページのパスワードを作成します-

Password.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.PasswordField;

public class Password {
   @Property
   private String pwd;
}

さて、対応するテンプレートファイルを作成すると、次のようになります-

Password.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
   <p> Form application </p>
   <h3> Password field created from Tapestry component </h3>

   <t:form>
      <table>
         <tr>
            <td> Password: </td>
            <td><t:passwordfield t:id = "pwd"/> </td>
         </tr>
      </table>
   </t:form>

</html>

ここで、PasswordFieldコンポーネントには、プロパティ pwd を指すパラメーターidがあります。 ページを要求すると、次の結果が生成されます-

*http://localhost:8080/myFirstApplication/Password*

パスワードフィールド

TextAreaコンポーネント

TextAreaコンポーネントは、複数行の入力テキストコントロールです。 以下に示すように、ページTxtAreaを作成します。

TxtArea.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.TextArea;

public class TxtArea {
   @Property
   private String str;
}

次に、対応するテンプレートファイルを以下のように作成します。

TxtArea.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
   <h3>TextArea component </h3>

   <t:form>
      <table>
         <tr>
            <td><t:textarea t:id = "str"/>
            </td>
         </tr>
      </table>
   </t:form>

</html>

ここでは、TextAreaコンポーネントのパラメーターidはプロパティ「str」を指します。 ページを要求すると、次の結果が生成されます-

*http://localhost:8080/myFirstApplication/TxtArea* **

テキストエリアコンポーネント

コンポーネントを選択

選択コンポーネントには、選択肢のドロップダウンリストが含まれています。 以下に示すように、ページSelectOptionを作成します。

SelectOption.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Select;

public class SelectOption {
   @Property
   private String color0;

   @Property

   private Color1 color1;
   public enum Color1 {
      YELLOW, RED, GREEN, BLUE, ORANGE
   }
}

次に、対応するテンプレートを作成します次のとおりです-

SelectOption.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
   <p> Form application </p>
   <h3> select component </h3>

   <t:form>
      <table>
         <tr>
            <td> Select your color here: </td>
            <td> <select t:type = "select" t:id = "color1"></select></td>
         </tr>
      </table>
   </t:form>

</html>

ここでは、選択コンポーネントには2つのパラメータがあります-

  • Type -プロパティのタイプは列挙型です。
  • Id -IDはTapestryプロパティ「color1」を指します。

ページを要求すると、次の結果が生成されます-

*http://localhost:8080/myFirstApplication/SelectOption*

コンポーネントの選択

RadioGroupコンポーネント

RadioGroupコンポーネントは、Radioコンポーネントのコンテナグループを提供します。 RadioおよびRadioGroupコンポーネントは連携して、オブジェクトのプロパティを更新します。 このコンポーネントは、他の無線コンポーネントをラップする必要があります。 以下に示すように、新しいページ「Radiobutton.java」を作成します-

Radiobutton.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;

public class Radiobutton {
   @Property
   @Persist(PersistenceConstants.FLASH)
   private String value;
}

次に、対応するテンプレートファイルを作成します。以下に示します-

Radiobutton.tml

<html t:type = "Newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
   <h3>RadioGroup component </h3>

   <t:form>
      <t:radiogroup t:id = "value">
         <t:radio t:id = "radioT" value = "literal:T" label = "Male"/>
         <t:label for = "radioT"/>  
         <t:radio t:id = "radioF" value = "literal:F" label = "Female"/>
         <t:label for = "radioF"/>  
      </t:radiogroup>
   </t:form>

</html>

ここでは、RadioGroupコンポーネントIDがプロパティ「値」とバインドしています。 ページをリクエストすると、次の結果が生成されます。

*http://localhost:8080/myFirstApplication/Radiobutton*

ラジオグループ

コンポーネントを送信

ユーザーが送信ボタンをクリックすると、タグのアクション設定で指定されたアドレスにフォームが送信されます。 以下に示すように、ページ SubmitComponent を作成します。

package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.InjectPage;

public class SubmitComponent {
   @InjectPage
   private Index page1;
   Object onSuccess() {
      return page1;
   }
}

次に、以下に示すように、対応するテンプレートファイルを作成します。

SubmitComponent.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">
   <h3>Tapestry Submit component </h3>

   <body>
      <t:form>
         <t:submit t:id = "submit1" value = "Click to go Index"/>
      </t:form>
   </body>

</html>

ここでは、Submitコンポーネントが値をIndexページに送信します。 ページを要求すると、次の結果が生成されます-

*http://localhost:8080/myFirstApplication/SubmitComponent*

コンポーネントを送信

フォーム検証

フォームの検証は通常、クライアントが必要なすべてのデータを入力してフォームを送信した後にサーバーで行われます。 クライアントが入力したデータが正しくないか、単に欠落している場合、サーバーはすべてのデータをクライアントに送り返して、正しい情報でフォームを再送信するように要求する必要があります。

検証のプロセスを理解するために、次の簡単な例を考えてみましょう。

以下に示すように、ページ Validate を作成します。

Validate.java

package com.example.MyFirstApplication.pages;

import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Persist;

public class Validate {
   @Property
   @Persist(PersistenceConstants.FLASH)
   private String firstName;

   @Property
   @Persist(PersistenceConstants.FLASH)
   private String lastName;
}

次に、以下に示すように、対応するテンプレートファイルを作成します。

Validate.tml

<html t:type = "newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <t:form>
      <table>
         <tr>
            <td><t:label for = "firstName"/>:</td>
            <td><input t:type = "TextField" t:id = "firstName"
            t:validate = "required, maxlength = 7" size = "10"/></td>
         </tr>
         <tr>
            <td><t:label for = "lastName"/>:</td>
            <td><input t:type = "TextField" t:id = "lastName"
            t:validate = "required, maxLength = 5" size = "10"/></td>
         </tr>
      </table>
      <t:submit t:id = "sub" value =" Form validation"/>
   </t:form>

</html>

フォーム検証には次の重要なパラメータがあります-

  • Max -最大値を定義します。 =«最大値、20»。
  • MaxDate -たとえば、maxDateを定義します =«最大日付、2013年6月9日»。 同様に、MinDateを割り当てることもできます。
  • MaxLength -例えば =«最大長、80»。
  • 最小-最小。
  • MinLength -例えば =«最小長、2»。
  • Email -標準の電子メール正規表現^ \ w [._ \ w] \ w @ \ w [-._ \ w] \ w \。\ w2,6 $またはnoneを使用する電子メール検証。

ページを要求すると、次の結果が生成されます-

*http://localhost:8080/myFirstApplication/Validate*

フォーム検証

Apacheタペストリー-Ajaxコンポーネント

AJAXは Asynchronous JavaScript and XML の略です。 これは、 XML、JSON、HTML、CSS 、および JavaScript の助けを借りて、より良く、より速く、よりインタラクティブなWebアプリケーションを作成するための手法です。 AJAXを使用すると、Webページをリロードせずに非同期でデータを送受信できるため、高速です。

ゾーンコンポーネント

ゾーンコンポーネントは、コンテンツ(マークアップ)およびコンテンツ自体の位置を提供するために使用されます。 Zoneコンポーネントのボディは、コンテンツを生成するためにTapestryによって内部的に使用されます。 動的コンテンツが生成されると、Tapestryはそれをクライアントに送信し、データを正しい場所に再レンダリングし、HTMLをトリガーしてアニメーション化し、ユーザーの注意を引きます。

このゾーンコンポーネントは、EventLinkコンポーネントとともに使用されます。 EventLinkには、 t:zone 属性を使用して特定のゾーンに関連付けるオプションがあります。 ゾーンがEventLinkで構成されたら、EventLinkをクリックすると、ゾーンの更新がトリガーされます。 さらに、EventLinkイベント(refreshZone)を使用して、動的データの生成を制御できます。

AJAXの簡単な例は次のとおりです-

AjaxZone.tml

<html t:type = "Newlayout" title = "About MyFirstApplication"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
   xmlns:p = "tapestry:parameter">

   <body>
      <h1>Ajax time zone example</h1>
      <div class = "div1">
         <a t:type = "eventlink" t:event = "refreshZone" href = "#"
            t:zone = "timeZone">Ajax Link </a><br/><br/>
         <t:zone t:id = "timeZone" id = "timeZone">Time zone: ${serverTime}</t:zone>
      </div>
   </body>

</html>

AjaxZone.java

package com.example.MyFirstApplication.pages;

import java.util.Date;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.Request;

public class AjaxZone {
   @Inject
   private Request request;

   @InjectComponent
   private Zone timeZone;

   void onRefreshPage() {
   }

   Object onRefreshZone() {
      return request.isXHR() ? timeZone.getBody() : null;
   }

   public Date getServerTime() {
      return new Date();
   }
}

結果は次の場所に表示されます。http://localhost:8080/MyFirstApplication/AjaxZone

Ajaxタイムゾーン

Apacheタペストリー-休止状態

この章では、 BeanEditForm および* Gridコンポーネント*とHibernateの統合について説明します。 Hibernateはhibernateモジュールを介してタペストリーに統合されています。 hibernateモジュールを有効にするには、 pom.xml ファイルにtapestry-hibernate依存関係とオプションで hsqldb を追加します。 次に、リソースフォルダーのルートにある hibernate.cfg.xml ファイルを使用してhibernateを構成します。

pom.xml(部分)

<dependency>
   <groupId>org.apache.tapestry</groupId>
   <artifactId>tapestry-hibernate</artifactId>
   <version>${tapestry-release-version}</version>
</dependency>

<dependency>
   <groupId>org.hsqldb</groupId>
   <artifactId>hsqldb</artifactId>
   <version>2.3.2</version>
</dependency>

Hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
   "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
      <property name = "hibernate.connection.driver_class">
         org.hsqldb.jdbcDriver
      </property>
      <property name = "hibernate.connection.url">
         jdbc:hsqldb:./target/work/sampleapp;shutdown = true
      </property>
      <property name = "hibernate.dialect">
         org.hibernate.dialect.HSQLDialect
      </property>

      <property name = "hibernate.connection.username">sa</property>
      <property name = "hibernate.connection.password"></property>
      <property name = "hbm2ddl.auto">update</property>
      <property name = "hibernate.show_sql">true</property>
      <property name = "hibernate.format_sql">true</property>
   </session-factory>
</hibernate-configuration>

BeanEditFormコンポーネントを使用して* employee追加ページ*を作成し、Gridコンポーネントを使用して* employeeリストページ*を作成する方法を見てみましょう。 永続層はHibernateモジュールによって処理されます。

従業員クラスを作成し、@ Entityアノテーションで装飾します。 次に、関連フィールドに検証アノテーションを追加し、idフィールドに関連アノテーション@Idおよび@GeneratedValueを休止状態にします。 また、性別を列挙型として作成します。

Employee.java

package com.example.MyFirstApplication.entities;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.apache.tapestry5.beaneditor.NonVisual;
import org.apache.tapestry5.beaneditor.Validate;

@Entity
public class Employee {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @NonVisual
   public Long id;

   @Validate("required")
   public String firstName;

   @Validate("required")
   public String lastName;

   @Validate("required")
   public String userName;

   @Validate("required")
   public String password;

   @Validate("required")
   public String email;
   public String phone;

   @Validate("required")
   public String Street;

   @Validate("required")
   public String city;

   @Validate("required")
   public String state;

   @Validate("required,regexp=^\\d{5}(-\\d{4})?$")
   public String zip;
}
Gender.java (enum)
package com.example.MyFirstApplication.data;

public enum Gender {
   Male, Female
}

従業員リストページ ListEmployee.java を、ページの下の新しいフォルダemployeeおよび /src/main/resources/pages/employee フォルダにある対応するテンプレートファイルListEmployee.tmlに作成します。 Tapestryは、繰り返しデータを削除することにより、サブフォルダーの短いURLを提供します。

たとえば、ListEmployeeページには、通常のURL(/employee/listemployee)および短縮URL(/employee/list)からアクセスできます。

@Injectアノテーションを使用して、Hibernateセッションをリストページに挿入します。 リストページでプロパティ getEmployees を定義し、注入されたセッションオブジェクトを使用して従業員を追加します。 以下に示すように、従業員クラスのコードを完成させます。

ListEmployee.java

package com.example.MyFirstApplication.pages.employee;

import java.util.List;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;
import com.example.MyFirstApplication.entities.Employee;
import org.apache.tapestry5.annotations.Import;
@Import(stylesheet="context:mybootstrap/css/bootstrap.css")

public class ListEmployee {
   @Inject
   private Session session;

   public List<Employee> getEmployees() {
      return session.createCriteria(Employee.class).list();
   }
}

ListEmployeeクラスのテンプレートファイルを作成します。 テンプレートには2つの主要なコンポーネントがあります-

  • PageLink -従業員のリンクページを作成します。
  • グリッド-従業員の詳細を表示するために使用されます。 グリッドコンポーネントには、従業員リストを挿入するソース属性があり、レンダリングするフィールドを含める属性が含まれています。

ListEmployee.tml(すべての従業員をリスト)

<html t:type = "simplelayout" title = "List Employee"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <h1>Employees</h1>

   <ul>
      <li><t:pagelink page = "employee/create">Create new employee</t:pagelink></li>
   </ul>
   <t:grid source = "employees"
      include = "userName,firstName,lastName,gender,dateOfBirth,phone,city,state"/>
</html>

従業員作成テンプレートファイルを作成し、BeanEditFormコンポーネントを含めます。 コンポーネントには次の属性があります-

  • オブジェクト-ソースを含みます。
  • reorder -レンダリングされるフィールドの順序を定義します。
  • submitlabel -フォーム送信ボタンのメッセージ

完全なコーディングは次のとおりです-

<html t:type = "simplelayout" title = "Create New Address"
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
   <t:beaneditform
      object = "employee"
      submitlabel = "message:submit-label"
      reorder = "userName,password,firstName,lastName,
      dateOfBirth,gender,email,phone,s treet,city,state,zip"/>
</html>

従業員作成クラスを作成し、セッション、従業員のプロパティ、リストページ(ナビゲーションリンク)を含め、コンポーネントのOnSuccessイベント(データを更新する場所)を定義します。 セッションデータは、hibernateセッションを使用してデータベースに保持されます。

完全なコーディングは次のとおりです-

package com.example.MyFirstApplication.pages.employee;

import com.example.MyFirstApplication.entities.Employee;
import com.example.MyFirstApplication.pages.employee.ListEmployee;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.hibernate.annotations.CommitAfter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;

public class CreateEmployee {
   @Property
   private Employee employee;
   @Inject
   private Session session;
   @InjectPage
   private ListEmployee listPage;
   @CommitAfter
   Object onSuccess() {
      session.persist(employee);
      return listPage;
   }
}
*CreateEmployee.properties* ファイルを追加し、フォーム検証で使用されるメッセージを含めます。 完全なコードは次のとおりです-
zip-regexp=^\\d{5}(-\\d{4})?$
zip-regexp-message = Zip Codes are five or nine digits. Example: 02134 or 901251655.
submit-label = Create Employee

従業員の作成ページとリストページのスクリーンショットは以下に示されています-

従業員の作成

作成ページ

Apacheタペストリー-ストレージ

すべてのWebアプリケーションには、ユーザーオブジェクト、ユーザー設定などの特定のユーザーデータを保存する何らかの方法が必要です。 たとえば、ショッピングカートアプリケーションでは、ユーザーが商品の購入を希望するまで、ユーザーが選択したアイテム/商品を一時的なバケット(カート)に保存する必要があります。 データベースにアイテムを保存できますが、選択したアイテムをすべてのユーザーが購入するわけではないため、費用がかかりすぎます。 そのため、アイテムを保存/永続化するための一時的な手配が必要です。 Apache Tapestryは、データを永続化する2つの方法を提供します-

  • 永続性ページデータ
  • セッションストレージ

どちらにも独自の利点と制限があります。 次のセクションで確認します。

永続化ページのデータ

永続性ページデータは、リクエスト間でデータを1つのページに永続化する単純な概念であり、ページレベルの永続性*とも呼ばれます。 *@ Persist アノテーションを使用して実行できます。

@Persist
public int age;

フィールドに@Persistアノテーションが付けられると、フィールドの値はリクエスト間で保持され、リクエスト中に値が変更された場合、次回アクセスされたときに反映されます。 Apache Tapestryは、@ Persistコンセプトを実装するための5種類の戦略を提供します。 彼らは次のとおりです-

  • セッション戦略-データはセッションを使用して永続化され、デフォルトの戦略です。
  • フラッシュ戦略-データもセッションを使用して永続化されますが、非常に短命です。 データは、後続の1つのリクエストでのみ使用できます。
@Persist(PersistenceConstants.FLASH)
private int age;
  • クライアント戦略-データは、URLクエリ文字列、フォームの非表示フィールドなど、クライアント側に保持されます。
@Persist(PersistenceConstants.FLASH)
private int age;
  • Hibernate Entity Strategy -データはHibernateモジュールをエンティティとして使用して永続化されます。 エンティティはHibernateに保存され、その参照(Javaクラス名とその主キー)はトークンとして HttpSession に保存されます。 エンティティは、HttpSessionで利用可能なトークンを使用して復元されます。
@Persist(HibernatePersistenceConstants.ENTITY)
private Category category;
  • * JPAエンティティ戦略*-データはJPAモジュールを使用して永続化されます。 エンティティのみを保存できます。
@Persist(JpaPersistenceConstants.ENTITY)
private User user;

セッションストレージ

セッションストレージは、複数ページウィザードのデータやログインユーザーの詳細など、ページ全体で使用できる必要があるデータを保存するために使用される高度な概念です。 セッションストレージには、2つのオプションがあります。1つは複雑なオブジェクトを保存し、もう1つは単純な値を保存します

  • セッションストアオブジェクト-複雑なオブジェクトを保存するために使用されます。
  • セッション属性-単純な値を保存するために使用されます。

セッションストアオブジェクト(SSO)

SSOは、 @ SessionStore アノテーションを使用して作成できます。 SSOは、オブジェクトのタイプを使用してオブジェクトを保存します。 たとえば、* Cartオブジェクト*は、トークンとしてCartクラス名を使用して保存されます。 したがって、任意の複雑なオブジェクトをアプリケーションに1回(ユーザーごとに1つ)格納できます。

public class MySSOPage {
   @SessionState
   private ShoppingCart cart;
}

SSOは特殊なストアであり、複雑な/特殊なオブジェクトのみを格納するために使用する必要があります。 SSOを使用して単純なデータ型を保存することもできますが、Stringなどの単純なデータ型を保存すると、アプリケーションに「String」値が1つだけ保存されます。 アプリケーションで単一の「文字列」値を使用することは、単に不可能です。 Apache Tapestryはセッション属性を提供するため、単純なデータ型を使用できます。

セッション属性

セッション属性を使用すると、タイプではなく名前でデータを保存できます。

public class MyPage {
   @SessionAttribute
   private String loggedInUsername;
}

デフォルトでは、セッション属性はフィールド名を使用してセッションのデータを参照します。 以下に示すように、注釈パラメーターによって参照名を変更できます-

public class MyPage {
   @SessionAttribute("loggedInUserName")
   private String userName;
}

名前をセッション参照として使用する際の主な問題の1つは、複数のクラス/ページで同じ名前を誤って使用する可能性があることです。 この場合、保存されたデータは予期せず変更される可能性があります。 この問題を修正するには、クラス/ページ名およびパッケージ名とともに名前を使用する方が良いでしょう。 com.myapp.pages.register.email のようになります。com.myapp.pagesはパッケージ名、registerはページです/クラス名と最後に電子メールは変数(保存される)名です。

Apacheタペストリー-高度な機能

この章では、Apache Tapestryのいくつかの高度な機能について詳しく説明します。

制御の反転

Tapestryは、組み込みのInversion of Controlライブラリを提供します。 TapestryはIoCに深く統合されており、すべての機能にIoCを使用しています。 Tapestry IoCの構成は、他の多くのIoCコンテナーのようにXMLではなくJava自体に基づいています。 タペストリーIoCベースのモジュールはJARファイルにパッケージ化され、設定なしでクラスパスにドロップされます。 タペストリーIoCの使用法は、明るさに基づいています。つまり、

  • 2つまたは3つのメソッドの小さなインターフェイス。
  • 2つまたは3つのパラメーターを持つ小さなメソッド。
  • 明示的なメソッド呼び出しではなく、イベントを介した匿名通信。

モジュール

モジュールは、Tapestryアプリケーションの機能を拡張する方法です。 Tapestryには、組み込みモジュールと多数のサードパーティモジュールの両方があります。 Hibernateは、Tapestryが提供するホットで非常に便利なモジュールの1つです。 また、JMX、JPA、Spring Framework、JSR 303 Bean Validation、JSONなどを統合するモジュールもあります。 注目すべきサードパーティのモジュールのいくつかは-

  • タペストリー-カイエン
  • Tapestry5-googleanalytics
  • タペストリー5のギャング-Tapestry5-HighCharts
  • タペストリー5のギャング-Tapestry5-jqPlot
  • タペストリー5のギャング-Tapestry5-Jquery
  • タペストリー5のギャング-Tapestry5-Jquery-mobile
  • タペストリー5のギャング-タペストリー5-ポートレット

ランタイム例外

タペストリーの最も優れた機能の1つは、*詳細なエラー報告*です。 Tapestryは、最先端の例外レポートを提供することにより、開発者を支援します。 タペストリーの例外レポートは、詳細情報を含む単純なHTMLです。 誰でも簡単にレポートを理解できます。 TapestryはHTMLでエラーを表示するだけでなく、例外が発生した日時をプレーンテキストで保存します。 これにより、開発者は実稼働環境でも例外を確認できます。 開発者は、壊れたテンプレート、予期しないnull値、一致しないリクエストなどの問題を修正する自信を持ち続けることができます。

ライブクラスとテンプレートのリロード

Tapestryは、変更されるとテンプレートとクラスを自動的にリロードします。 この機能により、ビルドとテストのサイクルを経ることなく、アプリケーションの変更を即座に反映できます。 また、この機能により、アプリケーション開発の生産性が大幅に向上します。

アプリケーションのルートパッケージが org.example.myfirstapp であると考えてください。 次に、次のパスのクラスが再読み込みのためにスキャンされます。

  • org.example.myfirstapp.pages

  • org.example.myfirstapp.components

  • org.example.myfirstapp.mixins

  • org.example.myfirstapp.base

  • org.example.myfirstapp.services

    *AppModule.java* でプロダクションモードを *true* に設定することにより、ライブクラスのリロードを無効にできます。
configuration.add(SymbolicConstants.PRODUCTION_MODE,”false”);

単体テスト

単体テストは、個々のページとコンポーネントをテストする手法です。 Tapestryは、ユニットテストのページとコンポーネントに簡単なオプションを提供します。

ページのユニットテスト:Tapestryは、アプリケーションをテストするクラス PageTester を提供します。 これは、ブラウザとサーブレットコンテナの両方として機能します。 サーバー側のブラウザを使用せずにページをレンダリングし、結果のドキュメントをチェックして正しいレンダリングを確認できます。 単純なページ Hello を考えてみましょう。これは、helloをレンダリングし、helloテキストはid hello_id のhtml要素で囲まれています。 この機能をテストするには、以下に示すようにPageTesterを使用できます-

public class PageTest extends Assert {
   @Test
   public void test1() {
      Sring appPackage = "org.example.myfirstapp";//package name
      String appName = "App1";//app name
      PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");
      Document doc = tester.renderPage("Hello");
      assertEquals(doc.getElementById("hello_id").getChildText(), "hello");
   }
}

PageTesterは、ページのレンダリングに加えて、コンテキスト情報、フォーム送信、リンクナビゲーションなどを含めるオプションも提供します。

統合テスト

統合テストは、単体テストのように個々のページをチェックする代わりに、モジュールとしてアプリケーションをテストするのに役立ちます。 統合テストでは、複数のモジュールをユニットとして一緒にテストできます。 Tapestryは、 Tapestry Test Utilities という小さなライブラリを提供して、統合テストを実行します。 このライブラリは、Seleniumテストツールと統合してテストを実行します。 このライブラリは、Seleniumサーバー、Seleniumクライアント、およびJettyインスタンスを起動および管理する基本クラス SeleniumTestCase を提供します。

統合テストの例の1つは次のとおりです-

import org.apache.tapestry5.test.SeleniumTestCase;
import org.testng.annotations.Test;

public class IntegrationTest extends SeleniumTestCase {
   @Test
   public void persist_entities() {
      open("/persistitem");
      assertEquals(getText("//span[@id='name']").length(), 0);
      clickAndWait("link = create item");
      assertText("//span[@id = 'name']", "name");
   }
}

開発ダッシュボード

開発ダッシュボードは、アプリケーションの問題を特定/解決するために使用されるデフォルトのページです。 ダッシュボードには、URL http://localhost:8080/myfirstapp/core/t5dashboard からアクセスします。 ダッシュボードには、アプリケーションで使用可能なすべてのページ、サービス、およびコンポーネントライブラリが表示されます。

応答圧縮

Tapestryは、* GZIP圧縮*を使用して応答を自動的に圧縮し、クライアントにストリーミングします。 この機能により、ネットワークトラフィックが削減され、ページの配信が高速化されます。 圧縮は、AppModule.javaのシンボル tapestry.min-gzip-size を使用して構成できます。 デフォルト値は100バイトです。 応答のサイズが100バイトを超えると、Tapestryは応答を圧縮します。

セキュリティ

Tapestryは、Webアプリケーションの既知のセキュリティ脆弱性からアプリケーションを保護するための多くのオプションを提供します。 これらのオプションの一部を以下にリストします-

  • HTTPS -タペストリーページに @ Secure の注釈を付けて、安全なページにし、* httpsプロトコル*のみでアクセスできるようにすることができます。
  • ページアクセス制御-特定のユーザーのみがアクセスするページを制御します。
  • ホワイトリストページ-タペストリーページに @ WhitelistAccessOnly の注釈を付けて、 localhost からのみアクセスできるようにすることができます。
  • 資産セキュリティ-タペストリーでは、特定の種類のファイルにのみアクセスできます。 他のものは、ファイルの* MD5ハッシュ*が提供されている場合にのみアクセスできます。
  • シリアル化されたオブジェクトの日付-タペストリーはHMACをシリアル化されたJavaオブジェクトデータに統合し、クライアントに送信してメッセージの改ざんを防ぎます。
  • Cross Site Request Forgery -Tapestryは、tapestry-csrf-protectionと呼ばれるサードパーティモジュールを提供して、CSRF攻撃を防ぎます。
  • セキュリティフレームワークの統合-Tapestryは、単一の認証/承認実装にロックしません。 Tapestryは、一般的な認証フレームワークと統合できます。

ロギング

Tapestryは、ロギングの広範なサポート、実行中のアプリケーションの進行状況の自動記録を提供します。 Tapestryでは、事実上のJavaロギングライブラリ SLF4J を使用しています。 アノテーション @ Log は、メソッドの入り口と出口、および可能な例外を発行するために、任意のコンポーネントメソッドに含めることができます。 また、Tapestryが提供するロガーオブジェクトは、以下に示すように @ Inject アノテーションを使用して任意のコンポーネントに挿入できます-

public class MyPage {
   @Inject
   private Logger logger;

  //. . .

   void onSuccessFromForm() {
      logger.info("Changes saved successfully");
   }

   @Log
   void onValidateFromForm() {
     //logic
   }
}

最後に、Apache Tapestryは、簡潔で、スケーラブルで、保守可能で、堅牢で、Ajax対応のアプリケーションを構築するための最良の方法をもたらすと言えます。 Tapestryは、サードパーティのJavaアプリケーションと統合できます。 また、非常に簡単かつ高速であるため、大規模なWebアプリケーションの作成にも役立ちます。