JavaEE7のJSF, Facelets, JSPの関係

JavaEEを使ったアプリ開発の際に、いつも気になるが後回しにしていたこと…
HTML5への対応方法の調査等、今後の理解促進のために、調べてみた。

FaceletsとJSFとの関係は?

JSFはWebアプリ開発のためのフレームワークであり、ページレンダリングの機能として、JSPやFaceletsを使っている。JSF1.2までは標準でJSPが使用されていたが、JSF2.0からはレンダリング性能や利便性を向上するためにFaceletsが利用される。

用語説明
JSP
(JavaServer Pages)
テンプレートからWebページを生成するための標準。
1999年に初版がリリースされており、既に古い標準になっている。
テンプレートの変更時やリロード時に、JSPコンパイラは、テンプレートからサーブレットのソースコードを生成する。このサーブレットをコンパイル・実行してページを生成する仕組み。
FaceletsJSFのために開発されたWebページテンプレート技術。
XMLベースのテンプレート(xhtml)をSAXベースコンパイラで処理するため、JSPと比較して高速にページ生成ができる。
Apache Tapestryと近い実装になっている。
JSF
(JavaServer Faces)
JavaベースのWebアプリケーションフレームワークである。
JSF1.2からJava EEに採用されている。
JSF1.2まではJSPを使用してたが、それ以降はFaceletsを使用するよう変更された。
(実現技術としてJSPを使用していたので、JSPを置き換える仕様というわけではないようだ。)

JSF/JSP/JavaEEの対応は次の通り。

JSFJavaEEJSFが利用するエンジン備考
JSF1.0/1.1JSPJSF仕様の初回リリース、バグフィックスリリース
JSF1.2JavaEE5JSP/FaceletsJSF1.2までJSPが標準。
設定変更でFaceletsも利用可。
JSF2.0JavaEE6FaceletsJSF2.0からFaceletsが標準
JSF2.2JavaEE7FaceletsHTML5対応

参考:
JSF 2.0 の新機能概要とFacelets テンプレートのご紹介 | 寺田 佳央 – Yoshio Terada


.jsp, .jsf, .xhtml等があるが、何を使うべきなのか?

