カスタムJSPバッグを使用したJSPのオーバーライド

LiferayのJSPをオーバーライドするAPIベースのアプローチ(つまり、動的インクルードポートレットフィルター)は、アプリおよびコアのJSPをオーバーライドする最良の方法です。カスタムJSPバッグを使用して、コアJSPをオーバーライドすることもできます。しかし、このアプローチはAPIベースのアプローチほど安定していません。カスタムJSPバッグのJSPにバグがある場合(コードやLiferayの変更のせいで)、ほとんどの場合は実行時に、機能が壊れたり、厄介なログエラーが表示されたりすることで気付くはずです。カスタムJSPバッグを使用してJSPをオーバーライドすることはバッドプラクティスであり、Extプラグインを使用してLiferay DXPをカスタマイズするのと同じです。ただし、既存のカスタムJSPバッグを維持している場合は、このチュートリアルでその動作について説明します。

重要:Liferayは、カスタムJSPバッグを使用してオーバーライドされたJSPのアップグレードを保証できません。

カスタムJSPバッグモジュールは、次の基準を満たす必要があります。

  • 拡張するJSPのカスタムJSPを提供および指定している。

  • カスタムJSPを提供するためのCustomJspBag実装が含まれている。

モジュールは、このコードをLiferayのOSGiランタイムに転送します。 新しいモジュールを作成したら、カスタムJSPを指定します。

カスタムJSPの指定

Liferay DXPのコアJSPをオーバーライドするJSPを作成します。Mavenの標準ディレクトリレイアウトを使用している場合は、src/main/resources/META-INF/jspsの下にJSPを配置します。以下をオーバーライドする場合:

portal-web/docroot/html/common/themes/bottom-ext.jsp

カスタムJSPを次のように配置します。

[your module]/src/main/resources/META-INF/jsps/html/common/themes/bottom-ext.jsp

:モジュール内src/main/resources/META-INF/jsps以外の場所にカスタムJSPを配置する場合は、その場所をモジュールのbnd.bndファイル内の-includeresource: META-INF/jsps=ディレクティブに割り当てます。 たとえばモジュール内のフォルダsrc/META-INF/custom_jspsにカスタムJSPを配置する場合は、bnd.bnd内で次のように指定します。

-includeresource: META-INF/jsps=src/META-INF/custom_jsps

カスタムJSPバッグを実装する

Liferay DXP(特にCustomJspBagRegistryUtilクラス)は、CustomJspBagサービスからJSPを読み込みます。次の手順では、カスタムJSPバッグを実装します。

  1. モジュールで、CustomJspBagを実装するクラスを作成します。

  2. 次のように、@Componentアノテーションを追加して、クラスをOSGiサービスとして登録します。

    @Component(
    immediate = true,
    property = {
    "context.id=BladeCustomJspBag",
    "context.name=Test Custom JSP Bag",
    "service.ranking:Integer=100"
    }
    )
    
    • immediate = true:モジュールのアクティベーションでサービスを利用できるようにします。
    • context.id:カスタムJSPバッグのクラス名。BladeCustomJspBagをクラス名に置き換えます。
    • context.name:人間が読み取れるサービス名。独自の名前に置き換えます。
    • service.ranking:Integer:実装の優先順位。コンテナは、優先度が最も高い実装を選択します。
  3. getCustomJspDirメソッドを実装して、JSPが存在するモジュールのJAR内のフォルダパスを返します(例:META-INF/jsps)。

    @Override
    public String getCustomJspDir() {
    return "META-INF/jsps/";
    }
    
  4. activateメソッドと次のフィールドを作成します。このメソッドは、モジュールがアクティブ化されると、すべてのカスタムJSPのURLパスをリストに追加します。

    @Activate
    protected void activate(BundleContext bundleContext) {
    _bundle = bundleContext.getBundle();
    
    _customJsps = new ArrayList<>();
    
    Enumeration<URL> entries = _bundle.findEntries(
    getCustomJspDir(), "*.jsp", true);
    
    while (entries.hasMoreElements()) {
    URL url = entries.nextElement();
    
    _customJsps.add(url.getPath());
    }
    }
    
    private Bundle _bundle;
    private List<String> _customJsps;
    
  5. このモジュールのカスタムJSP URLパスのリストを返すgetCustomJspsメソッドを実装します。

    @Override
    public List<String> getCustomJsps() {
    return _customJsps;
    }
    
  6. 新しいcom.liferay.portal.kernel.url.URLContainerを返すgetURLContainerメソッドを実装します。URLコンテナをインスタンス化し、getResourcesおよびgetResourceメソッドをオーバーライドします。getResourcesメソッドは、指定されたパスで、コンテナ内のリソースへのすべてのパスを検索します。一致するカスタムJSPパスのStringsHashSetが返されます。getResourceメソッドは、その名前ごとに1つの特定のリソースを返します(パスを含む)。サンプルのBladeCustomJspBagクラスは、次のようにgetURLContainerを実装します。

    @Override
    public URLContainer getURLContainer() {
    return _urlContainer;
    }
    
    private final URLContainer _urlContainer = new URLContainer() {
    
    @Override
    public URL getResource(String name) {
    return _bundle.getEntry(name);
    }
    
    @Override
    public Set<String> getResources(String path) {
    Set<String> paths = new HashSet<>();
    
    for (String entry : _customJsps) {
    if (entry.startsWith(path)) {
    paths.add(entry);
    }
    }
    
    return paths;
    }
    
    };
    
  7. trueを返すisCustomJspGlobalメソッドを実装します。

    @Override
    public boolean isCustomJspGlobal() {
    return true;
    }
    

