J3 Limited
 
Google
WWW J3Ltd
 
Creating The Project, Welcome JSF

Introduction

The last section looked installing all the required software to develop enterprise applications. In this installment, an example JEE application starts to be developed.

The example application is called MyCV, the goal is to allow users to register, and edit their personal details. An option to generate a CV as HTML or in an other format is made available. Such an application, while being relatively simple, is good enough to cover most issues encountered in the development of JEE applications, namely:

  • JSP and JSF, for the presentation layer (Web pages)
  • EJB's for the business logic
  • JAAS for security and authentication
  • Internationalization for multiple language support
  • Using third party libraries

In this installment, Java Server Faces and internationalization are introduced.

The source code for this chapter can be downloaded as a zip archive from here.

Before starting this installment, JBoss, Eclipse and the JBoss Eclipse IDE plug-in should be installed and configured correctly, as explained in the previous installments.

Create The Project

In Eclipse a new EJB 3 project is created.

Next is pressed and MyCV is entered as the project name.

Next is pressed, and the existing JBoss configuration is selected. If no JBoss configuration exists, how to create a configuration is covered here. Finish is clicked, and the project is created.

Create The Web Application Deployment Descriptor

A new web application deployment descriptor is created by right clicking the project folder in the package explorer, and selecting new->other. The Web Application 2.4 Deployment Descriptor is selected, and next is clicked:

The src folder is selected as the folder where the new file called web.xml will be created, finish is clicked:

Create A JSF Library

The JBoss installation includes JSF 1.1.To make use of this, a new user library is created in JBoss. The project properties dialog is selected, within this, the Java Build path is selected, then the project libraries tab is clicked:

Add library is clicked in the above dialog.

User library is selected, as this is a new "user" library that is being created.

In the "User Libraries" dialog, the "New..." button is pressed.

The name of the library given is JBossJSF, as it will include the jar files that JBoss includes in its installation. When the above dialog is dismissed, by clicking on OK, the "Add Jars..." button is clicked in the "User Libraries" dialog.

The jar files to add to this library can be found in a JBoss folder, below the root installation of JBoss called server/default/deploy/jbossweb-tomcat55.sar/jsf-libs. All the files in this folder are selected and added to the library, then OK is clicked. All the subsequent dialogs are dismissed by clicking on OK or Finish. This completes the creation of the JSF user library.

Configure The Project Web.xml File

In order to use Java Server Faces, the web application deployment descriptor needs to be altered to look like the one shown below:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation= "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>MyCV</display-name>

<listener>
<listener-class> org.apache.myfaces.webapp.StartupServletContextListener </listener-class>
</listener>

<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>

<servlet>
<display-name>FacesServlet</display-name>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>

</web-app>

The above enables JSF in the web application. In addition, the application's display name is given, and the JSF state saving method is set to "server". The STATE_SAVING_METHOD can be either "client" or "server". The client value means that the entire state is saved in a hidden field on each page page. The server value means that the state is saved on the server. For large applications, saving the state on the client may become problematic, hence saving on the server is usually the best option.

Create An Error Page

When developing web applications, an error page can prove to be very valuable. The error error page, shown below, is used to display an exception message and a stack trace. It is usually displayed if there is a bug in the code, or the if system is not behaving correctly. The errors generated when the user enters incorrect values should not use the error page.

Some errors generate a stack trace in Eclipse's console window (and JBoss' log file), but others do not. When creating JSF pages, it is common to mistype something or forget to include an attribute. When the application is run, the JSF page in question cannot be displayed, instead the error page is displayed and the error message is usually a good indicator of what needs to be fixed in the JSF page. For these reasons, it is well worth creating the error page early on in the project.

A new JSP file called errorpage.jsp is created in the src/web folder of the project:

<%@ page isErrorPage="true" %>  
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link href="styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="errorMessage"><%= exception.getLocalizedMessage() %></div>
<pre class="errorStackTrace">
<%
java.io.CharArrayWriter cw = new java.io.CharArrayWriter();
java.io.PrintWriter pw = new java.io.PrintWriter(cw, true);
exception.printStackTrace(pw);
out.println(cw.toString());
%>
</pre>
</body>
</html>

