Java

Getting Started with Jakarta Faces

Jakarta Faces, formerly known as JavaServer Faces (JSF), is a powerful framework for building user interfaces for Java web applications. It simplifies the development process by providing a component-based model for building UIs, along with a set of standard components and lifecycle management. If you are new to Jakarta Faces and want to explore its capabilities, this guide will help you get started.

1. Understanding Jakarta Faces

Jakarta Faces is a framework that simplifies the creation of user interfaces for Java web applications. It follows the MVC (Model-View-Controller) architecture, where views represent the UI components, and the application logic resides in the controller and model layers.

A Jakarta Faces application typically consists of the following components:

  • UI Components: These are the visual elements used to create the user interface of the application, such as buttons, input fields, tables, and dropdown menus.
  • Managed Beans: These are Java classes that manage the application’s business logic and interact with the UI components. Managed beans are responsible for handling user input, processing data, and controlling navigation within the application.
  • Navigation Rules: These define how users navigate between different views or pages within the application.
  • Facelets Templates: Facelets is a templating language used in Jakarta Faces to define the layout and structure of web pages. Facelet templates provide a reusable way to define the structure of multiple pages within the application.
  • Configuration Files (Optional): Jakarta Faces applications may include configuration files such as faces-config.xml which contain metadata about the application’s managed beans, navigation rules, and resource mappings.
  • Validators and Converters: Jakarta Faces provides built-in validators and converters to validate user input and convert data between different formats.
  • Application Deployment Descriptor (Optional): This is a configuration file (web.xml) that specifies deployment settings and servlet mappings for the Jakarta Faces application. It defines how the application should be deployed and accessed within an application server environment.

1.1 Setting Up Jakarta Faces

We need to set up our development environment. Make sure you have the following installed:

  • Java Development Kit (JDK) 8+.
  • An IDE (Integrated Development Environment) such as IntelliJ IDEA, Eclipse, or NetBeans.
  • Jakarta Faces libraries or jakarta.jakartaee-web-api maven dependency.

1.2 Getting Started

  • Access Eclipse Starter For Jakarta EE: Start by visiting start.jakarta.ee in your web browser. You will be greeted by a simple and intuitive user interface.
  • Customize Your Project: On the homepage, you will find various options to customize your project. You can specify the Jakarta EE version, Jakarta EE profile, Java SE version and runtimes (GlassFish, WildFly, Payara, TomEE, OpenLiberty).
  • Generate Your Project: Once you have configured your project, hit the “Generate” button. This will create a downloadable ZIP file containing your project structure.
  • Set Up Your Project: Extract the downloaded ZIP file to your desired location on your local machine. You will find a Maven project with some dependencies depending on your choice during customization.
  • Import into Your IDE: Open your preferred Integrated Development Environment (IDE) such as IntelliJ IDEA, Eclipse, or Netbeans and import the project.
  • Start Coding: With the project imported into the IDE, you are set to start coding! You will find a basic project structure with the dependencies you selected, allowing you to focus on implementing your application logic without worrying about boilerplate setup.

The project’s pom.xml file should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.eclipse</groupId>
	<artifactId>my-faces-app</artifactId>
	<version>0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>my-faces-app</name>
	<description>
		This is a very simple Jakarta EE application generated by the official Eclipse Starter.
	</description>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
		<maven.compiler.release>11</maven.compiler.release>
		<jakartaee-api.version>10.0.0</jakartaee-api.version>
		<compiler-plugin.version>3.11.0</compiler-plugin.version>
		<war-plugin.version>3.4.0</war-plugin.version>
		<cargo.version>1.10.11</cargo.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>jakarta.platform</groupId>
			<artifactId>jakarta.jakartaee-web-api</artifactId>
			<version>${jakartaee-api.version}</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>my-faces-app</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${compiler-plugin.version}</version>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>${war-plugin.version}</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>

			<!-- Execute 'mvn clean package cargo:run' to run the application. -->
			<plugin>
				<groupId>org.codehaus.cargo</groupId>
				<artifactId>cargo-maven3-plugin</artifactId>
				<version>${cargo.version}</version>
				<configuration>
					<container>
						<containerId>glassfish7x</containerId>
						<zipUrlInstaller>
							<url>https://repo.maven.apache.org/maven2/org/glassfish/main/distributions/web/7.0.12/web-7.0.12.zip</url>
                                                </zipUrlInstaller>
					</container>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

