JSR 168: Portlet Specification

JCPでは現在JSR 286としてJavaポートレット仕様バージョン2.0の標準化が進められており、7月よりPublic Reviewが行われている最中だ。次期バージョンのポートレット仕様も気になるところだが、今回はその前に現行の仕様である「JSR 168: Portlet Specification」を紹介しておきたい。

JSR 168はポータルアプリケーションで利用される「ポートレット」と呼ばれる小型のWebコンポーネントを作成するためのAPIである。一般にポータルと言えばシングルサインオンやコンテンツ統合を提供するWebアプリケーションを指す。ポートレットはこのポータルで利用されるUIコンポーネントで、リクエストに応じて動的に画面の生成を行うことができる。今ならばGoogleガジェットのようなものを想像してもらうとわかりやすいだろう。

ポートレットは「ポートレットコンテナ」によって管理される。Webブラウザがポータルにアクセスすると最初にこのポートレットコンテナが呼び出され、内部で管理するポータルを呼び出して画面を生成する。1つのページに複数のポートレットを表示することもできる。

サーブレットの仕組みにも似ているが、ポートレットはあくまでも画面の一部を構成するためのコンポーネントであり、それ単体で完結したアプリケーションにはならない。そのためURLでアクセスすることはできず、必ずポータルアプリケーションを介してアクセスすることになる。また、ポートレットはそれぞれ個別にライフサイクルを持ち、それはポートレットコンテナによって管理される。

JSR 168で興味深いのは、ポータルとポートレットはそれぞれ独立したアプリケーションとして構成されている点である。したがって、あるポートレットを別のポータルアプリケーションに持っていってそのまま利用することもできる。この高い相互運用性がポートレット仕様の特徴だ。

JSR 168の最終仕様は2003年の10月にリリースされているため、現在ではすでにこの仕様に準拠したアプリケーションが多数出回っている。参照実装はApache Foundationによって開発されている「Apache Pluto」で、現在はバージョン1.1.4が公開されている。今回はこのApache Plutoを使ってみよう。

Apache Plutoでポートレット開発

Apache Plutoの最新版はこのサイトからダウンロードできる。Webコンテナ付きで利用できるTomcatバンドル版(pluto-current-bundle.*)が用意されているので、今回はこれを使用する。

ファイルをダウンロードし、インストールしたい場所(以下、{$PLUTO_HOME}と記述)に展開する。中身は通常のTomcatであり、Apache Plutoの本体となるWebアプリケーションがすでに設定済みの状態で用意されている。{$PLUTO_HOME}/binディレクトリに移動して、startup.bat(Windowsの場合)またはstartup.sh(UNIXの場合)を実行すれば、Apache Plutoが有効になった状態のTomcatが起動する(プロンプト1)。

プロンプト1 Plutoの起動例(Windowsの場合)

{$PLUTO_HOME}\bin>.\startup.bat

この状態で「http://localhost:8080/pluto/portal」にアクセスすれば、Plutoで提供されるポータルアプリケーションのページ表示される。ログイン名とパスワードはどちらも「pluto」でアクセスできる(図1、図2)。

図1 ログイン名もパスワードも「pluto」でOK

図2 ログイン後のページ

停止するにはshutdown.batまたはshutdown.shを実行すればよい(プロンプト2)。

プロンプト2 Plutoの停止例(Windowsの場合)

{$PLUTO_HOME}\bin>.\startup.bat

ポータルアプリケーションもWebアプリケーションの一種なので、内部ではサーブレットを利用している。具体的には、ServletContextやServletRequest、ServletResponseがPortlet API(PortletContext、PortletRequest、PortletResponse)によってラップされ、ブラウザからのリクエストはポートレットコンテナに集約されて各ポートレットに振り分けられる。Plutoの場合、この機能は{$PLUTO_HOME}/webapps/plutoによって提供される。

ポータルだけでなくポートレットもWebアプリケーションの一種である。JSR 168では、サーブレットアプリケーションを作るのと同様の感覚でポートレットを作成することができる。ここではごく簡単なポートレットの作成例を紹介する。基本的な手順は通常のWebアプリケーション作成と同様で、ここでは「SamplePortlet」というプロジェクト名で作成することにする。

リスト1は「Hello Portlet!」と表示するだけのシンプルなポートレットである。JSR 168で提供されるポートレットの雛型であるGenericPortletクラスを元に作成している。doView()は表示用のメソッドで、リクエストをRenderRequest、レスポンスをRenderResponseとして受け取る。ここではRenderResponseからWriterを取得して文字を出力している。

リスト1 HelloWorldPortlet.java

package apisample.portlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class HelloWorldPortlet extends GenericPortlet {
    public void doView(RenderRequest request, RenderResponse response)
        throws PortletException, IOException {
        response.setContentType("text/html");
        response.setTitle("Hello World");
        PrintWriter writer = response.getWriter();
        writer.println("<h2>Hello Portlet!</h2>");
    }
}

WEB-INF/web.xmlにはリスト2のように記述する。1つ目のポイントはservlet-classにorg.apache.pluto.core.PortletServletを指定し、init-paramでポートレット名を指定する点である。もう1つのポイントはurl-patternの先頭に「/PlutoInvoker/」というパターンが付加されている点で、/PlutoInvoker/の後ろはポートレット名を指定する。

リスト2 WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

    <servlet> 
        <servlet-name>HelloWorldPortlet</servlet-name> 
        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class> 
        <init-param> 
            <param-name>portlet-name</param-name> 
            <param-value>HelloWorldPortlet</param-value> 
        </init-param> 
        <load-on-startup>1</load-on-startup> 
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloWorldPortlet</servlet-name>
        <url-pattern>/PlutoInvoker/HelloWorldPortlet</url-pattern>
    </servlet-mapping>

</web-app>

ポートレット本体の定義はWEB-INF/portlet.xmlというファイルにリスト3のように記述することで行う。ここではポートレット名に対応して呼び出されるポートレットのクラスを指定する。

リスト3 WEB-INF/portlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet" xmlns="http://java.sun.com/xml/ns/portlet">
    <portlet>
        <portlet-name>HelloWorldPortlet</portlet-name>
        <display-name>HelloWorld</display-name>
        <portlet-class>apisample.portlet.HelloWorldPortlet</portlet-class>
        <portlet-info>
            <title>Hello World</title>
        </portlet-info>
    </portlet>
</portlet-app>

これをコンパイルしてWARファイルを作成し、Tomcatにデプロイする。この時点でPlutoの管理ページである「Pluto Admin」ページを表示させると、図3のようにHellWorldPortletがポートレットとして選択できるようになっている。ここでは新たに「Hello World」というページを作成し、そこにHelloWorldPortletを1つだけ配置してみた。すると図4のように「Hello World」ページが追加され、これを選択すると図5のように表示される。

図3 「Pluto Admin」を表示すると「HellWorldPortlet」が選択できるようになっている

図4 いちばん右のタブに「Hello World」が追加されている

図5 「Hello World」タブを選ぶと「Hello Portlet!」が表示された