1 / 20
COIT20259 — Week 9

Facelets PDL &
Jakarta Faces Components

Comparing how the web can be built, then mastering the declarative language and component toolkit that Jakarta Faces gives you.
Enterprise Computing  ·  Press → to begin  ·  Press T for contents
2 / 20

This WeekLearning Objectives

By the end of this week you will be able to:

Building on Week 8
Last week we understood what Jakarta Faces is and its architecture. This week we go deeper — learning the exact language Facelets uses and the library of ready-made components at your disposal.
3 / 20
Section 1

Web Page Technologies: A Comparison

Before committing to any framework, good engineers ask: "What are my options, and when should I use each?" Let's compare the main approaches to building web pages.
4 / 20

Section 1.1Three Ways to Build a Web Page

Every web page ultimately reaches the browser as HTML. But how that HTML is produced varies greatly:

Static HTML Simple

You write the HTML directly. The file is sent to the browser as-is. Data never changes unless you edit the file.

Use when
Marketing pages, documentation, landing pages with no user data.
Server-Side Rendering Enterprise

The server builds the HTML page dynamically — data from a database is injected before sending to the browser. This is what Jakarta Faces does.

Use when
Data-driven apps, forms, dashboards, enterprise systems.
Client-Side (SPA) Modern

The browser downloads a JavaScript app that builds the page itself. The server only provides raw data (via APIs). Examples: React, Angular, Vue.

Use when
Highly interactive apps, real-time updates, mobile-first products.
5 / 20

Section 1.2Jakarta Faces vs Other Technologies

Criterion Raw HTML / JSP Jakarta Faces (Facelets) React / Angular (SPA)
Who builds the page? Developer writes HTML manually JF framework generates HTML from components Browser JavaScript builds it
Java integration Manual (JSP scriptlets — messy) Native — beans connect directly Via REST API calls
Reusable components? Limited (manual copy-paste) Yes — rich component library Yes — component ecosystem
Templating / layouts? No standard approach Built-in with Facelets templates Component composition
Best suited for Simple, small sites Enterprise Java applications Highly interactive modern UIs
Bottom Line
Jakarta Faces is the right choice when you are already in the Java ecosystem and need a full-stack framework with minimal configuration. It trades some UI flexibility for deep Java integration.
6 / 20

Section 1.3Why Facelets Replaced JSP

The older approach to Java web pages was JSP (JavaServer Pages). Facelets replaced it as the standard view technology for Jakarta Faces.

Problems with JSP

  • Mixed Java code and HTML — hard to read and maintain
  • No proper templating — every page repeated the header/footer
  • Compilation step required — slower development cycle
  • Browser couldn't display raw JSP pages for design review

Facelets improvements

  • Pure XML/HTML — no Java code in the page file
  • Built-in templating system — define once, reuse everywhere
  • No compilation — interpreted at runtime, faster iteration
  • Valid XHTML — designers can open pages in any browser
  • Better error messages — points to the exact line
Analogy
JSP was like writing instructions on the back of the finished painting. Facelets separates the blueprint (template) from the content — like a proper architect's drawing with labelled slots to fill in.
7 / 20
Section 2

Facelets Page Declaration Language

PDL is the formal name for the rules and syntax Facelets uses. Understanding PDL means understanding how to read and write any Facelets page correctly.
8 / 20

Section 2.1What Is a Page Declaration Language?

Definition
A Page Declaration Language (PDL) is a set of rules for declaring UI components in a page file. Facelets PDL extends standard HTML using XML namespaces to add Jakarta Faces-specific tags.

Think of it like this: HTML gives you a set of building blocks (<input>, <button>). Facelets PDL extends that vocabulary with smarter, Java-aware versions:

Plain HTMLFacelets PDL equivalentWhat makes it smarter
<input type="text"> <h:inputText value="#{bean.name}"/> Automatically binds to a Java property; handles validation
<button>Submit</button> <h:commandButton action="#{bean.save}"/> Calls a Java method; manages navigation outcome
<table>...</table> <h:dataTable value="#{bean.items}"/> Iterates a Java list automatically; generates rows
<span>text</span> <h:outputText value="#{bean.total}"/> Reads a Java value; supports formatters
9 / 20

Section 2.2XML Namespaces — The Key to PDL

Facelets pages are valid XML files. To use JF tags, you declare namespaces in the opening <html> tag — these tell the server which tags come from which library.

<html
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="jakarta.faces.html"          ← HTML components (inputs, forms, tables)
  xmlns:f="jakarta.faces.core"          ← Core tags (validators, converters, events)
  xmlns:ui="jakarta.faces.facelets"      ← Templating (define, insert, include)
  xmlns:c="jakarta.tags.core"           ← JSTL core (if/forEach logic)