これで、モジュールはカスタムJSPとカスタムJSPバッグの実装を提供します。デプロイすると、Liferay DXPは、オーバーライドするコアJSPの代わりにカスタムJSPを使用します。

JSPを拡張する

コアJSPに何かを追加する場合は、空の-ext.jspがあるかを確認し、JSP全体ではなくそれをオーバーライドします。JSP全体が大幅に変更されると、その過程でカスタマイズが崩れる可能性があるため、こうすることでよりシンプルかつ安定した状態を維持できます。-ext.jspをオーバーライドすると、-ext.jspを含む元のJSPのみに依存します。たとえば、portal-web/docroot/html/common/themes/bottom.jspを開き、最後までスクロールしてください。 以下が表示されます。

<liferay-util:include page="/html/common/themes/bottom-ext.jsp" />

bottom.jspに何かを追加する必要がある場合は、bottom-ext.jspをオーバーライドします。

Liferay DXP 7.0以降、以前はhtml/common/themesに含まれていた以下のJSPファイルのコンテンツがインライン化され、パフォーマンスが向上しました。

  • body_bottom-ext.jsp
  • body_top-ext.jsp
  • bottom-ext.jsp
  • bottom-test.jsp

これらはコードベースの明示的なファイルではなくなりました。ただし、モジュールでそれらを作成して、機能とコンテンツを追加することは引き続き可能です。

このタイプのカスタマイズは最後の手段であることに留意してください。この実装の性質によりオーバーライドが壊れる可能性があり、Liferayのコア機能がそれとともに機能しなくなる可能性があります。オーバーライドするJSPが別のモジュールにある場合は、JSPをオーバーライドするためのLiferay APIベースのアプローチに関するセクションを参照してください。

サイトスコープのJSPカスタマイズ

Liferay Portal 6.2では、アプリケーションアダプタを使用して、コアJSPのカスタマイズの対象を特定のサイトに絞り込むことができました。Liferay DXP 7.0ではJSPの大部分がモジュールに移行されたため、このユースケースは大幅に縮小しました。コアJSPのカスタマイズの対象を特定のサイトに絞り込む必要がある場合は、Liferay Portal 6.2の場合と同様にアプリケーションアダプタを準備して、 Liferay DXP 7.1にデプロイします。これで引き続き機能します。ただし、このアプローチはLiferay DXP 7.1では非推奨であり、Liferay 8.0ではまったくサポートされていないことに注意してください。

関連トピック

Upgrading Core JSP Hooks

« OSGiフラグメントを使用したJSPのオーバーライドJSPを使用したインラインコンテンツのオーバーライド »
この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています