Building JSF Forms

Peter Pilgrim

September 2015

 In this article by Peter Pilgrim, author of the book Java EE 7 Web Application Development, we will learn about Java Server Faces as an example of a component-oriented web application framework. As opposed to Java EE 8 MVC, WebWork or Apache Struts, which are known as request-oriented web application frameworks.

A request-oriented framework is one where the information flow is web request and response. Such frameworks provide ability and structure above the javax.servlet.http.HttpServletRequest and javax.servlet.http.HttpServletResponse objects, but there are no special user interface components. The application user with additional help must program mapping of parameters and attributes to the data entity models. The developer therefore has to write parsing logic.

It is important to understand that component-oriented frameworks like JSF have their detractors. The quick inspection of the code resembles components like in standalone client like Java Swing or even JavaFX, but behind the scenes lurks the very same HttpServletRequest and HttpServletResponse. Hence, a competent JSF developer has to be still aware of the Servlet API and the underlying servlet scopes. This was a valid criticism in 2004 and in the digital marketing age, a digital developer has to know not only Servlet, we can presume they would be open to learning other technologies such as JavaScript.

(For more resources related to this topic, see here.)

Create Retrieve Update and Delete

In this article, we are going to solve everyday problem with JSF. Java EE framework and enterprise application are about solving data entry issues. Unlike social networking software that is built with a different architecture and non-functional requirements: scalability, performance, statelessness, and eventual consistency, Java EE applications are designed for stateful work flows. Following is the screenshot of the page view for creating contact details:

The preceding screenshot is the JSF application jsf-crud, which shows contact details form.

Typically an enterprise application captures information from a web user, stores it in a data store, allows that information to be retrieved and edited. There is usually an option to delete the user's information. In software engineering, we call this idiom, Create Retrieve Update and Delete (CRUD).

What constitutes actual deletion of user and customer data is a matter ultimately that affects business owners who are under pressure to conform to local and international law that define privacy and data protection.

Basic create entity JSF form

Let's create a basic form that captures the user's name, e-mail address and date of birthday. We shall write this code using HTML5 and take advantage of the Bootstrap for modern day CSS and JavaScript. See http://getbootstrap.com/getting-started/.

Here is the JSF Facelet view createContact.xhtml:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
     xmlns:h="http://xmlns.jcp.org/jsf/html"
     xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
     xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
   <meta charset="utf-8"/>
   <title>Demonstration Application </title>
     <link
       href="#{request.contextPath}/resources/styles/bootstrap.css"
         rel="stylesheet"/>
     <link
       href="#{request.contextPath}/resources/styles/main.css"
         rel="stylesheet"/>
</h:head>

<h:body>
   <div class="main-container">
     <div class="header-content">
     <div class="navbar navbar-inverse" role="navigation">
   </div>
   </div><!-- headerContent -->
     <div class="mainContent">
       <h1> Enter New Contact Details </h1>

         <h:form id="createContactDetail" styleClass="form-
           horizontal" p:role="form">
                   ...
         </h:form>

      </div><!-- main-content -->

      <div class="footer-content">

     </div> <!-- footer-content -->
   </div> <!-- main-container -->
</h:body>
   <script
     src="#{request.contextPath}/resources/javascripts/jquery-
       1.11.0.js"></script>
   <script
    src="#{request.contextPath}/resources/javascripts/bootstrap.js">
   </script>
   <script src="#{request.contextPath}/resources/app/main.js">
   </script>
</html>

You already recognise the <h:head> and <h:body> JSF custom tags. Because the type if a Facelet view (*.xhtml), the document is actually must be well formed like a XML document. You should have noticed that certain HTML5 elements tags like <meta> are closed and completed: the XHTML document must be well-formed in JSF.

Always close XHTML elements

The typical e-commerce application has web pages with standard HTML with <meta>, <link>, and <br> tags. In XHTML and Facelet views these tags, which web designers normally leave open and hanging, must be closed. Extensible Markup Language (XML) is less forgiving and XHTML, which is derived from XML, must be well formed.

The new tag <h:form> is a JSF custom tag that corresponds to the HTML form element. A JSF form element shares many on the attributes of the HTML partner. You can see the idattribute is just the same. However, instead of the class attribute, we have in JSF, the styleClass attribute, because in Java the method java.lang.Object.getClass() is reserved and therefore it cannot be overridden.

What is the JSF request context path expression?