>

How namespaces work

The prefix (h:, f:, ui:) is like a first name that tells JF which library owns the tag:

h:inputText → HTML input component
f:validateLength → Core validator
ui:insert → Template slot to fill
Important: Jakarta vs Java EE
Old code used http://xmlns.jcp.org/jsf/html. Modern Jakarta EE uses the short form jakarta.faces.html. Using the wrong one is a common student error — always use the jakarta. prefix.
10 / 20

Section 2.3Facelets Templating — Write Once, Reuse Everywhere

The most powerful feature of Facelets PDL is its templating system. Define a master layout once; every page just fills in the slots.

Template file (layout.xhtml)

Master Template
<h:head> — always the same </h:head>
Navigation bar — fixed across all pages
<ui:insert name="content">
  Default content (optional)
</ui:insert>
Footer — fixed across all pages

The ui:insert is the slot — a named hole that child pages fill in.

Child page (home.xhtml)

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

  <ui:define name="content">
    <!-- This fills the slot -->
    <h2>Welcome Home!</h2>
    <p>Today's date is
      <h:outputText
        value="#{bean.today}"/>
    </p>
  </ui:define>

</ui:composition>

ui:define provides the content for the named slot.

11 / 20

Knowledge CheckSection 2 — Facelets PDL

Q1: Your web application has 50 pages, all sharing the same navigation bar and footer. What is the most maintainable approach in Facelets?
Facelets templating is designed exactly for this. One template file defines the shared layout; each of the 50 pages only declares its unique content using ui:define. When you need to change the nav bar, you change it in exactly one place.
Q2: A student writes xmlns:h="http://xmlns.jcp.org/jsf/html" in their Facelets page. What is the likely problem?
Jakarta EE migrated from the javax.* / jcp.org namespaces to jakarta.* namespaces starting with Jakarta EE 9. Using the old URL on a GlassFish 7 / Jakarta EE 10 server will cause components to not be recognised.
12 / 20
Section 3

Developing with JF Components

Jakarta Faces ships with a rich library of ready-made components. Let's tour the four main component groups and see how to use them effectively.
13 / 20

Section 3.1The Four Component Groups

Jakarta Faces components are grouped by the namespace prefix that identifies them:

PrefixLibraryPurposeExamples
h: HTML Components Standard UI widgets rendered as HTML Forms, inputs, buttons, tables, links
f: Core Components Non-visual: validators, converters, events Validate email, format dates, AJAX
ui: Facelets Tags Templating and composition Templates, fragments, includes, repeat
c: JSTL Core Flow control logic in the page if-else conditions, forEach loops
Mental Model
Think of h: as your visible furniture (what users interact with), f: as the wiring behind the walls (invisible rules and behaviour), and ui: as the architectural blueprint (page structure).
14 / 20

Section 3.2HTML Components — The h: Library

Most-used h: components

h:form h:inputText h:inputSecret h:commandButton h:outputText h:outputLabel h:selectOneMenu h:selectManyCheckbox h:dataTable h:column h:messages h:link
Rule: Always wrap inputs in h:form
JF components that submit data must be inside an <h:form>, never a plain HTML <form>. The JF form adds state-tracking data that makes the framework work.
<!-- A complete login form -->
<h:form>

  <h:outputLabel
    for="email"
    value="Email:"/>
  <h:inputText
    id="email"
    value="#{loginBean.email}"/>

  <h:outputLabel
    for="pw"
    value="Password:"/>
  <h:inputSecret
    id="pw"
    value="#{loginBean.password}"/>

  <h:commandButton
    value="Login"
    action="#{loginBean.login}"/>

  <h:messages globalOnly="true"/>

</h:form>
15 / 20

Section 3.3Core Components — The f: Library

Core components are non-visual — they attach behaviour to other components. They are always nested inside an h: component.

Validators

Automatically check user input before it reaches your Java code:

<h:inputText
  value="#{bean.age}">
  <f:validateLongRange
    minimum="18"
    maximum="120"/>
</h:inputText>

<h:inputText
  value="#{bean.code}">
  <f:validateLength
    minimum="6"
    maximum="10"/>
</h:inputText>

Converters

Transform data between the String the browser sends and the Java type your bean expects:

<h:inputText
  value="#{bean.salary}">
  <f:convertNumber
    minFractionDigits="2"
    maxFractionDigits="2"/>
</h:inputText>

<h:outputText
  value="#{bean.birthDate}">
  <f:convertDateTime
    pattern="dd/MM/yyyy"/>