JavaEE7(JSF2.0)以降を使用するのであれば.xhtmlを使用するべきである。
JSFを使用しない、後方互換等を考えるのであれば、.jsp/.jsfの使用も考慮する必要がある。

  • 拡張子: “.jsp”
    JSP用のファイル拡張子。
    この拡張子のファイルがリクエストされると、サーブレットコンテナに組み込まれているJspServletが当該ページをJSPとして処理する。
    web.xmlでのservlet-mappingによるリクエストパスとサーブレットとの対応付けは不要である。
  • 拡張子: “.jsf
    JSF1.2でよく使用されていた拡張子。
    JSF1.2を使用する際、次のようなweb.xmlの宣言が行われていた。
    “*.jsf”という仮想パスが要求された場合、FacesServletがサーブレットで処理を行う、という設定である。FacesServletはFaceletsの機能を実装したサーブレットであり、要求された仮想パスに対応する”.xhtml”ファイル(物理ファイル)を解析して、実際のページを生成して返却する。
    ユーザに見せるパスはあくまでも.jsfであり、セキュリティ上の理由で内部処理用の.xhtmlはユーザに見せない、という考えである。(この設定が行われない場合、ユーザがxhtmlファイルの中身を見ることができてしまう。)

    なお、JSF1.0/1.1との互換性を維持するために、”*.faces”や”/faces/*”がマッピングされる場合もある。

    参考だが、FacesServletが使用する物理ファイルは次のように変更可能である。(下記は.xhtmlではなく.xmlを使用する場合の例)

  • 拡張子: “*.xhtml”
    JSF2.0以降では*.xhtmlがFacesServletにマッピングされることになった。
    ページを作る際もアクセスする際もどちらも.xhtmlを使用する。
    (JSF1.2の時のように*.xhtmlをユーザに隠す必要はなくなった。)
    JSF1.2では次のように.xhtmlをFacesServletにマッピングする設定を行うと無限ループになってしまうが、JSF2.0以降では正しく動作する。

参考:
What is the difference between creating JSF pages with .jsp or .xhtml or .jsf extension – Stack Overflow
web.xml – Sometimes I see JSF URL is .jsf, sometimes *.xhtml and sometimes /faces/. Why? – Stack Overflow


JSF2.2のHTML5のサポートとは?

HTML5ではカスタムの要素や属性の定義が可能となった。
このようなHTML5の仕様に対応するために、JSF2.2では次の機能が追加された。

  • パススルー要素:
    HTML5の要素や属性をJSFコンポーネントと同様にサーバサイドのインスタンスに対応付けできる。次の例では、”jsf:”という名前空間を宣言し、input要素で”jsf:id=…”と使用している。結果として、この要素はサーバサイドでFacelets要素として扱われる。
  • パススルー属性:
    パススルー要素とは逆に、JSFコンポーネントで指定する属性をJSFコンポーネントの属性として処理しないように指定できる。
    次の例では、”p:”という名前空間を宣言し、JSFの属性として処理せずにそのままレンダリングする属性に対して、”p:type=..”, “p:min=…”等のように属性を指定している。
    なお、JSF2.1以前では、JSFコンポーネントに存在しない属性を指定した場合、レンダリングされない。名前空間”p:”はPrimeFacesで使用されることがあるため、混乱を避けるために”pt:”という名前空間を使う場合もある。

結果として開発者は、次のようにページ作成の方法を選択できる。
個人的には、これまでJavaEE6での実装を行っていたので、1.の方法に馴染んでいるが、HTML5の対応を進めるのであれば、2.の方法にも慣れていく必要がある。

  1. , 等のJSFコンポーネントを使った従来からのページ作成方法
  2. 上記のJSFコンポーネントのタグは使用せずに、HTML5を使ってページを作成する方法。HTML5の要素にて、JSFと対応付けをマークするための”jsf:id”等の属性を使用する。
  3. 上記の2つをミックスしたページ作成方法

参考:
8.9 HTML5-Friendly Markup – Java Platform, Enterprise Edition: The Java EE Tutorial (Release 7)
Custom HTML tag attributes are not rendered by JSF – Stack Overflow
HTML5とJSF, //enterprise java /


HTML5なのにxhtmlを使用するのか?

ブラウザはページ上のdoctypeでHTMLの種類は識別するので、ファイルの拡張子は重要ではない。
また、HTML5はXHTMLの要件を満たしているため、XHTMLファイル上にHTML5の記述をしても仕様上・実装上の問題はなく、既存のFacesServletを利用できる。

  • ブラウザはページの拡張子ではなく、doctypeに宣言された値に基づいて、対象ページがHTML5/HTML4.01/XHTML1.0等かを識別する。
  • faceletsは、特定のdoctypeの宣言を強制しない。faceletsとしては、どんなdoctypeが宣言されても関知しない。
  • JSF2.2ではHTML5をサポートするが、上記の通りパススルー要素/属性がメインの対応であり、やはりdoctypeについては関知しない。
  • XHTMLは、コンピュータで各種処理で処理しやすいよう、開始/終了タグの関係を厳密に定義すること期待する仕様になっている。HTML5では、人やコンピュータが処理しやすいよう、この要件を満たしているので、XHTMLでHTML5のタグを表現することは可能である。
    (厳密には、HTML5とXHTML1.0で異なる箇所もあるので完全な互換があるわけではない。)

参考:
jsf – JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used – Stack Overflow

番外

  • Mojjara: SunのJSFのリファレンス実装(JSF RI)。はGlassfishプロジェクトの一環で開発が進められた。1.2_08以降では、Glassfish以外でも利用できるようにしたのがMojjara。
  • 要素とタグ: 「タグ」とは、要素の開始/終了を示す識別子である。「要素」とは、開始から終了タグまで定義されるコンテンツを意味する。