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. 次のgradlewコマンドを実行してJARファイルをビルドし、それを新しいDockerコンテナにデプロイします。

    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. モジュールが正常にデプロイされ、コンテナコンソールを介して開始されたことを確認します。

    Processing com.acme.b4k8.impl-1.0.0.jar
    STARTED com.acme.b4k8.impl_1.0.0 [1656]
    
  4. ブログ ウィジェットをサイト ページに追加して、ポートレット フィルターが機能していることを確認します。

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

    WARN [http-nio-8080-exec-2][B4K8PortletFilter:54] Blogs portlet rendered in 3 ms with an average of 3 ms out of 1 renders.
    WARN [http-nio-8080-exec-10][B4K8PortletFilter:54] Blogs portlet rendered in 0 ms with an average of 1 ms out of 2 renders.
    

ポートレットフィルターを使用したポートレットのレンダリングフェーズの監査

提供されているサンプルのフィルターは、ブログポートレットを対象とし、RenderFilterインターフェイスを使用してそのレンダリングフェーズを監査します。

@Component(
	property = {
		"javax.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(
				"Blogs portlet rendered in " + renderTime +
					" ms with an average of " + averageRenderTime +
						" ms out of " + count + " renders.");
		}
	}

	@Override
	public void init(FilterConfig filterConfig) throws PortletException {
	}

	private static final Log _log = LogFactoryUtil.getLog(
		B4K8PortletFilter.class);

	private final LongAdder _count = new LongAdder();
	private final LongAdder _totalTime = new LongAdder();

}

このコードでは、フィルターは最初にOSGi DSコンポーネントとして宣言され、PortletFilter.classサービスとして識別されます。 この宣言の一部として、2つのプロパティも設定します。最初のプロパティはBlogsPortletを対象とし、2番目のプロパティは重要度を100に設定します。

ポートレット フィルターは、 RenderFilter インターフェイスの実装に進みます。このインターフェイスは、 PortletFilter インターフェイスを拡張します。 このインターフェースには3つのメソッド(つまり、initdestroydoFilter)が含まれており、ブログポートレットへの描画リクエストとその応答の両方でフィルタリングタスクを実行します。

  • init:ポートレットフィルターが最初にLiferayにデプロイされ、ポートレットコンテナ内で初期化されたときに呼び出されます。

  • destroy:サービスからポートレットフィルターを削除するために呼び出されます。

  • doFilter:クライアントリクエストにより描画リクエスト/応答のペアがチェーンを通過するたびに、ポートレットコンテナによって呼び出されます。

この例では、doFilterは次の方法でブログポートレットを監査します。

  1. レンダリングフェーズの開始時間をメモします。

    long startTime = System.currentTimeMillis();
    
  2. FilterChaindoFilterメソッドを実行して、チェーン内のすべての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(
		"Blogs portlet rendered in " + renderTime +
			" ms with an average of " + averageRenderTime +
				" ms out of " + count + " renders.");
}

描画リクエストが行われるたびに、このdoFilterが呼び出されます。