</h:outputText>
Why this matters
Without a converter, "12.5" (String) can't be assigned to a double field — JF would throw a conversion error.
16 / 20

Section 3.4Displaying Lists — The h:dataTable

h:dataTable is one of the most powerful JF components — it automatically generates an HTML table from a Java List.

How it works

  • value — points to your Java list (#{bean.products})
  • var — names the variable for each row item (p)
  • Each h:column is one table column
  • JF loops through the list automatically — you just describe one row
Analogy
Like a mail-merge in Word — you write the row template once, and Word (JF) repeats it for every record in the data source.
<!-- In the Facelet page -->
<h:dataTable
  value="#{productBean.products}"
  var="p"
  border="1">

  <h:column>
    <f:facet name="header">Name</f:facet>
    <h:outputText
      value="#{p.name}"/>
  </h:column>

  <h:column>
    <f:facet name="header">Price</f:facet>
    <h:outputText
      value="#{p.price}">
      <f:convertNumber
        type="currency"/>
    </h:outputText>
  </h:column>

</h:dataTable>
17 / 20

Section 3.5Conditional Rendering & Iteration

Sometimes you want to show or hide parts of a page, or repeat a block. JF gives you two approaches:

Using the rendered attribute

Every JF component has a rendered attribute. Set it to a boolean EL expression — the component only appears in the HTML when it evaluates to true.

<!-- Only show if logged in -->
<h:panelGroup
  rendered="#{userBean.loggedIn}">
  <h:outputText
    value="Welcome back!"/>
</h:panelGroup>

<!-- Show error only if present -->
<h:outputText
  value="#{bean.error}"
  rendered="#{not empty bean.error}"
  style="color:red"/>

Using ui:repeat

For repeating a block that isn't a table, ui:repeat is the Facelets way:

<!-- List of messages -->
<ul>
  <ui:repeat
    value="#{inbox.messages}"
    var="msg">
    <li>
      <h:outputText
        value="#{msg.subject}"/>
    </li>
  </ui:repeat>
</ul>
h:dataTable vs ui:repeat
Use h:dataTable when you want an HTML <table>. Use ui:repeat when you want to repeat any arbitrary block of HTML.
18 / 20

Section 3.6Showing Validation Messages to Users

When validation fails, JF generates FacesMessages. You must add a component to the page to display them — they don't appear automatically.

ComponentWhat it displays
<h:message for="fieldId"/> Error message for one specific input field
<h:messages/> All messages on the page in a list
<h:messages globalOnly="true"/> Only messages not tied to a specific field (e.g., "Login failed")
<h:inputText
  id="age"
  value="#{bean.age}">
  <f:validateLongRange
    minimum="18" maximum="99"/>
</h:inputText>
<!-- Shows error just for this field -->
<h:message for="age" style="color:red"/>
Form Output Age: [ 150 ] ✗ Value must be between 18 and 99 h:message fires JF skips phases 4 & 5 → Render Response Form re-rendered with error message visible
Validation failure flow: error shown, business logic never called.
19 / 20

Knowledge CheckSection 3 — JF Components

Q1: You need to display a list of 100 orders in a table with columns for Order ID, Date, and Total. Which component combination is correct?
h:dataTable is specifically designed to iterate over a Java List and generate an HTML table. You define the structure for one row; JF repeats it for all 100 orders. Raw HTML tables can't bind to Java data, and ui:repeat is for non-table blocks.
Q2: A user enters "abc" in a field expecting an integer. What happens in the JF lifecycle?
Type conversion happens during Phase 2-3. If "abc" can't be converted to an integer, JF creates a conversion error FacesMessage, skips Update Model (Phase 4) and Invoke Application (Phase 5), and goes straight to Render Response to show the error. Your business logic is never touched.
20 / 20

Week 9 SummaryWhat We Covered

Section 1 — Web Technologies
  • Static HTML, Server-Side, and SPA approaches
  • Why Jakarta Faces suits enterprise Java
  • Why Facelets replaced JSP
Section 2 — Facelets PDL
  • XML namespaces: h:, f:, ui:
  • Jakarta EE 10 namespace URLs
  • Template + composition pattern (ui:insert / ui:define)
Section 3 — JF Components
  • HTML components: forms, inputs, buttons
  • Core: validators & converters
  • Data tables, conditional rendering, messages
Coming Up — Week 10
We will move from individual components into building complete, integrated Jakarta Faces applications — connecting JF pages to EJB session beans and JPA-managed data from the database.
Lab Task This Week
Build a web interface using Facelets that displays a list of entities from the database using h:dataTable, includes a form to add new entries, and validates all inputs before saving.

Table of Contents