Skip to main content

Java EE Application Development – A Basic JSF Application

In this tutorial, we will continue to develop our Notebook application. A simple “add a note” form and a response page will be added for the application. Now let’s have a look how I accomplished this.

project on Github: https://github.com/zxuqian/Learning-Java-EE-2016

Add dependencies

If you would like eclipse to do code assist when you are writing JSF pages, you need to add two dependencies in the pom.xml. As you may noticed, the wildfly 10 runtime does not provide jsf-impl.jar at compile time in its library. That is also why our application can run successfully but sometimes it will be failed for maven to build.

Here is the pom.xml file. Under the <dependencies> tag, the provided means jar files imported here are provided only during compile time, you will not find it in the war archive:

<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>notebook</groupId>
  <artifactId>notebook</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>notebook</name>
  
  <build>
    <sourceDirectory>src</sourceDirectory>
    <finalName>notebook</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.0.0</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
        <!-- https://mvnrepository.com/artifact/com.sun.faces/jsf-api -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.2.13</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sun.faces/jsf-impl -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.2.13</version>
            <scope>provided</scope>
        </dependency>
        
  </dependencies>
</project>

 

Index.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:jsf="http://xmlns.jcp.org/jsf"
    xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:f="http://xmlns.jcp.org/jsf/core">
    
<h:head>
    <title>Qiantu - A simple Notebook</title>
</h:head>
<h:body>
    <h2>Hello, welcome!</h2>
    <p>Add a note here: </p>
    <h:form>
        <label for="username">Name: </label>
        <h:inputText id="username" value="#{note.name}" /><br />
        <label for="email">email: </label>
        <input type="email" jsf:id="email" value="#{note.email}" /><br />
        <label for="note">Note: </label>
        <h:inputTextarea id="note" rows="8" value="#{note.note}"></h:inputTextarea><br />
        <input type="submit" jsf:id="submit" action="response" value="Submit" />
    </h:form>
</h:body>


</html>

This page, in terms of JSF, is called a Facelet. The page here is a little different than the previous examples of JSF because now it is written in HTML5. There are four namespaces imported in the <html> tag.

  • “h” is the tag lib provided by JSF and includes mostly html tags. Each tag has a corresponding Java component representing it. It is pretty much like other application programming model, e.g. IOS, Android.
  • “f” is actions that JSF provided with us, but here we won’t use it yet, but as we go deep with JSF, I will explain how to use it.
  • “jsf” is kind of an identification when you would like to use HTML5 to write your Facelets. When an HTML5 tag has no relating JSF tag, provided by “h” tag lib, you can just write down the original html tag, but have at least one attribute defined with jsf: prefix,  then it will be treated as a JSF compoment. This is called a pass-through element.
  • “p” almost does the opposite of jsf: prefix. If you have attributes in your tag but you don’t want it be treated as JSF attribute,  you can defined it with p: prefix. The attributes with p: prefix are called pass-through attributes.

The <h:head> <h:body> and <h:form> are directly parsed to HTML <head> <body> and <form>. If you don’t want to manage the state of these components in JSF managed beans (I will talk about it later), you can just use plain HTML tags.

<h:inputText> is equivalent to <input type=”text”>, the value here is referenced to the name property of a managed bean called note. The syntax used here is called EL expression which is a powerful expression that can do some operations or read and write properties of managed beans. You will see name, email and note are defined in the Note class which is a managed bean. If there no values was assigned to name, the input text field will remain blank and the the EL #{note.name} will try to write user input to the name property when user clicks submit button.

<input type=”email”>, well, JSF does not have the corresponding components to it, so here I just write the original HTML tag, but I added jsf: prefix to its id attributes so it will be treated as a JSF component. It does not matter which attribute you put the prefix before it.

Also, there’s a textarea that I use the tag provided by JSF.

Note our last tag, <input type=”submit”…>, it is a plain HTML tag, but you can use attributes defined by JSF but not by HTML as long as you make it to be a JSF component by adding jsf: prefix to one of its attributes. The functionality of the tag is equal to <h:commandButton>. The action attribute means that after the button has been clicked, what action will take place. Here it will jump into a page called response.xhtml (You don’t have to write the .xhtml suffix).

Note.java

package com.zxuqian.notebook.web;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class Note {
    
    private String name;
    private String email;
    private String note;
    
    //private static final Logger log = Logger.getLogger(Note.class.getCanonicalName());

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
    
    
}

The class is similar to the controller in MVC model. It is annotated by @ManagedBean and @RequestScoped annotations. The @ManagedBean is used to identify this class as a JSF component and it also indicate that Context Dependency Injection is enabled. I will talk about CDI in future blogs. The @RequestScoped means that values of properties are only valid during a single client request. There are also @SessionScoped and ApplicationScoped annotations which have its own purpose that I will explain it in the future.

When the Note class is annotated by @ManagedBean, it is given a default name note, which is the lowercased class name. The name can be used in EL expressions. There are three member variables, name, email and note. You have to define getters and setters for these variables because only by doing this, you can read and write values to them by using EL expressions.

Response.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:jsf="http://xmlns.jcp.org/jsf"
    xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:f="http://xmlns.jcp.org/jsf/core">
    
<h:head>
    <title>Qiantu - A simple Notebook</title>
</h:head>
<h:body>
    <h3>Here is your input</h3>
    <p>Username: #{note.name}</p>
    <p>Email: #{note.email}</p>
    <p>Note: #{note.note}</p>
</h:body>
</html>

The response.xhtml page simply outputs what you have input in the form of index.xhtml page.

The application now is pretty simple, but we will gradually add small functions to it and make it a complete Java EE application.

Final result

Type http://localhost:8080/notebook in your browser and give some test data:

then click submit, you will see the response:

All done! Well, you may think how ugly it is, but now we are only focusing on implementation of functionalities in the backends. I think some day I will talk about front-end technologies and make our application more pretty using some html frameworks, such as bootstrap.

Problems

There maybe some problems using Run on server functionality provided by eclipse. The deployed project will be automatically added a version suffix. In my example, the context root of the project is notebook, but after deploy it on the server, it became notebook-0.0.1-SNAPSHOT so I have to access pages by typing http://localhost:8080/notebook-0.0.1-SNAPSHOT, that’s not cool. After doing some research, I found you can change the name of the deployed project by doing these steps:

Double click the server from Servers tab:

In the page that appears, click Deployment tab, you will see:

Double click the cell under Deployment Location, you can give it a name that you desire. After done this, don’t forget to save it.

If you have any other questions or advices, leave a comment below. I will be glad to help you out and hear from you.