1.3 Enable/Activate Faces

The Faces Servlet acts as the entry point for processing JSF requests. Create a Java Class and add the following code. Having the @FacesConfig annotation on a class utilized within an application ensures the activation of Jakarta Faces and its CDI-specific functionalities.

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.faces.annotation.FacesConfig;

@FacesConfig()
@ApplicationScoped
public class FacesActivator {
    
}

1.4 Using web.xml

We can also rely on the web.xml descriptor for configuration. Locate the <servlet> element within web.xml and add the following:

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>	

<servlet-name> defines a name for the servlet. <servlet-class> specifies the FacesServlet class that handles JSF requests. <load-on-startup>1</load-on-startup> ensures the servlet loads during application startup.

1.4 Servlet Mapping

Jakarta Faces uses the Faces Servlet to handle specific URL patterns. Add a <servlet-mapping> element after the <servlet> definition like this:

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

This configuration instructs the servlet to handle requests ending with .xhtml extension, commonly used for JSF views. We can adjust the pattern based on our view naming convention.

1.5 Extensionless Mapping

JSF 4.0 introduces extensionless mapping, allowing us to access views without the .xhtml extension. To enable this, add the following context parameter to the web.xml file:

<context-param>
    <param-name>jakarta.faces.AUTOMATIC_EXTENSIONLESS_MAPPING</param-name>
    <param-value>true</param-value>
</context-param>

1.6 Add beans.xml File

Create a beans.xml file and place the file within the src/main/webapp/WEB-INF directory.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
       bean-discovery-mode="annotated"
       version="4.0">
</beans>

1.7 Add PrimeFaces

PrimeFaces is a popular open-source UI component library for JavaServer Faces (JSF) applications, providing a rich set of components for building modern web applications. Integrating PrimeFaces into the project is a straightforward process, and with the ability to apply themes, we can enhance the visual appeal of our web application effortlessly.

1.7.1 Adding PrimeFaces Dependencies

To add PrimeFaces dependencies to the pom.xml file, open the pom.xml file located at the root of the project directory and add the following dependencies:

        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>10.0.0</version>
        </dependency>

1.7.2 Apply PrimeFaces Themes

PrimeFaces provides a variety of built-in themes that we can apply to our web application to customize its appearance. To apply a theme, we need to configure the web.xml file of the project.

Open the web.xml file located in the src/main/webapp/WEB-INF directory and add the following context parameter:

    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>saga</param-value>
    </context-param>

2. Facelets in Jakarta Faces

Facelets is a powerful templating language used in Jakarta Faces for defining the structure and layout of web pages. It allows developers to create reusable templates and compose dynamic web pages by including components and expressions.

Facelets templates typically have a .xhtml extension and consist of XHTML markup combined with Jakarta Faces component tags and expressions. These templates can include static content as well as dynamic content generated by Jakarta Faces components and managed beans.

2.1 Standard Tag Libraries Supported by Facelets

The table below shows the standard libraries supported by Facelets in Faces 4.0

PrefixURNExamples
xmlns:hjakarta.faces.htmlh:head, h:inputText
xmlns:fjakarta.faces.coref:facet, f:actionListener
xmlns:facesjakarta.facesfaces:id, faces:value
xmlns:fnjakarta.tags.functionfn:toLowerCase, fn:contains
xmlns:uijakarta.faces.faceletsui:component, ui:include
xmlns:cjakarta.tags.corec:forEach, c:if
xmlns:ptjakarta.faces.passthroughpt:type, pt:placeholder
xmlns:ccjakarta.faces.composite

2.2 Create View (Jakarta Faces Page)

Now, let’s create a simple Faces page to test our setup. Create a new XHTML file named index.xhtml in the src/main/webapp directory with the following content:

