Skip to content

Latest commit

 

History

History
289 lines (208 loc) · 18.5 KB

README.adoc

File metadata and controls

289 lines (208 loc) · 18.5 KB

Building a dynamic web application using Jakarta Faces

Note
This repository contains the guide documentation source. To view the guide in published form, view it on the Open Liberty website.

Learn how to build a dynamic web application using Jakarta Faces, Jakarta Contexts and Dependency Injection, and Jakarta Expression Language.

What you’ll learn

You’ll learn how to build a dynamic web application using Jakarta Faces for the user interface (UI), Jakarta Contexts and Dependency Injection (CDI) for managing backend logic, and Jakarta Expression Language (EL) for data binding.

Jakarta Faces is a powerful framework for building web applications with reusable UI components. It provides an API for managing component state, handling events, server-side validation, page navigation, and supports internationalization. The framework also offers tag libraries for adding components and binding them to server-side objects, simplifying UI development. Jakarta Contexts and Dependency Injection provides a flexible way to manage the lifecycle of backend beans, allowing managed beans to be automatically created and injected when needed. Jakarta Expression Language allows data binding between the UI and the backend, enabling componenets to display dynamic data and respond to user actions.

The application you will build in this guide is a dynamic web application that displays system load data on demand. Using Jakarta Faces for the UI, you’ll create a table to show the system’s cpu load and heap memory usage. You’ll also learn how to use CDI to provide the system load data from a managed bean, and to use Jakarta Expression Language to bind this data to the UI components.

Try what you’ll build

The finish directory in the root of this guide contains the finished application. Give it a try before you proceed.

To try out the application, first go to the finish directory and run Maven with the liberty:run goal to build the application and deploy it to Open Liberty:

cd finish
mvn liberty:run

After you see the following message, your Liberty instance is ready.

The defaultServer server is ready to run a smarter planet.

Check out the web application at http://localhost:9080/index.xhtml. Click the refresh icon refresh button, located next to the table title, to update and display the latest system load data in the table.

After you are finished checking out the application, stop the Liberty instance by pressing CTRL+C in the command-line session where you ran Liberty. Alternatively, you can run the liberty:stop goal from the finish directory in another shell session:

mvn liberty:stop

Creating a static Jakarta Faces page

Start by creating a static Jakarta Faces page that displays an empty table for system load data, which serves as the starting point for your application.

Navigate to the start directory to begin.

When you run Open Liberty in dev mode, dev mode listens for file changes and automatically recompiles and deploys your updates whenever you save a new change. Run the following goal to start Open Liberty in dev mode:

mvn liberty:dev

After you see the following message, your Liberty instance is ready in dev mode:

**************************************************
*     Liberty is running in dev mode.

Dev mode holds your command-line session to listen for file changes. Open another command-line session to continue, or open the project in your editor.

Create the index.xhtml file.
src/main/webapp/index.xhtml

index.xhtml

link:staging/index.xhtml[role=include]

footer.xhtml

link:finish/src/main/webapp/WEB-INF/includes/footer.xhtml[role=include]

In the index.xhtml file, the xmlns attributes define the XML namespaces for various Jakarta Faces tag libraries. These namespaces allow the page to use Jakarta Faces tags for templating, creating UI components, and enabling core functionality like form submissions and data binding. For more information on the various tag libraries and their roles in Jakarta Faces, refer to the Jakarta Faces Tag Libraries Documentation.

The index.xhtml file combines standard HTML elements with Jakarta Faces components, enabling both static layout and dynamic functionality. Jakarta Faces tags, like <h:outputStylesheet> and <ui:include>, manage UI components, resource inclusion, and data binding, offering additional features beyond standard HTML; while standard elements like <div> and <section> structure the page’s layout. The <h:outputStylesheet> includes a CSS file to style the page. The <ui:include> tag incorporates reusable components, such as the provided footer.xhtml file, to streamline maintenance and reuse across multiple pages.

At this point, the page defines a table that has no data entries. We’ll add dynamic content in the following steps.

Mapping Faces Servlet

Before you can access the Jakarta Faces page, you need to configure the Faces Servlet in your application. This servlet handles all requests for .xhtml pages and processes them using Jakarta Faces.

Create the web.xml file.
src/main/webapp/WEB-INF/web.xml

web.xml

link:finish/src/main/webapp/WEB-INF/web.xml[role=include]

The <servlet> element defines the Faces Servlet that is responsible for processing requests for Jakarta Faces pages. The <load-on-startup> element with a value of 1 specifies that the servlet should be loaded and initialized when the application starts.

The <servlet-mapping> element specifies which URL patterns are routed to the Faces Servlet. In this case, all URLs ending with .xhtml are mapped to be processed by Jakarta Faces. This ensures that any request for a .xhtml page is handled by the Faces Servlet, which manages the lifecycle of Jakarta Faces components, processes the page, and renders the output.

By configuring both the servlet and the servlet mapping, you’re ensuring that Jakarta Faces pages are properly processed and delivered in response to user requests.

