【コラム】

Java API、使ってますか?

25 JSFとポートレットをつなげるJSR 301

25/60

JSR 301 - Portlet Bridge Specification for JavaServer Faces

JSF(JavaServer Faces)は、言わずと知れたWebアプリケーション開発のためのフレームワークであり、豊富なUIコンポーネントとモデルとなるJavaBeans(Managed Bean)との連携によって、インタフェース主導によるWebアプリケーションの開発をサポートする。一方でポートレットもUIに主眼を置いたフレームワークだが、こちらは画面の一部を構成するためのコンポーネントである。

JSR 301は、このJSFとポートレットを統合して、JSFアプリケーションを単体のポートレットとして動作させられるようにするブリッジ仕様である。これによって、JSFという高い実績を持つフレームワークによって作成されたアプリケーションが、ポータルアプリケーションの中で自由に利用できるようになる。JSFは広く使われている上にそれをサポートする技術も多く存在しており、これをポートレットとして利用できるメリットは大きい。

このアイデア自身は古くからあり、後述のOpenPortal JSF Portlet Bridgeなどのようにすでに独自の実装を行っているプロジェクトも存在する。しかし、それらの異なる実装 どうしに互換性がない場合、ポートレットの持つ高い相互運用性という特徴を最大限に活かすことができない。JSR 301は、JSFとポートレット間の統一的なブリッジ仕様を策定することによりこれら実装の振る舞いを標準化する目的で提案された。仕様策定にあたっては主に次の3つのエリアにフォーカスが当てられている。

  • 共存: このポートレートブリッジと非ポートレットベースのJSFアプリケーションが、お互いの動作を妨げない
  • 正当性: ポートレットとJSFの間にあるモデルの違いを適切に吸収する
  • 拡張性: JSFには存在しないポートレットの拡張的な機能に対する振る舞いを定義する

JSR 301は現行のポートレット仕様であるJSR 168をターゲットとしているが、次期仕様であるJSR 286もサポートされる予定である。本稿執筆時点では、ちょうどEarly Draft Review 2が行われている最中だ。

OpenPortal JSF Portlet Bridgeを試す

現在、すでにJSFアプリケーションをポートレットとして動作させるための実装がいくつかの団体から公開されており、JSR 301の仕様もそれらのアイデアをスタート地点として議論されるはずである。そこで今回はそのような実装の中から、OpenPotalプロジェクトによる「JSF Portlet Bridge」を試してみたい。

JSF Portlet Bridgeはこのページよりダウンロードすることができる。ポートレットコンテナとしてはOpenPotal Portlet Containerを利用する。Portlet ContainerをGlassFish上で動作させている場合はJSF 1.2に対応したJSF Portlet Bridge 1.2.xを、Sun Java System Portal Server 7やPlutoで動作させている場合は1.1.xを使用する。

第23回ではPlutoを利用しているので、今回はGlassFishを使ってみよう。したがってJSF Portlet Bridge 1.2.xの方をダウンロードする。

まずPortlet Conatiner(ファイル名portlet-container-configurator.jar)をGlassFishにデプロイする。コマンドラインからプロンプト1のように実行する。

プロンプト1

> java -jar portlet-container-configurator.jar

図1のようなウィンドウが表示されるので、GlassFishのインストール先とドメインディレクトリのパスを入力し、[Ok]をクリックする。デプロイに成功したら[Quit]を押せばインストール完了となる。

図1 Portlet Containerのインストール

さて、今回はJSFアプリケーションをポートレットとして動作させるので、まずはベースとなるJSFアプリケーションを作ってから、それをポートレット対応にするという手順で進めていこう。JSFアプリケーションは身長と体重を入力したらBMI値を計算してくれるというもので、入力ページ、結果の出力ページ、Managed Beanはそれぞれリスト1、リスト2、リスト3のようにした。JSFに関する詳細な解説は省略させていただく。