It is usually recommended to put as little code as possible in the error page, so that there is less chance of the error page generating an error.

Now that the error page is done, the rest of the application can be developed.

The Default index.jsp

Whenever the application is accessed without specifying a page, index.jsp is accessed. This jsp is used to forward the user to the welcome page.

A new JSP in the src/web folder is created, called index.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<jsp:forward page="/welcome.faces" />
</body>
</html>
The page above forwards to the application's welcome page.

The Style Sheet

A style sheet file called styles.css is created in the src/web folder. JSF allows the use of styles with its tags. The style sheet created looks like this:

body, div, td, span, li, input { 
	font-family: Arial, Helvetica; 
	font-size: 12px;
	}
th {
	font-size: 14;px	
	}
.center, .pageTitle, .form {
		position: relative;
		margin: 0 auto;
		text-align: center;
	}
.pageTitle {
		font-size: 18px;
		font-weight: bold;
	}
.form {
		border:2px solid black;
	}
.tableHeader {
		background-color: #E0E8E8;
	}
	.tableFooter {
		background-color: #E0E8E8;
	}
.tableRowOdd {
		background-color: #FFFFFF;
	}
.tableRowEven {
		background-color: #EEF0F0;
	}
		
a {
	text-decoration: none;
	color: #337799;
	font-weight: bolder;
}
a:hover {
	text-decoration:underline;
	color: #FF5555;
	font-weight: bolder;
	}
td {
	text-align: left;
	}
.errorMessage {
	color : #FF0000;
	font-weight: bolder;
	}
.errorStackTrace {
	color : #000000;
	}
.formUserError {
	color : #FF0000;
	font-weight: bolder;
  }

The Welcome Page

The welcome page allows the user to select a language to use, register and logon to the site. As a first step, the language selection is done. The additional steps of logon and registering are covered in a later installment.

A new JSP file called welcome.jsp is created:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ page errorPage="errorpage.jsp" %>
<f:view>
<f:loadBundle basename="com.j3ltd.web.messages.ApplicationMessages" var="msg"/>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title><h:outputText value="#{msg.pageTitle}"/></title>
<link href="styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<h:form >
<div class="pageTitle"><h:outputText value="#{msg.welcome}"/></div>
<br/>
<h:panelGrid columns="3"
styleClass="center"
style="border:2px solid black"
headerClass="tableHeader">
<f:facet name="header">
<h:outputText value="#{msg.welcomeBoxTitle}"/>
</f:facet>
<h:outputText value="#{msg.login}"/>


<h:outputText value="#{msg.register}"/>


<h:outputText value="#{msg.forgotPassword}"/>

<h:outputText value=" "/><h:outputText value=" "/><h:outputText value=" "/>

<h:commandLink id="english" action="chooseLocale"
actionListener="#{welcomeBean.onChooseLocale}">
<h:outputText value="#{msg.english}" />
</h:commandLink>
<h:outputText value=" "/>
<h:commandLink id="french" action="chooseLocale"
actionListener="#{welcomeBean.onChooseLocale}">
<h:outputText value="#{msg.french}" />
</h:commandLink>

</h:panelGrid>
</h:form>
</body>
</html>
</f:view>

The page starts with the page directive, after this comes the JSF tag libraries, two of them. the html tag library is used to place JSF widgets on the page, the core library is independent of the rendering used (here it is html), it is usual to have both tag libraries, since every page's JSF content must be enclosed with the core tag "view". By convention, the html tags use the <h:...> prefix, the core tag library tags use the <f:...> prefix.

The error page to use is defined with <%@ page errorPage="errorpage.jsp" %>.

The bundle used in loadBundle contains the internationalized text to display. All the text displayed uses this bundle, as can be seen with the outputText tags.

The form tag acts much like an html form, though it is worth noting that it does not specify which page to submit to. In JSF, the page navigation is placed in a configuration file, which is covered in a later section.

JSF provides a panelGrid tag. It is very much like an html table, the number of columns is specified in the panelGrid tag. The facet "header" is used to provide a heading to the table. The table rows and columns are worked out by JSF, hence it is not necessary to specify where to put a new row or a new column. To create a blank row, three <h:outputText value=" "/> tags are coded

