#WHATIS? JavaServer Faces. An introduction to JSF 2.3

Scrolling through my news feed on Twitter I get flooded with new releases of npm modules and more and more blog articles about server-side rendering technologies for the latest Single Page Application frameworks like Angular, React. The following tweet summarized my current feelings:

As I personally really like React and used it in the past for several projects, I am not that happy about the bunch of additional npm packages I need for a working application. To be up-to-date you have stick to the latest versions and that is sometimes awful if you are also developing the backend as you have to observe more frameworks and libraries. For most of the (enterprise) applications,  it’s all about validating user inputs, manipulating, storing and displaying data. This can be easily achieved with an SPA and a backend like Spring or Java EE  but you need experience in both technologies and staying up-to-date is more complex.

To get a whole overview of the server-side vs. client-side web development and to overcome my (maybe) Junior mentality of using every new shiny framework I wanted to know more about server-side rendering with Java. I always had the prejudice that it’s quite old, slow and not usable these days but I never tried it for my own.

At one of the airhacks.com Adam Bien (@AdamBien) did a quick intro to JavaServer Faces (JSF)  and showed how easy it was to get started and create JSF components in seconds. To get deeper insights into this mature technology I bought the book The Definitive Guide to JSF in Java EE 8 from Bauke Scholtz (@OmniFaces) & Arjan Tijms (@arjan_tijms)  and worked through it. They cover all aspects of web development with JSF: WebSockets, Validation, Internationalization, Security etc. and I can highly recommend this awesome book.

Today I’ll show you a quick Hello World with JSF 2.3 and Maven on Payara 5.182 to make you familiar with the technology. Like every Java EE part (CDI, JPA, EJB …) JSF has a formal specification and several reference implementations. The most popular implementations for JSF are Apache MyFaces and Mojarra

To start your web development your  pom.xml needs at least the following dependency:

<?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>de.rieckpil.blog</groupId>
    <artifactId>hello-world-jsf-23</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>8.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>hello-world-jsf</finalName>
    </build>
</project>

The dependency javax:javaee-api brings you the formal specification with several classes and annotations. The implementation of the several Java EE APIs is provided by the application server (e.g. Payara, OpenLiberty, Wildfly etc.). Marking the dependency as provided will lead to a thin war deployment where the Java EE dependency is not packaged to the war file as it is part of the application server. The war file will just contain your business logic and the JSF views.

To configure your web application and later on JSF you need a web.xml file which has to be placed  in /src/main/webapp/WEB-INF:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">

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

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

    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

With this configuration, you enable the central FacesServlet, define the mapping of JSF related views and the welcome file. JSF follows the MVC approach and your views are mostly written as .xhtml files (a detailed JSF MVC explanation can be found here).

A simple Hello World view (index.xhtml) with an input field and a button to display the Hello World message can look like the following and should be stored at /src/main/webapp:

<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
    <title>Hello World JSF 2.3</title>
</h:head>
<h:body>

    <h:form>
        <h:outputLabel for="input" value="Who do you want to greet?"/>
        <h:inputText id="input" value="#{helloWorldBacking.name}"/>
        <h:commandButton value="Submit"
                         action="#{helloWorldBacking.greetPerson}">
        </h:commandButton>
        <br/>
        <h:outputText value="#{helloWorldBacking.greet}"/>
    </h:form>

</h:body>
</html>

You may notice the prefix <h:…> on several HTML elements which is one of the main differences to normal HTML (.html) files. With this prefix, you reference a specific namespace and in the case of <h:…> it’s the namespace of the basic HTML elements. There are several other namespaces you can use like <f:…> which give a bunch of predefined components and functionality. In the example above we are just using a form with a label for an input field, a submit button and a placeholder for some output text.

Another difference to normal HTML elements is the use of the following syntax #{xyz.value} as you can find it for the label value and the action for the submit button. This is an expression language where you can reference fields and methods of so-called backing beans which are written in Java. In our example, I am referencing two fields (name and greet) and a method (greetPerson) of the backing bean helloWorldBacking. The values get replaced when the JSF view is rendered on the server. The name of the backing bean is the name of the Java class which is annotated with @Named and a CDI scope like @RequestScoped if nothing else is configured. The backing bean looks like the following:

package de.rieckpil.blog;

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

@Named
@RequestScoped
public class HelloWorldBacking {

    private String name;
    private String greet;

    public void greetPerson() {
        this.greet = "Hello World: " + this.name + " !";
    }

    public String getGreet() {
        return greet;
    }

    public void setGreet(String greet) {
        this.greet = greet;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

With this setup, you don’t have to create any JavaScript code and inserting a name to the input field an pressing submit will render the same page with the Hello world message. This is just a small example of a quick JSF intro but there is a lot more to discover like WebSockets, AJAX calls,  UI layouting, notifications and much more.

For a quick deployment on your local machine I created a simple Dockerfile for starting the app:

FROM payara/server-full
COPY target/hello-world-jsf.war $DEPLOY_DIR

You can find the Hello World example with the required steps to run this application locally on GitHub.

I’ll definitely play more with JSF and start using the awesome component library PrimeFaces which brings a lot of ready-to-use components (e.g. date picker, dialogs, data tables, panels, menu bars etc.) and keep you up-to-date. If you want to get further information about JSF, have a look at the following book The Definitive Guide to JSF in Java EE 8 or at this overview for some tutorials and answers.

See you,

Phil.

 

2 Comments

  1. Pingback: #HOWTO: Simple CRUD table with JSF 2.3 and PrimeFaces | Philip's Homepage

  2. Armen August 12, 2018 at 12:42 pm

    Yeah, JSF +Omnifaces, Primefaces too power

Leave a comment

Your email address will not be published. Required fields are marked *