JBoss.orgCommunity Documentation
We highly recommend developing in Seam. This chapter is for users who for some reason cannot use Seam.
In this chapter you will learn how to create a simple JSF application being based on the "RAD" philosophy. We will create the familiar Guess Number application. The game is played according to the following rules. You are asked to guess a number between 0 and 100. If the guess is correct, a success page is displayed with a link to play again. If the guess is incorrect, a message is printed notifying that a smaller or a larger number should be entered and the game continues.
We'll show you how to create such an application from scratch, along the way demonstrating the powerful features included in JBoss Developer Studio such as project templating, Visual Page Editor, code completion and others. You will design the JSF application and then run the application from inside JBoss Developer Studio using the bundled JBoss server.
First, you should create a JSF 1.2 project using an integrated JBDS's new project wizard and predefined templates. Follow the next steps:
In the Web Projects view (if it is not open select
→ → → → ) click button.
Enter GuessNumber as a project name, in JSF Environment drop down list choose JSF 1.2
Leave everything else as it is and click the
buttonOur project will appear in the Project Explorer and Web Projects views. As you can see
JBoss Developer Studio has created the entire skeleton for the project with all
required libraries, faces-config.xml
file and web.xml
file.
As the project has been set up, new JSP pages should now be created.
Here, we are going to add two pages to our application. The first page is called
inputnumber.jsp
. It prompts you to enter a number. If the guess is incorrect, the same
page will be redisplayed with a message indicating whether a smaller or a larger number
should be tried. The second page is called success.jsp
. This page will be shown after you guess
the number correctly. From this page you also have the option to play the game again.
Now, we will guide you through the steps on how to do this.
First a folder called pages
needs to be created under the WebContent
folder. To do this right click on the WebContent
folder in the Package Explorer view and select → . Set the Folder Name to pages
and click the button.
Open the faces-config.xml
file.
Right click anywhere on the diagram mode
From the context menu select
Type pages/inputnumber as the value for the From View ID field
Leave everything else as is and click the
buttonIn the same way create another JSF view. Type pages/success as the value for From View ID
Select
→On the diagram you will see two created views.
Then, we should create connection between JSP pages.
In the diagram, select the
icon third from the top along the upper left side of the diagram to get an arrow cursor with a two-pronged plug at the arrow's bottom
Click on the pages/inputnumber page icon and then click on the pages/success page icon
A transition should appear between the two icons of views.
Select
→ from the menu barA resource file is just a file with a .properties extension for collecting text messages in one central place. JBoss Developer Studio allows you to create quickly a resource file. The messages stored in resource file can be displayed to you on a Web page during application execution.
With resource file you don't hard code anything into the JSP pages. It also makes it easier to translate your application to other languages. All you have to do is to translate all your messages to the other language and save them in a new properties file with a name that ends with the appropriate ISO-639 language code.
It is a good idea to keep your resources inside the JavaSource
folder, where you keep your .java files. Every time you build the project, all .properties files will then be copied to the classes
folder by default.
Right click the JavaSource
folder and select →
Enter game
as the Folder name and click the button
Your resource file and java bean will be stored in this folder.
Right click on the game
folder and select →
Type messages as the value for "name" attribute and click the button
JBoss Developer Studio will automatically open messages.properties file for editing.
Click the
button for adding new attribute to your resource fileEnter how_to_play for the "name" and Please pick a number between 0 and 100. for the value
Click the
buttonAdd the following properties using the same process:
makeguess_button=Make Guess trayagain_button=Play Again? success_text=How cool.. You have guessed the number, {0} is correct! tryagain_smaller=Oops..incorrect guess. Please try a smaller number. tryagain_bigger=Oops..incorrect guess. Please try a bigger number.
Select
→ from the menu barYour .properties file should now look like follows:
The
and buttons allow you to move the attributes in the list. To delete the attribute, select it and press the button.If you want to change a value or a name of your attribute, select it and then click the
button.If the .properties file is rather big and there are a lot of entries in it, you can use filtering and regular expressions narrow down the list. The Filter and Regular Expressions Search is implemented by an expandable panel, closed by default:
When "Expression" is not selected (as by default), filter is case insensitive. When "Expression" is selected, filter uses regular expressions which are case sensitive
Enter the characters that should be searched for in the entries to the 'name' or 'value' input fields accordingly. The filtered results will be displayed in the table below:
When using regular expressions please note, that regular expression syntax does not use "*" for any characters and "?" for any one character. It's necessary to use "." for any one character and ".*" for any characters. Symbols "*" and "?" are used to show that the preceding token is not required, for example, "a.a" matches "aba" but not "aa", while "a.?a" or a.*a" matches both; besides "a.*a" matches "abcda".
To find the exact match, use sequences \A and \z in expression. For example, expression "\Adate\z" matches only string "date"; expression "\Adate" matches "date" and "dateline", expression "date\z" matches "date" and "Begin date", and expression "date" matches all of them.
In this section you'll learn how to create a Java bean that will hold business logic of our application.
Right click the game
folder
Select
→Type NumberBean for bean name
A java bean is created.
Declare the variable of your entered number:
Integer userNumber;
JBDS allows to quickly generate getters and setters for java bean.
Right click the NumberBean.java
file in the Package Explorer view
Select
→Check userNumber box and click the button
Add the declaration of the second variable
int randomNumber;
.. other bean methods:
public NumberBean () { randomNumber = (int)(Math.random()*100); System.out.println ( "Random number: "+randomNumber); } public String playagain () { FacesContext context = FacesContext.getCurrentInstance(); HttpSession session = (HttpSession) context.getExternalContext().getSession(false); session.invalidate(); return "playagain"; } public String checkGuess () { // if guessed, return 'success' for navigation if ( userNumber.intValue() == randomNumber ) { return "success"; } else { FacesContext context = FacesContext.getCurrentInstance(); ResourceBundle bundle = ResourceBundle.getBundle("game.messages", context.getViewRoot().getLocale()); String msg = ""; // if number bigger, get appropriate message if ( userNumber.intValue() > randomNumber ) msg = bundle.getString("tryagain_smaller"); else // if number smaller, get appropriate message msg = bundle.getString("tryagain_bigger"); // add message to be displayed on the page via <h:messages> tag context.addMessage (null, new FacesMessage(msg)); // return 'tryagain' for navigation return "tryagain"; } }
And the import declarations:
import javax.faces.context.FacesContext; import javax.servlet.http.HttpSession; import javax.faces.application.FacesMessage; import java.util.ResourceBundle;
The whole java bean contain the following code:
package game; import javax.faces.context.FacesContext; import javax.servlet.http.HttpSession; import javax.faces.application.FacesMessage; import java.util.ResourceBundle; public class NumberBean { Integer userNumber; int randomNumber; // random number generated by application public Integer getUserNumber () { return userNumber; } public void setUserNumber (Integer value) { this.userNumber = value; } // constructor, generates random number public NumberBean () { randomNumber = (int)(Math.random()*100); System.out.println ( "Random number: " + randomNumber); } public String playagain () { FacesContext context = FacesContext.getCurrentInstance(); HttpSession session = (HttpSession) context.getExternalContext().getSession(false); session.invalidate(); return "playagain"; } // check if user guessed the number public String checkGuess () { // if guessed, return 'success' for navigation if ( userNumber.intValue() == randomNumber ) { return "success"; } // incorrect guess else { // get a reference to properties file to retrieve messages FacesContext context = FacesContext.getCurrentInstance(); ResourceBundle bundle = ResourceBundle.getBundle("game.messages", context.getViewRoot().getLocale()); String msg = ""; // if number is bigger, get appropriate message if ( userNumber.intValue() > randomNumber ) msg = bundle.getString("tryagain_smaller"); else // if number smaller, get appropriate message msg = bundle.getString("tryagain_bigger"); // add message to be displayed on the page via <h:messages> tag context.addMessage (null, new FacesMessage(msg)); // return 'tryagain' for navigation return "tryagain"; } } }
In this section you will learn about the faces-config.xml
file.
This file holds two navigation rules and defines the backing bean used.
Open the faces-config.xml
file in a source mode
Here we will add one more navigation rule and a managed bean declaration, so that the content of the file looks like this:
<?xml version="1.0" encoding="UTF-8"?> <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2_.xsd"> <navigation-rule> <from-view-id>*</from-view-id> <navigation-case> <from-outcome>playagain</from-outcome> <to-view-id>/pages/inputnumber.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/pages/inputnumber.jsp</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/pages/success.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>NumberBean</managed-bean-name> <managed-bean-class>game.NumberBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config>
The first navigation rule states that from any page (* stands for any page) an outcome of playagain will take you to the /pages/inputnumber.jsp
file. Outcome values are returned from backing bean methods in this example. The second navigation rule states that if you are at the page /pages/inputnumber.jsp
, and the outcome is success, then navigate to the /pages/success.jsp
page.
Now, we will continue editing the JSP files for our two "views" using the Visual Page Editor.
First, edit the inputnumber.jsp
file.
On this page we will have an output text component displaying a message, a text field for user's number entering and a button for input submission.
Open the inputnumber.jsp
file by double-clicking on the /pages/inputnumber. jsp
icon
The Visual Page Editor will open in a screen split between source code along the top and a WYSIWIG view along the bottom. You can see that some JSF code will have already been generated since we chose a template when creating the page.
At the beginning it's necessary to create a <h:form>
component that will hold the other components.
Place the mouse cursor inside the <f:view></f:view>
tag
Go to JBoss Tools Palette and expand JSF HTML folder by selecting it
Click on the <h:form>
tag
In the Insert Tag dialog select the id field and click on the second column. A blinking cursor will appear in a input text field inviting to enter a value of id
Enter inputNumbers and click the button
In source view you can see the declaration of a form.
First let's declare the properties file in the inputnumber.jsp
page using the loadBundle JSF tag.
Add this declaration on the top of a page, right after the first two lines:
<f:loadBundle basename="game.messages" var="msg"/>
As always JBDS provides code assist:
Switch to Visual tab, where it is possible to work with the editor through a WYSIWYG interface
Click the outputText item from the JSF HTML group in the JBoss Tools Palette view, drag the cursor over to the editor, and drop it inside the blue box in the editor
Select the second column in the value row.
Click the
button next to the value fieldJBDS will display a list of possible values:
Expand
→Select the how_to_play value and click the button. Then click the button.
The text will appear on the page:
Switch to Source mode and insert a <br/>
tag after the <h:outputText>
component to make a new line.
Click the
button.On the Palette click on inputText, drag the cursor over to the editor, and drop it inside the editor after the text.
Switch to a Source mode and insert a <br/>
tag after the <h:outputText>
component to make a new line
Click the
buttonOn the Palette click on inputText, drag the cursor over to the editor, and drop it inside the editor after the text
Select the value row and click in the second column
Click the
button next to the value fieldExpand
→Select userNumber value and click the button
Select the Advanced tab
Select the id row and click in the second column
Type userNumber in the text field
Select the required row and click in the second column
Click
button next to the value fieldExpand Enumeration and select true as a value
Click the
button, then click the buttonGo to Source mode
Add the validation attribute to <f:validateLongRange>
for user input validation
<h:inputText id="userNumber" value="#{NumberBean.userNumber}" required="true"> <f:validateLongRange minimum="0" maximum="100"/> </h:inputText>
Click the
buttonAgain select Visual mode
On the Palette, click on commandButton, drag the cursor over to the editor, and drop it inside the editor after the inputText
component.
In the editing dialog select the value row and click on the second column
Click the
button next to the value fieldExpand makeguess_button as a value
→ and selectClick the
buttonSelect the action row and click in the second column
Type #{NumberBean.checkGuess} in the text field
Click the
buttonIn Source mode add <br/>
tags between the <outputText>
, <inputText>
and <commandButton>
components to place them on different lines
inputnumber.jsp
page should look like this:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <f:loadBundle basename="game.messages" var="msg"/> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <f:view> <h:form id="inputNumbers"> <h:outputText value="#{msg.how_to_play}"/> <br/> <h:messages style="color: blue" /> <br/> <h:inputText id="userNumber" required="true" value="#{NumberBean.userNumber}"> <f:validateLongRange minimum="0" maximum="100" /> </h:inputText> <br/> <br/> <h:commandButton action="#{NumberBean.checkGuess}" value="#{msg.makeguess_button}"/> </h:form> </f:view> </body> </html>
We now edit the success.jsp
page in the same way as we just edited the inputnumber.jsp
file. The code for the success.jsp
page should look like the following:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <f:loadBundle basename="game.messages" var="msg"/> <html> <head> <title></title> </head> <body> <f:view> <h:form id="result"> <h:outputFormat value="#{msg.success_text}"> <f:param value="#{NumberBean.userNumber}" /> </h:outputFormat> <br /> <br /> <h:commandButton value="#{msg.trayagain_button}" action="#{NumberBean.playagain}" /> </h:form> </f:view> </body> </html>
Again you can use code assist provided by JBDS when editing jsp page:
The success.jsp
page is shown if you correctly guessed the number. The <h:outputFormat>
tag will get the value of success_text
from the properties file. The {0}
in success_text
will be substituted for by the value of the value attribute within the <f:param>
tag during runtime.
In the final result you have a button which allows you to replay the game. The action
value references a backing bean method. In this case, the method only terminates the current session so that when you are shown the first page, the input text box is clear and a new random number is generated.
Switch to Preview mode to see how this page will look in a browser:
Now we need to create the index.jsp
page.
The index.jsp
page is the entry point of our application. It's just forwarding to the inputnumber.jsp
page.
Right click the WebContent
folder and select →
Enter index
for name field and click the button.
Untick the Use JSP Template check box and click the button.
Edit the source of the file so it looks like the following:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <body> <jsp:forward page="/pages/inputnumber.jsf" /> </body> </html>
Note the .jsf extension of a page. It means that we trigger the JSF controller servlet to handle the page according the servlet mapping in the faces-config.xml
file.
Finally, we have all the pieces needed to run the application.
Start up JBoss server by clicking on the Servers view. (If the JBoss Server is already running, stop it by clicking on the red icon and then start it again. After the messages in the Console tabbed view stop scrolling, JBoss is available)
icon in theRight-click on the project and select
→Play with the application by entering correct as well as incorrect values
Figure 5.25. After You Enter a Guess, the Application Tells You Whether a Smaller or a Larger Number Should be Tried