リスト1 身長と体重の入力ページ

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSF-Portletブリッジのサンプル</title>
    </head>

    <body>

        <f:view>
            <h:form>
                <h2><h:outputText value="身長と体重を入力して下さい。"/></h2>
                <h:outputText value="身長:"/>
                <h:inputText id="inputHeight" value="#{CalculateBMI.height}"/>
                <h:outputText value="メートル "/>
                <h:outputText value="体重:"/>
                <h:inputText id="inputWeight" value="#{CalculateBMI.weight}"/>
                <h:outputText value="キログラム "/>
                <h:commandButton id="Submit" value="入力" action="success"/>
            </h:form>

        </f:view>

    </body>
</html>

リスト2 計算結果の出力ページ

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSF-Portletブリッジのサンプル</title>
    </head>

    <body>

        <f:view>
            <h:form>
                <h2><h:outputText value="計算結果:"/></h2>
                <h:outputText value="BMI値は "/>
                <h:outputText id="outputBMI" value="#{CalculateBMI.bmi}"/>
                <h:outputText value=" です。"/>
                <h:commandButton id="Submit" value="戻る" action="success"/>
            </h:form>

        </f:view>

    </body>
</html>

リスト3 CalculateBMI.java - BMI値を計算するManaged Bean

package apisample.jsfportlet;

import java.math.BigDecimal;

public class CalculateBMI {
    private double height;
    private double weight;
    private double bmi;

    public CalculateBMI() {
    }

    public void setHeight(double height) {
        this.height = height;
    }
    public double getHeight() {
        return this.height;
    }
    public void setWeight(double weight) {
        this.weight = weight;
    }
    public double getWeight() {
        return this.weight;
    }
    public double getBmi() {
        double tmpBmi = this.weight / Math.pow(this.height, 2);
        BigDecimal bd = new BigDecimal(String.valueOf(tmpBmi));
        this.bmi = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return this.bmi;
    }
}

faces-config.xmlにはManaged Beanの設定と、入力ページと出力ページへの遷移を定義してリスト4のようにする。

リスト4 WEB-INF/faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>
    <navigation-rule>
        <from-view-id>/input.jsp</from-view-id>
        <navigation-case>
            <from-outcome>success</from-outcome>
            <to-view-id>/output.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/output.jsp</from-view-id>
        <navigation-case>
            <from-outcome>success</from-outcome>
            <to-view-id>/input.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>

    <managed-bean>
        <managed-bean-name>CalculateBMI</managed-bean-name>
        <managed-bean-class>apisample.jsfportlet.CalculateBMI</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

</faces-config>

web.xmlはリスト5のようになる。

リスト5 WEB-INF/web.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>
    <navigation-rule>
        <from-view-id>/input.jsp</from-view-id>
        <navigation-case>
            <from-outcome>success</from-outcome>
            <to-view-id>/output.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/output.jsp</from-view-id>
        <navigation-case>
            <from-outcome>success</from-outcome>
            <to-view-id>/input.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>

    <managed-bean>
        <managed-bean-name>CalculateBMI</managed-bean-name>
        <managed-bean-class>apisample.jsfportlet.CalculateBMI</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

</faces-config>

以上を「JSFPortletSample」というアプリケーション名で作成したとすると、WARファイルの構成は図2のようになる。

図2 JSFPortletSample.warの構成

これをGlassFishにデプロイし、Webブラウザから「http://localhost:8080/JSFPortletSample/faces/input.jsp」にアクセスすると図3のように表示される。身長と体重を入力して[入力]をクリックすると、BMI値が計算されて図4のように結果が表示される。

図3 身長と体重の入力

図4 結果の出力

さて、これをJSF Portlet Bridgeを利用してポートレットとして動作させたい。まず、ダウンロードした「jsf-portlet.jar」をアプリケーションディレクトリに配置する。その上で、WEB-INF/ディレクトリにportlet.xmlを作成し、ここにポートレットの設定を記述する。ここではリスト2.11のようにした。

