ポートレットフィルターの使用
ポートレットフィルターは、各ポートレットリクエスト処理フェーズの開始時にリクエストとレスポンスをインターセプトするため、その段階で機能を追加することができます。 これにより、ポートレットのアクティビティの監査、コンテンツの変換、リクエストおよびレスポンス属性の追加または変更、ユーザー入力を取得するためのポートレットフェーズの一時停止などに役立ちます。
ポートレットフィルタを作成するには、以下の手順に従ってください。
-
フルネーム(
com_liferay_blogs_web_portlet_BlogsPortletなど)でターゲットポートレットを識別します。 -
インターセプトしたいポートレットのフェーズを決定し、
javax.portlet.filterパッケージから対応するポートレットフィルタインターフェイスを実装します。- アクションフェーズ -
アクションフィルタ - イベントフェーズ -
イベントフィルタ - レンダリングフェーズ -
レンダリングフィルタ - リソース提供フェーズ -
リソースフィルタ
各ポートレットフェーズの詳細については、 ポートレット を参照してください。
- アクションフェーズ -
-
@Componentアノテーションを使用してポートレットフィルタを OSGi フレームワーク内のコンポーネントとして宣言し、PortletFilter.classサービスとして識別します。注記ポートレットフィルタは OSGi宣言型サービス(DS)コンポーネントです。 フィルタは、
portlet.xml記述子または@PortletLifecycleFilterアノテーションを使用してポートレットに適用することもできます。 -
@Component宣言に以下のプロパティを入力します。"javax.portlet.name=[portlet_name]": このプロパティは、フィルタのターゲットポートレットを設定します。"service.ranking:Integer=[priority]": このプロパティはフィルタのランキングを設定し、整数値が大きいほど先に実行されます。 フィルターに最高ランクを割り当てることで、フィルターチェーンの先頭から開始されるようにしてください。
-
フィルターの
doFilterメソッドをオーバーライドして、必要な機能を追加します。
次の例では、RenderFilterを使用して、ブログポートレットのレンダリングフェーズを監査します。
サンプルポートレットフィルターのデプロイ
Liferay の新しいインスタンスを起動するには、次のコマンドを実行します。
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132
http://localhost:8080 で Liferay にサインインしてください。 メールアドレス test@liferay.com とパスワード test を使用してください。 プロンプトが表示されたら、パスワードを learn に変更してください。
次に、以下の手順に従って、サンプルポートレットフィルタをダウンロード、ビルド、および新しいDockerコンテナにデプロイします。
-
サンプルモジュールをダウンロードして解凍してください。
curl https://resources.learn.liferay.com/examples/liferay-b4k8.zip -Ounzip liferay-b4k8.zip -
JAR ファイルをビルドして新しい Docker コンテナにデプロイするには、次の
gradlewコマンドを実行してください。cd liferay-b4k8 ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)JAR ファイルは
build/libsフォルダ (つまり、b4k8-impl/build/libs/com.acme.b4k8.impl-1.0.0.jar) に生成されます。 -
コンテナコンソールから、モジュールが正常にデプロイされ、起動されたことを確認してください。
com.acme.b4k8.impl-1.0.0.jar の処理中 開始 com.acme.b4k8.impl_1.0.0 [1656] -
サイトページにブログウィジェットを追加して、ポートレットフィルターが正しく機能していることを確認してください。
ブログポートレットに対してレンダリング要求が行われるたびに、コンテナコンソールには、レンダリング時間、平均レンダリング時間、およびレンダリングの総数に関する監査情報を含む警告メッセージが表示されます。
警告 [http-nio-8080-exec-2][B4K8PortletFilter:54] ブログポートレットは、1回のレンダリングのうち平均3msで3msでレンダリングされました。 警告 [http-nio-8080-exec-10][B4K8PortletFilter:54] ブログポートレットは、2回のレンダリングのうち平均1msで0msでレンダリングされました。
ポートレットフィルタを使用したポートレットのレンダリングフェーズの監査
提供されているサンプルフィルタは、Blogs ポートレットを対象とし、 RenderFilter インターフェイスを使用してレンダリングフェーズを監査します。
@Component(
property = {
"jakarta.portlet.name=com_liferay_blogs_web_portlet_BlogsPortlet",
"service.ranking:Integer=100"
},
service = PortletFilter.class
)
public class B4K8PortletFilter implements RenderFilter {
@Override
public void destroy() {
}
@Override
public void doFilter(
RenderRequest renderRequest, RenderResponse renderResponse,
FilterChain filterChain)
throws IOException, PortletException {
long startTime = System.currentTimeMillis();
filterChain.doFilter(renderRequest, renderResponse);
long renderTime = (System.currentTimeMillis() - startTime) / 1000;
_totalTime.add(renderTime);
_count.increment();
if (_log.isInfoEnabled()) {
long count = _count.longValue();
long averageRenderTime = _totalTime.longValue() / count;
_log.info(
"ブログ ポートレットは " + renderTime +
" ms でレンダリングされ、平均レンダリング時間は " + averageRenderTime +
" ms で、 " + count + " 回のレンダリングのうちでした。");
}
}
@Override
public void init(FilterConfig filterConfig) throws PortletException {
}
private static final Log _log = LogFactoryUtil.getLog(
B4K8PortletFilter.class);
private final LongAdder _count = new LongAdder();
プライベート最終 LongAdder _totalTime = new LongAdder();
}
このコードでは、まずフィルタが OSGi DS コンポーネントとして宣言され、 PortletFilter.class サービスとして識別されます。 この宣言の一部として、2 つのプロパティも設定されます。最初のプロパティは BlogsPortletを対象とし、2 番目のプロパティは優先度を 100 に設定します。
ポートレットフィルタは、 RenderFilter インターフェースを実装します。このインターフェースは、 PortletFilter インターフェースを拡張します。 このインターフェースには 3 つのメソッド (つまり、 init、 destroy、 doFilter) が含まれており、ブログ ポートレットへのレンダリング リクエストとそのレスポンスの両方でフィルタリング タスクを実行します。
-
init: ポートレットフィルタが最初にLiferayにデプロイされ、ポートレットコンテナ内で初期化されたときに呼び出されます。 -
destroy: ポートレットフィルタをサービスから削除するために呼び出されました。 -
doFilter: クライアントのリクエストによりレンダリングリクエスト/レスポンスのペアがチェーンを通過するたびに、ポートレットコンテナによって呼び出されます。
この例では、 doFilter は、ブログ ポートレットを次の方法で監査します。
-
レンダリングフェーズの開始時刻を注記します。
long startTime = System.currentTimeMillis(); -
FilterChainのdoFilterメソッドを実行し、チェーン内のすべてのRenderFilter を呼び出します。filterChain.doFilter(renderRequest, renderResponse); -
ブログポートレットがレンダリングフェーズを完了するまでにかかる時間を計算します。
long renderTime = (System.currentTimeMillis() - startTime) / 1000; -
現在のレンダリング時間を、すべてのレンダリングの合計時間に加算します。
_totalTime.add(renderTime); -
ポートレットのレンダリング総数を増加させます。
_count.increment(); -
LongAdderユーティリティを使用してポートレットの平均レンダリング時間とレンダリングの総数を保存し、次にLogユーティリティを使用してこれらの値をポートレットの現在のレンダリング時間とともに表示します。
if (_log.isInfoEnabled()) {
long count = _count.longValue();
long AverageRenderTime = _totalTime.longValue() / count;
_log.info(
"ブログポートレットは " + renderTime +
" ミリ秒でレンダリングされ、平均レンダリング時間は " + averageRenderTime +
" ミリ秒で、 " + count + " 回のレンダリングのうちです。");
}
レンダリング要求が行われるたびに、この doFilter が呼び出されます。