The curious mark up around the links to the style sheets, JavaScript and other resources is the expression language #{request.contextPath}. The expression reference ensures that the web application path is added to the URL of JSF resources. Bootstrap CSS itself relies on font glyph icons in a particular folder. JSF images, JavaScript modules files and CSS files should be placed in the resources folder of the web root.

The p:role attribute is an example of JSF pass-through attribute, which informs the JSF render kit to send through the key and value to the rendered output. The pass-through attributes are important key addition in JSF 2.2, which is part of Java EE 7. They allow JSF to play well with recent HTML5 frameworks such as Bootstrap and Foundation (http://foundation.zurb.com/).

Here is an extract of the rendered HTML source output.

<h1> Enter New Contact Details </h1>
<form id="createContactDetail" name="createContactDetail"
method="post" action="/jsf-crud-1.0-
   SNAPSHOT/createContactDetail.xhtml" class="form-horizontal"
     enctype="application/x-www-form-urlencoded" role="form">
<input type="hidden" name="createContactDetail"
value="createContactDetail" />

JSF was implemented before the Bootstrap was created at Twitter. How could the JSF designer retrofit the framework to be compatible with recent HTML5, CSS3, and JavaScript innovations? This is where pass-through attribute help. By declaring the XML namespace in the XHTML with the URI http://xmlns.jcp.org/jsf/passthrough. then we enable the feature for the page view. As you can see the attribute name and value role="form" is simply passed through to the output. The pass-through attributes allow JSF to easily handle HTML5 features such as placeholders in text input fields, as we will exploit from now onwards.

If you are brand new to web development, you might be scared of the markup that appears over complicated. There are lots and lots of DIV HTML elements, which are often created by page designers and Interface Developers. This is the historical effect and just the way HTML and The Web has evolved over time. The practices of 2002 have no bearing on 2016.

Let's take a deeper look at the <h:form> and fill in the missing details. Here is the extracted code:

<h:form id="createContactDetail"
styleClass="form-horizontal"
p:role="form">
<div class="form-group">
   <h:outputLabel for="title" class="col-sm-3 control-label">
     Title</h:outputLabel>
   <div class="col-sm-9">
     <h:selectOneMenu class="form-control" id="title"
         value="#{contactDetailController.contactDetail.title}">
       <f:selectItem itemLabel="--" itemValue="" />
       <f:selectItem itemValue="Mr" />
       <f:selectItem itemValue="Mrs" />
       <f:selectItem itemValue="Miss" />
       <f:selectItem itemValue="Ms" />
       <f:selectItem itemValue="Dr" />
     </h:selectOneMenu>
   </div>
</div>
<div class="form-group">
   <h:outputLabel for="firstName" class="col-sm-3 control-label">
     First name</h:outputLabel>
   <div class="col-sm-9">
     <h:inputText class="form-control"
       value="#{contactDetailController.contactDetail.firstName}"
       id="firstName" placeholder="First name"/>
   </div>
</div>
... Rinse and Repeat for middleName and lastName ...
<div class="form-group">
   <h:outputLabel for="email" class="col-sm-3 control-label">
   Email address </h:outputLabel>
   <div class="col-sm-9">
     <h:inputText type="email"
       class="form-control" id="email"
       value="#{contactDetailController.contactDetail.email}"
       placeholder="Enter email"/>
   </div>
</div>
<div class="form-group">
 <h:outputLabel class="col-sm-3 control-label">
     Newsletter
 </h:outputLabel>
 <div class="col-sm-9 checkbox">
     <h:selectBooleanCheckbox id="allowEmails"
   value="#{contactDetailController.contactDetail.allowEmails}">
         Send me email promotions
     </h:selectBooleanCheckbox>
 </div>
</div>
<h:commandButton styleClass="btn btn-primary"
   action="#{contactDetailController.createContact()}"
   value="Submit" />
</h:form>

This is from is built using the Bootstrap CSS styles, but we shall ignore the extraneous details and concentrate purely on the JSF custom tags.

The <h:selectOneMenu> is a JSF custom tag that corresponds to the HTML Form Select element. The <f:selectItem> tag corresponds to the HTML Form Select Option element. The <h:inputText> tag corresponds to the HTML Form Input element. The <h:selectBooleanCheckbox> tag is a special custom tag to represent a HTML Select with only one Checkbox element. Finally, <h:commandButton> represents a HTML Form Submit element.

JSF HTML Output Label

The <h:outputLabel> tag renders the HTML Form Label element.

<h:outputLabel for="firstName" class="col-sm-3 control-label">
   First name</h:outputLabel>

Developers should prefer this tag with conjunction with the other associated JSF form input tags, because the special for attribute targets the correct sugared identifier for the element.

Here is the rendered output:

<label for="createContactDetail:firstName"
class="col-sm-3 control-label"> First name</label>

We could have written the tag using the value attribute, so that looks like this:

<h:outputLabel for="firstName" class="col-sm-3 control-label"
value="firstName" />

It is also possible to take advantage of internationalization at this point, so just for illustration, we could rewrite the page content as:

<h:outputLabel for="firstName" class="col-sm-3 control-label"
value="${myapplication.contactForm.firstName}" />

JSF HTML Input Text

The <h:inputText> tag allows data to be entered in the form like text.

<h:inputText class="form-control"
value="#{contactDetailController.contactDetail.firstName}"
   id="firstName" placeholder="First name"/>

The value attribute represents a JSF expression language and the clue is the evaluation string starts with a hash character. Expression references a scoped backing bean ContactDetailController.java with the name of contactDetailController. In JSF 2.2, there are now convenience attributes to support HTML5 support, so the standard id, class, and placeholder attributes work as expected.

The rendered output is like this:

<input id="createContactDetail:firstName" type="text"
name="createContactDetail:firstName" class="form-control" />

Notice that the sugared identifier createContactDetails:firstName matches the output of the <h:outputLabel> tag.

JSF HTML Select One Menu

The <h:selectOneMenu> tag generates a single select drop down list. If fact, it is part of a family of selection type custom tags. See the <h:selectBooleanCheckbox> in the next section.

In the code, we have the following code:

<h:selectOneMenu class="form-control"
         id="title"
         value="#{contactDetailController.contactDetail.title}">
     <f:selectItem itemLabel="--" itemValue="" />
     <f:selectItem itemValue="Mr" />
     <f:selectItem itemValue="Mrs" />
     <f:selectItem itemValue="Miss" />
     <f:selectItem itemValue="Ms" />
     <f:selectItem itemValue="Dr" />
</h:selectOneMenu>

The <h:selectOneMenu> tag corresponds to a HTML Form Select tag. The value attribute is again JSF expression language string.

In JSF, we can use another new custom tag <f:selectItem> to define in place option item. The <f:selectItem> tag accepts an itemLabel and itemValue attribute. If you set the itemValue and do not specify the itemLabel, then the value becomes the label. So for the first item the option is set to , but the value submitted to the form is a blank string, because we want to hint to the user that there is a value that ought be chosen.

The rendered HTML output is instructive:

<select id="createContactDetail:title" size="1"
name="createContactDetail:title" class="form-control">
<option value="" selected="selected">--</option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Miss">Miss</option>
<option value="Ms">Ms</option>
<option value="Dr">Dr</option>
</select>

JSF HTML Select Boolean Checkbox

The <h:selectBooleanCheckbox> custom tag is special case of selection where there is only one item that the user can choose. Typically, in web application, you will find such an element is the finally terms and condition form or usually in marketing e-mail section in an e-commerce application.

In the targeted managed bean, the only value must be a Boolean type.

<h:selectBooleanCheckbox for="allowEmails"
   value="#{contactDetailController.contactDetail.allowEmails}">
   Send me email promotions
</h:selectBooleanCheckbox>

The rendered output for this custom tag looks like:

<input id="createContactDetail:allowEmails" type="checkbox"
name="createContactDetail:allowEmails" />

JSF HTML Command Button

The <h:commandButton> custom tags correspond to the HTML Form Submit element. It accepts an action attribute in JSF that refers to a method in a backing bean. The syntax is again in the JSF expression language.

<h:commandButton styleClass="btn btn-primary"
   action="#{contactDetailController.createContact()}"
   value="Submit" />

When the user presses this submit, the JSF framework will find the named managed bean corresponding to contactDetailController and then invoke the no arguments method createContact().

In the expression language, it is important to note that the parentheses are not required, because the interpreter or Facelets automatically introspects whether the meaning is an action (MethodExpression) or a value definition (ValueExpression). Be aware, most examples in the real world do not add the parentheses as a short hand.

The value attribute denotes the text for the form submit button. We have could written the tag in the alternative way and achieve the same result.

<h:commandButton styleClass="btn btn-primary"
   action="#{contactDetailController.createContact()}" >
   Submit
</h:commandButton>

The value is taken from the body content of the custom tag. The rendered output of the tag looks like something this:

<input type="submit" name="createContactDetail:j_idt45"
value="Submit" class="btn btn-primary" />
<input type="hidden" name="javax.faces.ViewState"
id="j_id1:javax.faces.ViewState:0"
 value="-3512045671223885154:3950316419280637340"
    autocomplete="off" />

The above code illustrates the output from the JSF renderer in the Mojarra implementation (https://javaserverfaces.java.net/), which is the reference implementation. You can clearly see that the renderer writes a HTML submit and hidden element in the output. The hidden element captures information about the view state that is posted back to the JSF framework (postback), which allows it to restore the view.

Finally, here is a screenshot of this contact details form:

The contact details input JSF form with additional DOB fields

Now let's examine the backing bean also known as the controller.

Backing Bean controller

For our simple POJO form, we need a backing bean or a modern day JSF developer parlance a managed bean controller.

This is the entire code for the ContactDetailController:

package uk.co.xenonique.digital;
import javax.ejb.EJB;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import java.util.List;

@Named("contactDetailController")
@ViewScoped
public class ContactDetailController {
@EJB ContactDetailService contactDetailService;

private ContactDetail contactDetail =
 new ContactDetail();

public ContactDetail getContactDetail() {
     return contactDetail;
}

public void setContactDetail(
 ContactDetail contactDetail) {
     this.contactDetail = contactDetail;
}

public String createContact() {
     contactDetailService.add(contactDetail);
     contactDetail = new ContactDetail();
     return "index.xhtml";
}

public List<ContactDetail> retrieveAllContacts() {
     return contactDetailService.findAll();
}
}

For this managed bean, let's introduce you to a couple of new annotations. The first annotation is called @javax.inject.Named and it is declares this POJO to be CDI managed bean, which also simultaneously declares a JSF controller. Here, we declare explicitly the value of name of the managed bean as contactDetailController. This is actually the default name of the managed bean, so we could have left it out.

We can also write an alternative name like this:

@Named("wizard")
@ViewScoped
public class ContactDetailController { /* .. . */ }

Then JSF would give as the bean with the name wizard. The name of the managed bean helps in expression language syntax.

When we are talking JSF, we can interchange the term backing bean with managed bean freely. Many professional Java web develop understand that both terms mean the same thing!

The @javax.faces.view.ViewScoped annotation denotes the controller has a life cycle of view scoped. The view scoped is designed for the situation where the application data is preserved just for one page until the user navigates to another page. As soon as the user navigates to another page JSF destroys the bean. JSF removes the reference to the view-scoped bean from its internal data structures and the object is left for garbage collector.

The @ViewScoped annotation is new in Java EE 7 and JSF 2.2 and fixes a bug between the Faces and CDI specifications. This is because the CDI and JSF were developed independently. By looking at the Java doc, you will find an older annotation @javax.faces.bean.ViewScoped, which is come from JSF 2.0, which was not part of the CDI specification.

For now, if you choose to write @ViewScoped annotated controllers you probably should use @ManagedBean. We will explain further on.

The ContactDetailController also has dependency on an EJB service endpoint ContactDetailService, and most importantly is has a bean property ContactDetail. Note that getter and setter methods and we also ensure that the property is instantiated during construction time.

We turn our attention to the methods.

public String createContact() {
     contactDetailService.add(contactDetail);
     contactDetail = new ContactDetail();
     return "index.xhtml";
}

public List<ContactDetail> retrieveAllContacts() {
     return contactDetailService.findAll();
}

The createContact() method uses the EJB to create a new contact detail. It returns a String, which is the next Facelet view index.xhtml. This method was referenced by the <h:commandButton>.

The retrieveAllContacts() method invokes the data service to fetch the list collection of entities. This method will be referenced by another page.

Summary

In this article, we learned about JSF forms we explore HTML and core JSF custom tags in building the answer to one of the sought questions on the Internet. It is surprising that this simple idea is considered difficult to program. We built digital JSF form that initially created a contact detail. We saw the Facelet view, the managed bean controller, the stateful session EJB and the entity

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Digital Java EE 7 Web Application Development

Explore Title
comments powered by Disqus