<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="jakarta.faces.core"
      xmlns:jsf="jakarta.faces"
      xmlns:h="jakarta.faces.html">

    <f:view>
        <h:head>
            <title>Facelets Example</title>
        </h:head>
        <h:body>
            <h1>Welcome to Jakarta Faces!</h1>
            <h:form>
                <h:inputText value="#{userBean.username}" />
                <h:commandButton value="Submit" action="#{userBean.submit}" />
            </h:form>
            <h:outputText value="Welcome, #{userBean.username}" rendered="#{userBean.submitted}" />
        </h:body>
    </f:view>
</html>

In this example:

  • We define a simple XHTML document structure.
  • We include Jakarta Faces component tags (e.g., <h:form>, <h:inputText>, <h:commandButton>) to create form elements.
  • We use EL (Expression Language) expressions (e.g., #{userBean.username}, #{userBean.submit}, #{userBean.submitted}) to bind components to managed bean properties and methods.
  • The userBean is a CDI bean responsible for handling user input and processing form submissions.

2.3 Create Backing Bean

Below is an example of a backing bean (CDI bean) in Jakarta Faces, which corresponds to the Facelets example provided above:

import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;

@Named
@RequestScoped
public class UserBean {
    
    private String username;
    private boolean submitted;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public boolean isSubmitted() {
        return submitted;
    }

    public void setSubmitted(boolean submitted) {
        this.submitted = submitted;
    }

    public String submit() {
        // Process user input or perform any necessary actions
        submitted = true;
        return null; // Navigate to the same page (refresh)
    }
}

In this backing bean:

  • @Named annotation marks this class as a CDI bean that will be managed by the Jakarta Faces framework.
  • @RequestScoped annotation specifies that a new instance of the managed bean will be created for each HTTP request made by the client to the server.
  • The username property represents the value entered by the user in the input field.
  • The submitted property indicates whether the form has been submitted.
  • The submit() method is invoked when the form is submitted. It updates the submitted flag and can perform any necessary actions, such as processing user input or navigating to another page.

3. Start and Run the Application

Starting the application is straightforward.

  • Navigate to Project Directory: Open your terminal or command prompt and navigate to the root directory of your project.
  • Run Maven Command: Use the following Maven command to start GlassFish (chosen runtime for this article) and run the application:
./mvnw clean package cargo:run

This command will compile your project, package it into a WAR file, and deploy it to the GlassFish server.

[INFO] --- cargo:1.10.11:run (default-cli) @ my-faces-app ---
[INFO] Resolved container artifact org.codehaus.cargo:cargo-core-container-glassfish:jar:1.10.11 for container glassfish7x
[INFO] Parsed GlassFish version = [7.0.12]
[INFO] GlassFish 7.0.12 starting...
[INFO] Waiting for cargo-domain to start .........................
[INFO] Waiting finished after 24,673 ms.
[INFO] Successfully started the domain : cargo-domain
[INFO] domain  Location: /Users/omozegieaziegbe/Downloads/jakartaee-hello-world/target/cargo/configurations/glassfish7x/cargo-domain
[INFO] Log File: /Users/omozegieaziegbe/Downloads/jakartaee-hello-world/target/cargo/configurations/glassfish7x/cargo-domain/logs/server.log
[INFO] Admin Port: 4,848
[INFO] Command start-domain executed successfully.
[INFO] GlassFish 7.0.12 started on port [8080]
[INFO] Press Ctrl-C to stop the container...

Once the server is up and running, open your web browser and navigate to http://localhost:8080/my-faces-app/ to see the Faces application in action.

4. Conclusion

In conclusion, Jakarta Faces offers a robust framework for building dynamic and interactive web applications with Java. By leveraging components, navigation rules, and managed beans, developers can create rich user interfaces while abstracting away much of the complexity involved in web development.

Omozegie Aziegbe

Omos holds a Master degree in Information Engineering with Network Management from the Robert Gordon University, Aberdeen. Omos is currently a freelance web/application developer who is currently focused on developing Java enterprise applications with the Jakarta EE framework.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button