基本的な部分は第23回で紹介した通りだが、には必ず「com.sun.faces.portlet.FacesPortlet」と指定する。にはこのポートレットでサポートするモード(VIEW/EDIT/HELP)を指定できる。そして各モードの初期ページをに設定する。

リスト6 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/portlet-app_1_0.xsd 
                        http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" 
    xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" >

    <portlet>
        <portlet-name>jsfportlet</portlet-name>
        <display-name>JSF Portlet</display-name>
        <portlet-class>com.sun.faces.portlet.FacesPortlet</portlet-class>

        <init-param>
          <description>Portlet init page</description>
          <name>com.sun.faces.portlet.INIT_VIEW</name>
          <value>/input.jsp</value>
        </init-param>

        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>VIEW</portlet-mode>
        </supports>

        <portlet-info>
            <title>JSF Portlet</title>
        </portlet-info>
    </portlet>

</portlet-app>

最後に、JSPページから のタグを削除し、かわりにポートレットのためのタグを追加する(リスト7、リスト8)。

リスト7 修正後のinput.jsp

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@ taglib uri="http://java.sun.com/jsf/portlet/components" prefix="p" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<f:view>
    <p:portletPage>
        <h:form>
               <h2><h:outputText value="身長と体重を入力して下さい。"/></h2>
               <h:outputText value="身長:"/>
               <h:inputText id="inputHeight" value="#{CalculateBMI.height}"/>
               <h:outputText value="メートル "/>
               <h:outputText value="体重:"/>
               <h:inputText id="inputWeight" value="#{CalculateBMI.weight}"/>
               <h:outputText value="キログラム "/>
               <h:commandButton id="Submit" value="入力" action="success"/>
           </h:form>
   </p:portletPage>           
</f:view>

リスト8 修正後のoutput.jsp

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@ taglib uri="http://java.sun.com/jsf/portlet/components" prefix="p" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<f:view>
    <p:portletPage>
           <h:form>
               <h2><h:outputText value="計算結果:"/></h2>
               <h:outputText value="BMI値は "/>
               <h:outputText id="outputBMI" value="#{CalculateBMI.bmi}"/>
               <h:outputText value=" です。"/>
               <h:commandButton id="Submit" value="戻る" action="success"/>
           </h:form>
   </p:portletPage>           
</f:view>

以上で修正は完了だ。JSFPortletSample.warの構成は図5のようになる。

図5 修正後のJSFPortletSample.warの構成

これをPortlet Containerにデプロイする。前回行ったように、Webブラウザから「http://localhost:8080/portletdriver/admin」にアクセスし、図6の画面からポートレットをデプロイする。

図6 ポートレットのデプロイメント

デプロイに成功したら、[ポートレット]タグのページを表示させると図7のように先ほど作成したJSFアプリケーションがポートレット内で動作しているはずだ。図8のようにBMI値の計算も有効になっているのがわかる。

図7 JSFアプリケーションがポートレットとして動作

図8 Managed Beanの動作も有効

なお、OpenPortal JSF Portlet BridgeではすでにJSR 301に準拠した実装を開発する作業が始められている。

25/60

インデックス