The jakarta.faces.PROJECT_STAGE context parameter determines the current stage of the application in its development lifecycle. Because it is currently set to Development, you will see additional debugging information, including developer-friendly warning messages such as WARNING: Apache MyFaces Core is running in DEVELOPMENT mode. For more information about valid values and how to set the PROJECT_STAGE parameter, you can refer to the official Jakarta Faces ProjectStage documentation.

Because you are running Open Liberty in dev mode and have configured the Faces Servlet, all the changes are automatically picked up.

Check out the web application that you created at the http://localhost:9080/index.xhtml URL. You should see the static page with the system loads table displaying only the headers and no data.

Implementing backend logic with dependency injection

To provide system load data to your web application, you’ll create a CDI-managed bean that retrieves information about the system’s CPU load and memory usage. This bean will be accessible from the Jakarta Faces page and will supply the data to be displayed.

Create the SystemLoadBean class.
src/main/java/io/openliberty/guides/application/SystemLoadBean.java

SystemLoadBean.java

link:finish/src/main/java/io/openliberty/guides/application/SystemLoadBean.java[role=include]

Annotate the SystemLoadBean class with a @Named annotation to make it accessible in the Jakarta Faces pages under the name systemLoadBean. Because the SystemLoadBean bean is a CDI managed bean, a scope is necessary. An application scope is used in this example. To learn more about CDI, see the Injecting dependencies into microservices guide.

The @PostConstruct annotation ensures the init() method runs after the SystemLoadBean is initialized and dependencies are injected. The init() method sets up any required resources for the bean’s lifecyccle.

The fetchSystemLoad() method retrieves the current system load and memory usage, then updates the list of system load data.

The getSystemLoads() method is a getter method for accessing the list of system load data from the Jakarta Faces page.

Binding data to the UI with expression language

Now that you have the backend logic implemented with CDI, you’ll update the Jakarta Faces page to display the dynamic system load data by binding the UI components to the backend data using Jakarta Expression Language.

Update the index.xhtml file.
src/main/webapp/index.xhtml

index.xhtml

link:finish/src/main/webapp/index.xhtml[role=include]

SystemLoadBean.java

link:finish/src/main/java/io/openliberty/guides/application/SystemLoadBean.java[role=include]

The index.html uses a <h:commandButton> tag to create the refresh button, where the action #{systemLoadBean.fetchSystemLoad} invokes the fetchSystemLoad() method using Jakarta Expression Language when the button is clicked. This EL expression references the systemLoadBean managed bean, triggering the method to update the system load data. The <f:ajax> tag ensures that the systemLoadForm component is re-rendered without a full page reload.

The systemLoadsTable is populated using the <ui:repeat> tag, which iterates over the list of system load data provided by the systemLoadBean. The EL expression #{systemLoadBean.systemLoads} calls the getSystemLoads() method from the managed bean, binding the data to the UI components. If the systemLoadBean hasn’t been created yet, it is automatically initialized at this point. For each entry, the time, cpuLoad, and memoryUsage fields are displayed using <h:outputText>, while <f:convertNumber> formats numeric values to two decimal places.

Running the application

server.xml

link:finish/src/main/liberty/config/server.xml[role=include]

The required faces, expressionLanguage, and cdi features have been enabled for you in the Liberty server.xml configuration file.

Because you started the Open Liberty in dev mode at the beginning of the guide, so all the changes were automatically picked up.

Navigate to the http://localhost:9080/index.xhtml to view your web application. Click on the refresh icon refresh button to trigger an update on the system loads table.

Testing the application

While you can manually verify the web application by visiting http://localhost:9080/index.xhtml, automated tests are a much better approach because they are more reliable and trigger a failure if a breaking change is introduced. You can write unit tests for your CDI bean to ensure that the basic operations you implemented function correctly.

Create the SystemLoadBeanTest class.
src/test/java/io/openliberty/guides/application/SystemLoadBeanTest.java

SystemLoadBeanTest.java

link:finish/src/test/java/io/openliberty/guides/application/SystemLoadBeanTest.java[role=include]

The setUp() method is annotated with the @BeforeEach annotation, indicating that it is run before each test case to ensure a clean state for each test execution. In this case, it creates a new instance of SystemLoadBean and manually calls the init() method to initialize the list of system load data before each test.

The testInitMethod() test case verifies that after initializing SystemLoadBean, the list of system load data is not null and contains at least one entry.

The testFetchSystemLoad() test case verifies that after calling the fetchSystemLoad() method, the size of the list of system load data increases by one.

The testDataIntegrity() test case verifies that each SystemLoadData entry in the list of system load data contains valid values for time, cpuLoad, and memoryUsage.

Running the tests

Because you started Open Liberty in dev mode, you can run the tests by pressing the enter/return key from the command-line session where you started dev mode.

You see the following output:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running io.openliberty.guides.application.SystemLoadBeanTest
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.037 s -- in io.openliberty.guides.application.SystemLoadBeanTest

Results:

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

When you are done checking out the service, exit dev mode by pressing CTRL+C in the command-line session where you ran Liberty.

Great work! You’re done!

You just built a dynamic web application on Open Liberty by using Jakarta Faces for the user interface, CDI for managing beans, and Jakarta Expression Language for binding and handling data.