Challenge Engineer Life !

エンジニア人生を楽しみたい!仕事や趣味で学んだ技術的なことを書いていくブログです。

Java EE 7のJSF2.2で「Resource Library Contracts」チュートリアルをやってみました

JSF2.2で「Big Ticket」と呼ばれる機能には以下の4つがあります。
(JSF2.2のJSRより)

  • HTML 5 Friendly Markup
  • Resource Library Contracts
  • Faces Flows
  • Stateless Views

2つ目の「Resource Library Contracts」に関して8/2にUS Oracleからチュートリアルが
出たようなのでやってみました。元々は「Multi-Templating」とわかりやすくカッコいい
名前だったものですが、どういう経緯で変わったかはよくわかってないです(^^;

チュートリアルのリンク
Oracle Learning Library : Java EE 7: Applying JSF 2.2 Resource Library Contracts

アクセスすると以下のようなページが表示されるので「Begin Tutorial」を押します。

f:id:kikutaro777:20130803192521j:plain

以下のページが表示され、各ステップがバルーン式になっているので、上からやっていきます。

f:id:kikutaro777:20130803192600j:plain

細かく確認したい方は是非直接チュートリアルベースに進めてください(^^;
ここでは抜粋というか、自分がやったメモ書きレベルで、翻訳をするわけではありませんm(_ _)m

追記:投稿してから「今日書いた量多いな…」と思ったのですが、手順を細かく書いただけで、やってることは単純です。JSFにおいて複数のテンプレートとCSSを用意して、それを動的にスイッチできるようにしてるだけです(^^)使うの面倒くさそうと思われませんように…

Overview

目安としては45分くらいでできるチュートリアルとのこと。
実際そんなにはかからない気もしますが(^^;

必要な環境としては

とありますが、Java SEは7u25かなと(^^;
昨日公開になったチュートリアルですが、たぶんその当時に書いたんですかね…今年は
updateが多すぎる(-_-;

ベースとなるコードはダウンロードできるようになっており「Prerequisites(必須条件)」にリンクがあります。

f:id:kikutaro777:20130803192906j:plain

リンクをクリックして「JSFTemplateExampleApp.zip」を落とします。
解凍したフォルダをNetBeansProjects配下などに置きます。

f:id:kikutaro777:20130803192942j:plain

NetBeans7.3.1を立ち上げて以下手順でプロジェクトファイルを読み込みます。

f:id:kikutaro777:20130803193107j:plain

f:id:kikutaro777:20130803193112j:plain

f:id:kikutaro777:20130803193119j:plain

読み込めたら実行してみます。

以下のようなページが初期表示されて、adminページへのリンクとuserページへのリンクがあります。
f:id:kikutaro777:20130803193132j:plain

adminページは
f:id:kikutaro777:20130803193207j:plain

userページは
f:id:kikutaro777:20130803193215j:plain

テンプレートでcssを読み込んでいて
f:id:kikutaro777:20130803193721j:plain

すべて同じテンプレートを利用している構成になってます。
f:id:kikutaro777:20130803193645j:plain

ではResource Library Contractsで複数のテンプレート、CSSを扱えるようにしていきます。

contractsフォルダの作成

以下のようにcontractsという名称のフォルダを作成します。
ここに各種templateやcssを突っ込んでいくようです。

プロジェクトの「Webページ」を右クリックして「新規」から「その他」を選びます(フォルダが選択肢にあればそれを選択)
f:id:kikutaro777:20130803193814j:plain

カテゴリ「その他」のファイル・タイプ「フォルダ」を選択します
f:id:kikutaro777:20130803194009j:plain

フォルダ名「contents」で終了します。
f:id:kikutaro777:20130803194032j:plain

追加されればOKです。
f:id:kikutaro777:20130803194044j:plain

contractsフォルダ配下にサブフォルダ作成

contractsフォルダを右クリックして、先ほど同様に新規(サブ)フォルダを追加します。
blue,green,redと3つ追加します。

f:id:kikutaro777:20130803194606j:plain

resources配下をコピー

resourcesフォルダの配下にあるcssとテンプレートをコピーします。
f:id:kikutaro777:20130803195406j:plain

blue,green,redのフォルダにペーストします。
f:id:kikutaro777:20130803195525j:plain

f:id:kikutaro777:20130803195531j:plain

cssとtemplate.xhtmlを一部変更

ペーストしたcssLayout.cssを一部書き換えます。
書き換える対象はblueとgreenフォルダのcssのみです。

フォルダ #top background-color .center_content
blue #0000FF #C0F7F9
green #03FF71 #F3C7F7

以下のような感じです(blueの場合)
f:id:kikutaro777:20130803200330j:plain

さらにgreenの配下にあるdefault.cssに以下を追加します。

h3 {
    font-family: Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif;
    border-bottom: 1px solid #AFAFAF; 
    font-size:  10px;
    font-weight: bold;
    margin: 0px;
    padding: 0px;
    color:#FF0314;
}

blue,green,redの配下にあるtemplate.xhtmlでlinkタグのパスを変更します。

blueの場合

<link href="${facesContext.externalContext.requestContextPath}/resources/default.css" 
             rel="stylesheet" type="text/css" />
<link href="${facesContext.externalContext.requestContextPath}/resources/cssLayout.css" 
             rel="stylesheet" type="text/css" />

<link href="${facesContext.externalContext.requestContextPath}/contracts/blue/default.css" 
             rel="stylesheet" type="text/css" />
<link href="${facesContext.externalContext.requestContextPath}/contracts/blue/cssLayout.css" 
             rel="stylesheet" type="text/css" />

green,redもパスに合わせて同様に修正します。

resourcesフォルダ削除

resourcesフォルダを削除します。
f:id:kikutaro777:20130803201349j:plain

というわけで、contractsの配下に置いた3パターンのcssやtemplateがリソースとして使うという流れです。

templateの参照を修正

resourcesフォルダを削除したので、以下の5ファイル

の中で定義されているtemplateへの参照を以下変更します。

<ui:composition template="/resources/template.xhtml">

<ui:composition template="/template.xhtml">

faces-config.xmlの変更

faces-config.xmlを以下のapplicationタグを追加します。

<faces-config version="2.2"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
    <application>
        <resource-library-contracts>
            <contract-mapping>
                <url-pattern>/admin/*</url-pattern>
                <contracts>blue</contracts>
            </contract-mapping>
            
             <contract-mapping>
                <url-pattern>/user/*</url-pattern>
                <contracts>green</contracts>
            </contract-mapping>

            <contract-mapping>
                <url-pattern>*</url-pattern>
                <contracts>red</contracts>
            </contract-mapping>
        </resource-library-contracts>
    </application>
</faces-config>

マッピングは基本的に名前で行われるようですね(^^;

CDI管理対象Bean追加

テンプレートを動的に変更するためにCDI管理対象Beanを追加します。

まずはパッケージとして「com.example.beans」を以下の手順で追加します。

プロジェクトの「デフォルト・パッケージ」を右クリックして「新規」メニューから「その他」を選択します。
f:id:kikutaro777:20130803203130j:plain

カテゴリ「Java」のファイル・タイプ「Javaパッケージ」を選択して「次へ」
f:id:kikutaro777:20130803203135j:plain

パッケージ名「com.example.beans」を入力して「終了」します。
f:id:kikutaro777:20130803203140j:plain

続けて、作成されたパッケージを右クリックして「新規」「その他」から
カテゴリ「JavaServer Faces」ファイル・タイプ「JSF管理対象Bean」を選択します。
f:id:kikutaro777:20130803203850j:plain

TemplateBeanというクラス名にして、SessionScopedを選択します。
f:id:kikutaro777:20130803203907j:plain

※なぜか自分の環境だと以下エラーが出ました(-_-;あり
f:id:kikutaro777:20130803204022j:plain
クラスはできてるのですが、管理対象になってないPOJO…原因不明です。

まあ、自力で書けばいいので以下定義にします(^^;

package com.example.beans;

import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class TemplateBean implements Serializable{

    private String contract = "red";

    public String getContract() {
        return contract;
    }

    public void setContract(String contract) {
        this.contract = contract;
    }
}

index.xhtmlを変更

画面でテンプレートの切り替え選択ができるように、トップページのindex.xhtmlを以下定義とします。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <body>
            <ui:composition template="/template.xhtml">
                <ui:define name="content">
                    <a href="#{facesContext.externalContext.requestContextPath}/faces/admin/index.xhtml">Go to</a> Admin Page
                  
                    <h:panelGrid columns="1">
                        <p/>
                        <h2> Welcome to Home Page of ExampleApp Application </h2>
                        <p/><p/>
                        Choose a template for User Page:<br/>

                        <h:form>
                            <h:selectOneRadio value="#{templateBean.contract}" layout="pageDirection" required="true">
                                <f:selectItem itemValue="red" itemLabel="Red Header and Grey Body"/>
                                <f:selectItem itemValue="green" itemLabel="Green Header and Mauve Body"/>
                            </h:selectOneRadio>
                            <h:commandButton value="Apply" action="/user/index" />
                        </h:form>
                    </h:panelGrid>
                </ui:define>
            </ui:composition>
    </body>
</html>

viewタグ追加

長かったですが、これが最後です。
以下2ファイル

に以下の位置にviewタグを追加します。

<f:view contracts="#{templateBean.contract}">
            <ui:composition template="/template.xhtml">
...
</f:view> <!-- ←bodyタグの手前に-->

実行!

さてやっとこ…終わった(^^;ふぅ

実行すると以下の画面が表示されます。

f:id:kikutaro777:20130803210555j:plain

まずは上にあるadminへのリンクを押してみます。

f:id:kikutaro777:20130803210626j:plain

blueフォルダのtemplateとCSSで表示されてます。

ではまたトップ画面に戻って、ラジオボタンの選択を下に変更します。

f:id:kikutaro777:20130803210700j:plain

Applyボタンを押下すると

f:id:kikutaro777:20130803210711j:plain

greenフォルダのtemplateとCSSで表示されています。

チュートリアルの修正

表示されたのを見て気づきましたが、チュートリアルのほうではヘッダの文字がちゃんと「Red」「Blue」「Green」と変わってますが、その手順はなかったような…(見逃していたらすみません)

というわけで、一応、それぞれのテンプレートを書き換えて再度実行。

ヘッダの文言を「赤」に修正
f:id:kikutaro777:20130803211248j:plain

ヘッダの文言を「青」に修正
f:id:kikutaro777:20130803211254j:plain

ヘッダの文言を「緑」に修正
f:id:kikutaro777:20130803211258j:plain

というわけで、ちゃんと複数のテンプレートがつかえています(^^)

「PrimeFacesのテーマも似たようなことできるじゃん?」と一瞬思うかもしれませんが、テーマではCSSを変えることはできても、テンプレートを動的に変えることはできなかったので、そこが大きく違うかと思います。

関連情報

以下サイト辺りにResource Library Contractsに関する情報があります。

J-Development
What’s new in JSF 2.2?
http://jdevelopment.nl/jsf-22/

Arun Gupta's Weblog
Resource Library Contracts in JSF2.2
https://blogs.oracle.com/arungupta/entry/resource_library_contracts_in_jsf2

The Java EE 7 Tutorial
8.8 Resource Library Contracts
http://docs.oracle.com/javaee/7/tutorial/doc/jsf-facelets008.htm

にほんブログ村 IT技術ブログへ
にほんブログ村 にほんブログ村 IT技術ブログ Javaへ
にほんブログ村