Extending Liferay
ご覧のページは、お客様の利便性のために一部機械翻訳されています。また、ドキュメントは頻繁に更新が加えられており、翻訳は未完成の部分が含まれることをご了承ください。最新情報は都度公開されておりますため、必ず英語版をご参照ください。翻訳に問題がある場合は、 こちら までご連絡ください。

ポートレットフィルターの使用

ポートレットフィルターは、各ポートレットリクエスト処理フェーズの開始時にリクエストとレスポンスをインターセプトするため、その段階で機能を追加することができます。 これにより、ポートレットのアクティビティの監査、コンテンツの変換、リクエストおよびレスポンス属性の追加または変更、ユーザー入力を取得するためのポートレットフェーズの一時停止などに役立ちます。

ポートレットフィルタを作成するには、以下の手順に従ってください。

  1. フルネーム(com_liferay_blogs_web_portlet_BlogsPortletなど)でターゲットポートレットを識別します。

  2. インターセプトしたいポートレットのフェーズを決定し、 javax.portlet.filter パッケージから対応するポートレットフィルタインターフェイスを実装します。

    各ポートレットフェーズの詳細については、 ポートレット を参照してください。

  3. @Component アノテーションを使用してポートレットフィルタを OSGi フレームワーク内のコンポーネントとして宣言し、 PortletFilter.class サービスとして識別します。

    注記

    ポートレットフィルタは OSGi宣言型サービス(DS)コンポーネントです。 フィルタは、 portlet.xml 記述子または @PortletLifecycleFilter アノテーションを使用してポートレットに適用することもできます。

  4. @Component 宣言に以下のプロパティを入力します。

    • "javax.portlet.name=[portlet_name]": このプロパティは、フィルタのターゲットポートレットを設定します。
    • "service.ranking:Integer=[priority]": このプロパティはフィルタのランキングを設定し、整数値が大きいほど先に実行されます。 フィルターに最高ランクを割り当てることで、フィルターチェーンの先頭から開始されるようにしてください。
  5. フィルターの 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コンテナにデプロイします。

  1. サンプルモジュールをダウンロードして解凍してください。

    curl https://resources.learn.liferay.com/examples/liferay-b4k8.zip -O
    
    unzip liferay-b4k8.zip
    
  2. 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) に生成されます。

  3. コンテナコンソールから、モジュールが正常にデプロイされ、起動されたことを確認してください。

    com.acme.b4k8.impl-1.0.0.jar の処理中
    開始 com.acme.b4k8.impl_1.0.0 [1656]
    
  4. サイトページにブログウィジェットを追加して、ポートレットフィルターが正しく機能していることを確認してください。

    ブログポートレットに対してレンダリング要求が行われるたびに、コンテナコンソールには、レンダリング時間、平均レンダリング時間、およびレンダリングの総数に関する監査情報を含む警告メッセージが表示されます。

    警告 [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 は、ブログ ポートレットを次の方法で監査します。

  1. レンダリングフェーズの開始時刻を注記します。

    long startTime = System.currentTimeMillis();
    
  2. FilterChainのdoFilterメソッドを実行し、チェーン内のすべてのRenderFilter を呼び出します。

    filterChain.doFilter(renderRequest, renderResponse);
    
  3. ブログポートレットがレンダリングフェーズを完了するまでにかかる時間を計算します。

    long renderTime = (System.currentTimeMillis() - startTime) / 1000;
    
  4. 現在のレンダリング時間を、すべてのレンダリングの合計時間に加算します。

    _totalTime.add(renderTime);
    
  5. ポートレットのレンダリング総数を増加させます。

    _count.increment();
    
  6. LongAdder ユーティリティを使用してポートレットの平均レンダリング時間とレンダリングの総数を保存し、次に Log ユーティリティを使用してこれらの値をポートレットの現在のレンダリング時間とともに表示します。

if (_log.isInfoEnabled()) {
	long count = _count.longValue();

	long AverageRenderTime = _totalTime.longValue() / count;

	_log.info(
		"ブログポートレットは " + renderTime +
			" ミリ秒でレンダリングされ、平均レンダリング時間は " + averageRenderTime +
				" ミリ秒で、 " + count + " 回のレンダリングのうちです。");
}

レンダリング要求が行われるたびに、この doFilter が呼び出されます。