連載目次
第60回 どうなる? 今後のJavaプラットフォーム(Java SE編)
第59回 どうなる? 今後のJavaプラットフォーム(Java EE編)
第58回 Java SE 7の要注目機能"クロージャ"はどうなるのか その6
第57回 Java SE 7の要注目機能"クロージャ"はどうなるのか その5
第56回 Java SE 7の要注目機能"クロージャ"はどうなるのか その4
第55回 Java SE 7の要注目機能"クロージャ"はどうなるのか その3
第54回 Java SE 7の要注目機能"クロージャ"はどうなるのか その2
第53回 Java SE 7の要注目機能"クロージャ"はどうなるのか
第52回 Early Draftが公開されたJSF 2.0
第51回 EJBから独立したJava Persistence 2.0
第50回 モバイルJavaの新しい潮流となるか - MSA 2.0のドラフト公開
第49回 やっぱり基本はServlet - Servlet 3.0のEarly Draftを読む
第48回 JOGLで3Dプログラミング その4
第47回 JOGLで3Dプログラミング その3
第46回 JOGLで3Dプログラミング その2
第45回 JOGLで3Dプログラミング
第44回 JARファイルを効率的にネットワーク転送するためのPack200形式
第43回 Early Draftで把握するEJB 3.1の新機能
第42回 次世代の携帯端末向けJava仕様"MIDP 3.0"はどうなるか その2
第41回 次世代の携帯端末向けJava仕様"MIDP 3.0"はどうなるか その1
第40回 リソースアダプタによる接続の仕組み
第39回 JCAを利用したシステム間接続
第38回 Java EEと外部システムの接続性を支えるJCAがバージョンアップ
第37回 Javaのモジュラリティ強化を担う"スーパーパッケージ"とは
第36回 JSR 308対応のコンパイラを試す
第35回 公開されたJSR 308のEarly Draftを検証する
第34回 スクリプト言語とJavaを結びつけるJSR 223
第33回 Java EE環境に統一されたコンポーネントモデルを提供するJSR 299 その2
第32回 Java EE環境に統一されたコンポーネントモデルを提供するJSR 299 その1
第31回 Javaの文法がそのまま使えるスクリプト言語"BeanShell"
第30回 Javaアプリケーションにオブジェクトのキャッシュ機構を提供するJCache API
第29回 Javaアプリケーションからのリソース管理を可能にするJSR 284
第28回 XMLデータソースへの問い合わせはJSR 225で
第27回 Portlet Specification 2.0をもっと手軽に利用する
第26回 次期Javaポートレット仕様となるJSR 286
第25回 JSFとポートレットをつなげるJSR 301
第24回 Webサービス向けのポートレット仕様「WSRP」
第23回 高い相互運用性を実現するポートレットAPI - JSR 168
第22回 Java EE環境でタスクのスケジューリングを可能にするJSR 236
第21回 Java EE環境でのスレッドプログラミングを可能にするJSR 237
第20回 音声認識/合成のためのAPI - Java Speech APIとJSR 113
第19回 JSR 291でJavaプラットフォームにダイナミックコンポーネントモデルを導入
第18回 JAX-RSで簡単RESTful - JSR 311
第17回 待望のServlet 3.0がJSRに登場 - JSR 315
第16回 アノテーションを使ってバグ退治 - JSR 305
第15回 アノテーションをさらに広い範囲で利用可能にするJSR 308
第14回 Webアプリケーション開発の要となるか - JSF 2.0がJSRに登場
第13回 Webサービス経由でのJMX Agentへの接続を可能にするJSR 262
第12回 Javaアプリケーションのモジュール化をサポートするJava Module System
第11回 "NIO.2"がやってきた - JSR 203: More New I/O APIs for the Java Platform
第10回 JSR 295: Beans Bindingの参照実装を試す
第9回 けっこう便利! 単位を扱うAPI -- JSR 275: Units Specification
第8回 アノテーションでバリデーション - JSR 303: Bean Validator
第7回 Swing開発の救世主となるか - Swing Application Framework
第6回 JavaBeansのプロパティを同期させるバインディングAPI
第5回 誰よりも早く"Java SE 7"を睨む
第4回 日時情報の取り扱いを改善する JSR 310: Date and Time API
第3回 古いAPIも進化している!? - JSR 919: JavaMail 1.4
第2回 JSR 1 リアルタイムJava仕様
第1回 JCPによって進められるJava関連技術の標準化

もっと見る

提供:マイナビ

会員登録はこちら

大学・大学院・短大・専門学生向けの就職情報サイト「マイナビ2010」「マイナビ2009」に今すぐ登録しよう!  大手企業からベンチャー企業までの約13,000社の企業情報を公開、エントリーが可能です。2010年卒予定の方は「マイナビ2010」に、2009年卒予定の方は「マイナビ2009」に登録してください。

毎日コミュニケーションズはプライバシーマークを取得しています。



人気記事

一覧

イチオシ記事

新着記事