JSF In Action – U-Notify Behind The Scenes.

Recently I made a website, http://www.unotifier.com. It is a single hub for sending notification alerts via email and/or SMS. The website is built using JSF and Java EE (Web). These series of posts will take a look at the code powering it and try to use it to explain JSF and Java EE. Be warned that this is not an in-depth discussion about JSF/Java EE, I will just highlight some parts of JSF/Java EE that I used in designing the site.

 The architecture is simple, the views are JSF pages, Managed Beans and Servlets, the persistence layer is pure JPA (I have since given up on Hibernate for personal reasons). I use session beans for all persistence logic, e.g create, delete, update, search etc. Most of the code in the session beans are generated by Netbeans. No worries if you don’t understand these buzz words, It is just JEE way of saying MVC.

 So back to unotifier, in this post I will be taking a look at the front end, in subsequent posts I will talk about the back-end. As I said earlier the front-end is basically JSF and some servlets, I also use components from the Primefaces component framework.

 THE TEMPLATE

JSF allows you to define a template file that can then be used through out your website. The template file define names for particular parts of the page and the page using the template file can then define contents for these parts. Take a look at a sample template file

layout.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets">

<head>
	<ui:insert name='title'>
		Default Title
	</ui:insert>
</head>
<body>
	<div id='head'>
		Default top contents
	</div>
	<div id='center'>
		Default center contents
	</div>
	<div id='foot'>
		Default foot contents
	</div>
	<div id='right'>
		Default right contents
	</div>
</body>
</html>

This is basically what the unotifier template file looks like. If you take a look at the website again you can see each of the ui:insert defined right?

The head is the logo part of the site

The footer is where you have the contact informations

The center is the main contents area

The right is the place where you have the register and login forms.

Now since the header is never going to change for this website, I included the contents in the template file, and same as the footer. So in my web pages I only override the right hand side and the center.

A page that uses the above template file can look like this.

Home.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets">
	<ui:composition template='layout.xhtml'>
		<ui:define name='title'>Unotifier - Home Page</ui:define>
		<ui:define name='center'>
			Hello all, this is the center area
		</ui:define>
		…............
	</ui:composition
</html>

Any part of the template file that you define using ui:define will have a content different from what you specified in the template, else the default contents in the template file are used.

Take a look at http://www.unotifier.com/sent/views/index.xhtml for a sample file that shows the default template for unotifier. The page did not override any of the contents in the template file.

The ability to define templates like this is very important. You can define a part of your page that doesn’t change much in the template file and you are sure not going to have to do the dirty copy and paste every time you need this content. It also keeps your code clean and easy to maintain.

THE PAGES.

If you had taken time to register on the website, you will notice that you are always on a single page, home.xhtml even though not all the pages uses ajax. This is not to say that the code for unotifier is in a single page, no. I use another useful technique in JSF, includes and renders.

On the home page, the register form is a different JSF page, the login form is another page and the main contents is another JSF page. After login in, each of the parts of the page are different JSF pages, for example I have a settings.xhtml, add_client.xhtml, dialogs.xhtml, etc etc. JSF allows you to include these other JSF pages all in one page. JSF also have a render attribute for it’s components that takes a boolean value. This attribute tells the components either to show or not when the page loads, it’s like the css attribute display:none or display:block.

So to include another page in your page you say

<ui:include src='another_page.xhtml' />

and to do selective rendering

<h:form render="false">
</h:form>

That is all. This also helps a lot in keeping your code base organized.

THE COMPONENTS.

I can’t really say much about the components, all I can say is head to http://primefaces.org/showcase and see the wonders of primefaces for yourself.

What I can say though is this. The page uses a primefaces component called layout. If you are a Java Swing developer, this component is similar to your border layout. It has the North, South, Left, Right and Center sub-components that you can use to neatly and painlessly layout your website.

BACKING BEANS

Every other thing on the UI are basic JSF components, and primefaces components. JSF Components require backing beans to come alive, else they are just dummies, they won’t respond to you. A backing bean is also very simple. It is a POJO that contains methods, private variables and getters and setters. So for example the login form on unotifier have a backing bean that looks like this

/**
* @author trinisoftinc
*/
@ManagedBean(name = "loginController")
@SessionScoped
public class LoginController {

@EJB
private AdminFacade adminFacade;

private String l_email, l_password;
private static Logger logger = null;

/** Creates a new instance of LoginController */
public LoginController() {

}

public void doLogin() throws IOException {
   FacesContext context = FacesContext.getCurrentInstance();
   Admin admin = adminFacade.findByEmailAndPassword(l_email, l_password);
   if (admin == null) {
      context.addMessage(null, Main.doErrorMessage("Login Parameters incorrect"));
   } else if (!admin.isConfirmed()) {
      context.addMessage(null, Main.doErrorMessage("Please click the confirmation link in your email first."));
   } else {
      Map session = context.getExternalContext().getSessionMap();
      Main main = (Main) session.get("main");
      main.setLoggedInUser(admin);
   }
   l_email = "";
   l_password = "";
}

public String getL_email() {
   return l_email;
}

public void setL_email(String l_email) {
   this.l_email = l_email;
}

public String getL_password() {
   return l_password;
}

public void setL_password(String l_password) {
   this.l_password = l_password;
}

 and the JSF page itself looks like this

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui">
    <h:form prependId="false" styleClass="login_form">
        <h:panelGrid columns="1">
            <p:inputText id="login_email" value="#{loginController.l_email}" requiredMessage="email can not be empty" required="true" />
            <p:watermark value="email" for="login_email"/>
            <p:password id="login_password" feedback="*" minLength="6" value="#{loginController.l_password}" required="true" requiredMessage="password can not be null" />
            <p:watermark for="login_password" value="password" />
            <p:commandButton value="Login" actionListener="#{loginController.doLogin()}" ajax="false"/>
            <h:commandLink value="forgot password?" onclick="forgot_password.show(); return false;" />
        </h:panelGrid>
    </h:form>
</html>

So the inputTexts (TextFields) have values that are tied to variables in the backing beans and the commandButton have actionListener that is a method in the backing beans. When the button is clicked, the variables take the values from the textfields and the method doLogin() is called. ajax=false says page should refresh and ajax should not be used. If you forget to specify getters and setters for the private variables, the JSF page won’t see them.

This is how most simple JSF pages look like. Of course there are some complex ones that use phase listeners, validators, converters etc. All these are simple concepts that can be easily grasped if/when you need them.

And that is the UI for unotifier.


Advertisements

2 Comments »

  1. Moses said

    Great….well put and simply explained! I am just starting to use JSF/primefaces, and sometimes I have a problem getting the facelets to communicate with the backing beans. I will try to follow ya instructions here and let ya know how it goes.

  2. This is my first time pay a visit at here and i am really pleassant to read
    everthing at alone place.

RSS feed for comments on this post · TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: