ひこぽんのーと

覚書と雑記です。

JavaEE 7をやってみよう。 JSF テンプレートXML その3

JSF テンプレートについて補足。

JSF テンプレートXML その1でHTML画面の合成について書いたが、
その際に載せたHTMLがあんまり良くないらしい。

実行時に合成された画面のソースを表示してみると複数のBODYタグが含まれている。
というのも"画面パーツ"として掲載したHTMLはすべて、
HTMLタグから始まって、BODYタグなどをもつ、HTML4の形式で作った。
それらをJSFのテンプレートを通して合成しているので、
出来上がるページにはHTMLタグやBODYタグが複数存在してしまう。

それであっても、ブラウザは想定通りに画面を表示してしまうので、
無視していたのだが、後々、これが原因で問題が発生した。

必須入力チェックのエラーメッセージ表示処理を作成した際、
画面には正しくエラーメッセージが表示できるのだが、
その度にサーバーログに警告が書き込まれる、といった事象がそれ。

警告: FacesMessage がキューに入っていますが、表示されていません。

この警告をいくら調べても解決方法がわからない。
以前、バリデータの回ですでに確認済みの記法で書いたのに警告が出る。
しかも、バリデータの回ではこんな警告は出なかった。

結局のところ、テンプレートを使わずにHTMLを書いてみたら警告が出なくなったので、
画面合成に問題があることがわかった。

正しい合成の仕方としては、次のようになる。

  • 画面パーツとなるHTMLにはHTMLタグは使わない。
    すべてcompositionタグから始め、compositionタグに利用するxmlnsのURLを記載する。
  • HTMLタグやBODYタグはテンプレート用HTMLにだけ使用する。
  • FORMタグについてはテンプレートのみに持たせる方が無難。
    画面パーツにも持たせられるが、合成時には注意が必要。

そんなわけで、前回掲載したHTMLは以下のようにするのが正しいので、
修正版を掲載する。

[修正後のHTMLはこちら](クリックで開く)

  • jsf/layout/common/layout.xml
<!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://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
<ui:include src="/jsf/contents/common/htmlHeader.xhtml"/>
<ui:insert name="extHeader" />
<body>
    <h:form id="form1">
        <div id="wrapper">
            <div id="header">
                <div id="header_body">
                    <ui:include src="/jsf/contents/common/header.xhtml"/>
                </div>
            </div>
            <div id="contents">
                <ui:insert name="content" />
            </div>
            <div id="left-sidebar">
                <ui:include src="/jsf/contents/common/menu.xhtml"/>
            </div>
            <div id="footer">
                <ui:include src="/jsf/contents/common/footer.xhtml"/>
            </div>
        </div>
    </h:form>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Cache-Control" content="no-cache" />
    <title><ui:insert name="title">Default title</ui:insert></title>
    <h:outputStylesheet library="css" name="default.css" />
  </h:head>
</ui:composition>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html">
  <h:outputLabel value="#{staticText['site-title']}" />
</ui:composition>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html">
   <h:outputLabel value="#{staticText['copyright']}" />
</ui:composition>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html">
    <div>艦艇図鑑</div>
    <div>艦艇登録</div>
    <div>艦艇編集</div>
    <div>艦艇削除</div>
</ui:composition>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions"
      xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
      xmlns:x="http://java.sun.com/jsp/jstl/xml">
        <h2><h:outputLabel value="艦艇図鑑" /></h2>
        <h:dataTable var="item" value="#{warShipCat.allList}" styleClass="table" headerClass="headerrow" rowClasses="oddrow,evenrow">
            <h:column>
                <f:facet name="header">No.</f:facet>
                <h:outputText value="#{warShipCat.allList.rowIndex + 1}" />
            </h:column>
            <h:column>
                <f:facet name="header">艦種</f:facet>
                <h:outputText value="#{item.warshipType.name}" />
            </h:column>
            <h:column>
                <f:facet name="header">名前</f:facet>
                <h:outputText value="#{item.name}" />
            </h:column>
        </h:dataTable>
</ui:composition>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
        template="/jsf/layout/common/layout.xhtml">
    <ui:define name="title">#{staticText['warship.menu.lnkCatalog']}</ui:define>
    
    <ui:define name="content">
        <ui:include src="/jsf/contents/warship/content.xhtml"/>           
    </ui:define>
    
</ui:composition>