The page as it stands simply allows the user to select the language to use when displaying the page. commandLink tags are used to do select the language to use. When a commandLink tag is clicked by the user, a piece of code in a "managed bean" is called. It is usual to code one managed bean class per JSF page. The managed bean for the welcome page is explained in the next section. The action attribute is hard coded here with the value "chooseLocale", this value is used to decide what page to display next (as explained in a later section)

JBoss 4.03 comes with JSF 1.1. It is worth noting that in JSF 1.2 it is possible to specify a prelude and coda for each page. This makes it possible to place the tag libraries, error page, bundle and <f:view> in the prelude file, and the closing tags in the coda template file. Thus the repetition of this information is no longer required in each page.

The Welcome Page Managed Bean

It is usual for every JSF page to have a managed bean class associated with it. The managed bean class (written in Java) contains the code that the pages use to display computed values or to perform some programming logic. The idea of using JSF is that the JSF page does not contain code, only display information.

In this application, the managed bean for the welcome page is used to change the locale (language used to display welcome.jsp and all future pages).

A new file called Welcome.java is created in the src/com/j3ltd/web folder, which looks like this:

package com.j3ltd.web;

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import java.util.*;


public class Welcome {
    private HashMap<String, Locale> locales = null;

    public Welcome() {
        locales = new HashMap<String, Locale>(2);
        locales.put("english", new Locale("en", "UK"));
        locales.put("french", new Locale("fr", "FR"));
    }
    
    public void onChooseLocale(ActionEvent event) {
        String current = event.getComponent().getId();
        FacesContext context = FacesContext.getCurrentInstance();
        context.getViewRoot().setLocale((Locale) locales.get(current));
    }
}
When the user clicks on a language hyperlink (commandButton tag) in the welcom.jsp page, this managed bean's onChooseLocale() method is invoked. The method gets the "id" of the commandLink, which is either "french" or "english". This "id" value is used to look up the locale to set in the "locales" HashMap. The reason for using a HashMap is that additional languages can be added easily to the class, just by editing the constructor.

Internationalization Message Bundles

The easiest method of storing the text to be displayed is to use properties files. It is also possible to use java classes, but this is not done here. In this example, english and french are supported, the default language is english. The english text is placed in a file within the src folder path as follows: src/com.j3ltd/web/messages/ApplicationMessages.properties. The french version of the text is placed in src/com.j3ltd/web/messages/ApplicationMessages_fr.properties. Java's internationalization framework works out which file to use depending on the language. The file extensions _en for english, _fr for french, _de for german and others are defined as part of Java's internationalization, see http://java.sun.com/docs/books/tutorial/i18n/index.html for more details about internationalization. In the next section, english is configured as the default language to use, so it is not necessary to append "_en" to the filename.

ApplicationMessages.properties looks like this:

###################
#
# MyCV Application localised text, English
#
###################
pageTitle=MyCV, anytime, anywhere, always there
# Welcome Page
welcome=Welcome To MyCV
welcomeBoxTitle=Please select an option from those listed below
register=Register
login=Login
forgotPassword=Forgot Password

#General Values
english=English
french=Français

The french version, called ApplicationMessages_fr.properties looks like this:

###################
#
# MyCV Application localised text, French
#
###################
pageTitle=MyCV, n'importe quand, n'importe où, toujours la
# Welcome Page
welcome=Bienvenu Sur MyCV
welcomeBoxTitle=Selectionnez un des choix ci-dessous svp.
register=Joindre
login=Entrée membre
forgotPassword=Oublié mot de passe
 						  

The faces-config.xml Configuration File

JSF uses a file called faces-config.xml to store JSF specific information about the application. This includes:

  • Which locales are supported.
  • Managed bean names, and the java classes they use.
  • Navigation rules, which specify which page to display following a given action.

Many other things are also present in this file, each one is explained as the need arises.

The file faces-config.xml is created in the src/web folder of the project. At this stage there is very little that needs to go into faces-config.xml:

<?xml version='1.0' encoding='UTF-8'?>
<!--
   Copyright 2004 Sun Microsystems, Inc. All rights reserved.
   SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
   -->
<!DOCTYPE faces-config 
 		PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
 "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
 <faces-config>

  <application>
<message-bundle>com.j3ltd.web.messages.ApplicationMessages</message-bundle>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>fr</supported-locale>
</locale-config>

</application> <!-- Managed Beans --> <managed-bean> <managed-bean-name>welcomeBean</managed-bean-name> <managed-bean-class>com.j3ltd.web.Welcome</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <!-- Navigation Rules --> <navigation-rule> <from-view-id>/welcome.jsp</from-view-id> <navigation-case> <description> Choose locale changes locale then returns to welcome page </description> <from-outcome>chooseLocale</from-outcome> <to-view-id>/welcome.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config>

The internationalization details are given: the message files' location, the default locale (english) and the other locales supported (french).

The managed bean for the welcome page is defined, this bean contains the code that changes the user's locale, depending on the commandLink that is clicked.

The navigation rule states the welcome.jsp navigates to welcome.jsp when the outcome is "chooseLocale". The outcome chooseLocale was hard coded in the welcome.jsp page.

At this point all the code needed to display the welcome page is present. Also the code to change the language in which the page is displayed is present in the managed bean. This is a good point to build and test what has been written so far.

Packaging The Project

At this point there is enough to test that JSF and internationalization are all configured correctly. The project, as seen from the package explorer should look something like this:

The project properties dialog is opened (right click on MyCV in the package explorer and select "Properties..."), and the packaging configuration is selected, note that the "Enable Packaging" checkbox is checked. The add button is pressed and MyCV.war is entered as the archive to generate:

The archive is right clicked and the project file web.xml is added with the prefix WEB-INF. This process is repeated to add faces-config.xml:

MyCV.war is right clicked and "Add Folder" is selected, the "Project Folder" bin is added. **/*.class is entered in the "includes" field to include all the java classes in the bin folder. These classes are to be archived in the WEB-INF/classes folder, the prefix textfield is used to specify this.

MyCV.war is right clicked and "Add Folder" is selected, the "Project Folder" src is added. **/*.ApplicationMessages*.properties is entered in the "includes" field to include all the internationalization message files in the src folder. These files are to be archived in the WEB-INF/classes folder.

Finally the web folder (which contains the style sheet and the jsp files) needs to be added. * is entered in the Includes field, no prefix is specified:

Al the project properties dialogs are dismissed by clicking on OK, or Finish.

In the package explorer, the project MyCV is right clicked and "Run Packaging" is selected to build the war archive file.

Debug The Project

In the package explorer, the project MyCV is right clicked and "Debug As->Debug..." is selected:

This should bring up the debug dialog, with the settings already given during the installation of JBoss (see The section regarding Testing the installation for details).

In the debug dialog, the source tab is selected. The "Add..." button is pressed, to tell the debugger where to find the source files for the project. Finally, the Java Project MyCV is selected:

OK is pressed, in both dialogs to return to the debug dialog, where "Apply" is pressed.

The "Debug" button is pressed, and JBoss is launched. The console window displays the status of JBoss as it starts up, as mentioned in the installation chapter, any exception stack traces in the Eclipse console should be resolved before going any further. When the console finally says that JBoss has started, the war file MyCV.war is right clicked in the package explorer, and "deployment->deploy to" is selected:

The deployment dialog should show the JBoss configuration already defined in the "Test Installation" chapter.

A browser is opened, and the URL http://localhost:8080/MyCV is entered:

Clicking on the "Français" hyperlink displays the french version of the page:

This completes the first step in the project. The following has been achieved:

  • JSF, as supplied with JBoss is configured, and an Eclipse library has been created for JSF.
  • Internationalization is implemented and working.
  • An error page has been implemented.
  • A JSF page and managed bean have been created, configured and tested (the welcome page).

The next step is to implement the registration process, so that a user can become a member of MyCV.

 

  Copyright © 2006 J3 Ltd Permission is granted to reproduce material on this page, on the condition that a reference to "WWW.J3Ltd.com" is given as the source of the material.