JSF2.0+JPA2.0+eclipse 構築編:JSFに触れる

JSFがちゃんと動いているかどうかを検証するために、ちょっとした動的ページを作ってみます。

拡張子の変更

前回までの設定でJSFのページには拡張子「.jsf」でアクセス出来るようにしていました。でもこれではサーバ側の実装がJSFというのがバレバレです。これまでにこれが問題になったケースは正直ないですが、カッコ悪いです。たまたま私が携わってきたのが企業向けのアプリ中心でURLにあまり気を使う必要がなかったのですが、今回はちゃんといいURLにしたいです。

なので以降は拡張子「.xhtml」でアクセス出来るようにします。これならテンプレートに直接アクセス出来なくなるので一石二鳥。

index.htmlは削除

もういらなくなりました。

参考ページ

下記を参考に。というか、ほとんど写経。
※PDF http://courses.coreservlets.com/Course-Materials/pdf/jsf/jsf2/JSF2-Basics-with-Annotations.pdf

動きの概要

start-page.xhtmlにアクセスすると入力欄とボタンがあります。ボタンを押すとpage1,page2,page3のいずれかに遷移します。遷移先ページにはstart-page.xhtmlで入力したテキストが表示されます。

xhtmlの作成

全部で4つ。page1.xhtml、page2.xhtml、page3.xhtmlはほぼ同じ内容です。

start-page.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" >
<head>
    <meta charset="UTF-8" />
    <title>Start Page</title>
</head>
<body>
    <fieldset>
        <legend>Random Result Page</legend>
        <h:form>
            Press button to 1 of 3 possible results page.
            <br/>
            <h:inputText value="#{simpleBean.value}" />
            <h:commandButton value="Go to Random page" action="#{simpleBean.doNavigation}" />
        </h:form>
    </fieldset>
</body>
</html>

このファイルで大事なのは

<h:commandButton value="Go to Random page" action="#{simpleBean.doNavigation}" />

という記述です。ボタンを押したら「simpleBean」というオブジェクトの「doNavigation」というメソッドが動きます。すごく直感的。初めて触りますが実に分かりやすいです。
「simpleBeanというオブジェクト」というのが若干謎ですが、これがManagedBeanというヤツでしょう。アノテーションでクラスを修飾しておくと、コンテナがいい感じでインスタンスを管理してくれる、と。ざっくりした理解ですが最初は小難しいことは考えずいきます。

page1.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" >
<head>
    <meta charset="UTF-8" />
    <title>Page1</title>
</head>
<body>
    <h1>Page1 #{simpleBean.value} </h1>
</body>
</html>

page2.xhtmlとpage3.xhtmlは省略します。

ManagedBeanの作成

さて今回のキモ、ManagedBeanの作成です。
ブラウザで入力した値を保持し、また、ボタンが押されたら動くメソッドを持ちます。
ここではsandbox.bean.SimpleBeanというクラスを作成します。
こんな感じ。

package sandbo.bean;

import javax.faces.bean.ManagedBean;

/**
 * @author jabaraster
 */
@ManagedBean
public class SimpleBean {

    private String value;

    /**
     * @return
     */
    public String doNavigation() {
        return new String[] { "page1", "page2", "page3" }[(int) (Math.random() * 3)];
    }

    /**
     * @return the value
     */
    public String getValue() {
        return this.value;
    }

    /**
     * @param pValue the value to set
     */
    public void setValue(final String pValue) {
        this.value = pValue;
    }
}

単純かつ直感的。

  • @ManagedBeanを付与すると、JSFがいい感じに面倒を見てくれるようになるみたい
  • doNavigationメソッドから遷移してほしいページ(URL?)を返すとクライアントはそのページに遷移するみたい
  • 画面からの入力値はプロパティを通してセットされるみたい

動作確認

Bootクラスを実行して下記のURLにアクセスしてみましょう。ちょっとわくわくします。。。
http://localhost:18080/start-page.xhtml

おお!画面が出た!

何か入力して「Go to Random page」ボタンを押すと、3つのページのどれかが表示されるはずです。

おお!画面が遷移した!
今回はpage1に遷移しましたね。

入力欄に < のようなHTML特殊文字を入れましたが、いい感じでエスケープしてくれてます。
というかなぜJSPエスケープをデフォルトの動きにしなかったのかがたいへん疑問です。

思ったこと

ごく単純なJSFアプリを作ってみましたが、いい感じです。直感的なのがいい。

ただ、複雑なアプリになってくると

  • コレクションの表示はどうやんの?
  • よく使うコンポーネントの共通化、どうやんの?
  • 入力値検証は?

などなどいろいろ気になりますね。

次は

JSFも気になるんですが、いったんここで置いておいてJPAのセットアップに入ろうと思います。
JPA周りはトラブルが多く発生しそうな気がして、「早めにとりかかった方がいいんでない?」という心の声が聞こえたもので。