ポートレット・フィルター
JSR 286: Portlet Specification 2.0 のリリース以降、要求および応答を、所定のフェーズのポートレットに配信される前に代行受信して操作することが可能になりました。 ポートレット・フィルター を使用すると、特定の条件の発生時にポートレットのレンダリングをブロックすることができます。 また、ポートレット・フィルターを使用してラッパー内の要求および応答を修飾し、ポートレットの振る舞いを変更することもできます。
ポートレット・フィルターの使用法
ポートレット・フィルター・フィーチャーを使用するには、最初に以下のアクションを実行する必要があります。
- javax.portlet.filter パッケージの以下のインターフェースを 1 つ以上実装します。
- RenderFilter
- ActionFilter
- ResourceFilter
- EventFilter
- フィルターは、Web アプリケーションにあるポートレットの portlet.xml ファイル内に登録します。
以下のサンプル・コードは、ポートレットの processAction メソッドをフィルタリングするポートレット・フィルターを示します。
package my.pkg;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.filter.ActionFilter;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
public class MyPortletFilter implements ActionFilter {
public void init(FilterConfig config) throws PortletException {
String myInitParameter = config.getInitParameter("myInitParameter");
// ...
}
public void doFilter(ActionRequest request, ActionResponse response,
FilterChain chain) throws IOException, PortletException {
preProcess(request, response);
chain.doFilter(request, response);
postProcess (request, response);
}
private void preProcess(ActionRequest request, ActionResponse response) {
//For example, create a javax.portlet.filter.PortletRequestWrapper here
}
public void destroy() {
// free resources
}
}
以下のサンプル・コードでは、portlet.xml ファイルで上記のポートレット・フィルターを宣言する方法について示します。
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0" id="demo_app_id">
<portlet >
<portlet-name>MyPortlet1</portlet-name>
<!-- [...] -->
</portlet>
<portlet >
<portlet-name>MyPortlet2</portlet-name>
<!-- [...] -->
</portlet>
<filter>
<filter-name>PortletFilter</filter-name>
<filter-class>my.pkg .MyPortletFilter</filter-class>
<lifecycle>ACTION_PHASE</lifecycle>
<init-param>
<name>myInitParameter</name>
<value>myValue</value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PortletFilter</filter-name>
<portlet-name>MyPortlet1</portlet-name>
<portlet-name>MyPortlet2</portlet-name>
</filter-mapping>
</portlet-app>
RenderFilter インターフェースを実装する場合、例えば、<lifecycle>RENDER_PHASE</lifecycle> コードをフィルター・セクションに追加します。
この追加は、その他のフィルター・インターフェースと類似しています。
以下の値は、<lifecycle> パラメーターに有効です。
- RESOURCE_PHASE
- RENDER_PHASE
- EVENT_PHASE
- ACTION_PHASE
グローバル・ポートレット・フィルター
WebSphere® Application Server のポートレット・コンテナーは、JSR 286 で提供されるポートレット・フィルター・フィーチャーを拡張し、グローバル・レベルでフィルターを登録できるようにします。 これらのグローバル・フィルターは、ポートレット・コンテナー内で実行するすべてのポートレット (プレーン・ポートレットおよびコンソール・モジュールの両方を含む) に適用されます。
グローバル・ポートレット・フィルターを使用するには、以下のコードを Java™ アーカイブ (JAR) ファイルのルート・フォルダーか、Web アプリケーションの WEB-INF ディレクトリーに追加して、plugin.xml ファイルという名前を付けます。
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin id="portlet-filter-config" name="WS_Server" provider-name="IBM"
version="1.0.0">
<extension point="com.ibm.ws.portletcontainer.portlet-filter-config">
<portlet-filter-config class-name="my.pkg.PortletFilter" order="22000">
<description>Description of global PortletFilterImpl</description>
<lifecycle>ACTION_PHASE</lifecycle>
<lifecycle>EVENT_PHASE</lifecycle>
<lifecycle>RENDER_PHASE</lifecycle>
<lifecycle>RESOURCE_PHASE</lifecycle>
<init-param>
<name>MyInitParam1</name>
<value>MyInitValue1</value>
</init-param>
<init-param>
<name>MyInitParam2</name>
<value>MyInitValue2</value>
</init-param>
</portlet-filter-config>
</extension>
</plugin>
portlet-filter-config エレメントの order 属性は、フィルター・チェーン内でフィルターを実行する順序を定義します。
値が高いほど、フィルター・チェーンでそのフィルターが実行される順番が後になります。
グローバル・フィルターは、ローカル・ポートレット・フィルターよりも前にトリガーされます。
トラブルの回避 (Avoid trouble):

- グローバル・ポートレット・フィルターは、コンテナー内のすべてのポートレットに適用されるので、init メソッド内で FilterConfig#getPortletContext メソッドを呼び出す場合、グローバル・ポートレット・フィルターの戻り値はヌルになります。
- このフィーチャーを、WebSphere Application Server のポートレット文書フィルターと混同しないでください。 これらのポートレット文書フィルターは、厳密に言えば、レンダリングされた出力にのみ適用可能なサーブレット・フィルターです。 ポートレット文書フィルターについて詳しくは、ポートレット・フラグメントの HTML 文書への変換に関する資料を参照してください。
- グローバル・ポートレット・フィルターは、所定のポートレット・コンテナー内で実行するすべてのポートレットに影響を与えるため、Integrated Solutions Console 内に含まれるコンソール・モジュールもフィルターに掛けられます。 フィルター実装をテストして、コンソール・モジュールやポートレットに望ましくない副次作用が生じないことを確認することが重要です。 その 1 つとして、フィルター・ロジック内の要求のコンテキスト・パスを検査することによってテストする方法があります。