December 2006 [Revision number: V1-2] |
|
|
In this tutorial, you use NetBeans Visual Web Pack 5.5 to create an application that demonstrates how to use application, session, and request
scopes to manage your application's objects. Scope is the availability
(or context) of an object and its intended life span in a web
application.
The web application that you
create in this tutorial uses an object in application scope to tally
votes, and uses an object in session scope to ensure that a user votes
only once per session. The application uses a request scope object to
display the time that the user submitted the vote. The time is stored
in request scope, because the application does not need the value after
the response is sent to the client browser. |
Contents
|
|
 |
This tutorial works with the following resources
NetBeans Visual Web Pack 5.5 works with all supported servers and works
with both the Java EE 1.4 and Java EE 5 platforms. This tutorial
illustrates the Visual Web Pack features that work with the resources
check marked in the following table. For detailed information about the
supported servers and Java EE platform, see NetBeans Visual Web Pack 5.5 Installation Instructions.
Application Server |
Sun Java System Application Server 9
Tomcat
JBoss
BEA WebLogic |
JavaServer Faces Components/
Java EE Platform |
1.2 with Java EE 5*
1.1 with J2EE 1.4
|
Travel Database |
Not Required |
BluePrints AJAX Component Library |
Not Required |
* Only the Sun Java System Application Server supports Java EE 5.
About Scopes
As
long as a user stays on a page, the component values are remembered
even when the page redisplays, such as when the user clicks a button
that returns null. However, when the user leaves the page, the
component values disappear.
To make values available
to other pages, or to make values available to the same page, should
the user return to it, you need to store the values. When you create a
project from the IDE, the IDE creates three managed beans for storing values:
RequestBean1
SessionBean1
ApplicationBean1
The following figure shows the Outline window with the default managed beans.
Figure 1: Default Managed Beans |
A managed bean is
a JavaBeans object that a JavaServer Faces web application instantiates
and stores in either request scope, session scope, or application
scope. As you can guess, the web application stores RequestBean1 in request scope, SessionBean1 in session scope, and ApplicationBean1 in application scope.
To add a property to one of these managed beans, right-click the bean
in the Outline window and choose Add > Property from the pop-up
menu. After you complete the dialog and click OK, the IDE adds the
property and its appropriate getter and setter methods to the source
code. You can access a bean property's value by binding a component's
property to it, or by calling the bean property's getter and setter
methods. You use both access methods in this tutorial.
Before you create a bean property to store a value, you must determine
the appropriate scope for the property's value. Because several users
can access a web application at the same time, you want to use the
smallest scope possible so that you don't waste valuable space. The
following figure illustrates the duration of each type of scope.
- Application
scope lasts until the server stops the application. Values that you
store in an application bean are available to every session and every
request that uses the same application map.
- Session
scope begins when a user first accesses a page in the web application
and ends when the session times out due to inactivity, or when the web
application invalidates the session, such as, for example, by calling
session.invalidate() .
- Request scope begins when the user submits the page and ends when the response is fully rendered, whatever page that is.
Figure 2: Web Application Scopes |
Say that your web
application has a drop-down list of measurement types (pixels,
centimeters, and inches). You might want to store the list of choices
in ApplicationBean1 , so that the list is shared by all concurrent user sessions. On the other hand, you might store the user's login name in SessionBean1 ,
so that the name is available for all the pages that the user accesses
in that session. If you don't need the information beyond the lifetime
of the current request, you can save space by putting the property in RequestBean1 .
Warning: You cannot use a request bean if you have included the <redirect> element inside the <navigation-case>
element of a navigation rule. (You see these rules when you click the
XML button in the Page Navigation editor.) When the page is submitted,
the <redirect> element redirects the page and ends the request before a subsequent page can use any of the values stored in the Request Bean.
When you create a page from the IDE, the Java source for the page bean contains methods for accessing the RequestBean1 , SessionBean1 , and ApplicationBean1 objects. To access properties on these managed beans, you use code similar to the statements in the following code snippet.
Code Sample 1: Accessing an Application Bean Property |
ApplicationBean1 appBean = getApplicationBean1();
Option[] choices = appBean.BallotOptions(); |
The web application
instantiates a managed bean the first time, within that bean's scope,
that a page accesses a property in the managed bean. For example, an
instance of a SessionBean1 object does not exist for the user's session until the user accesses a page that references a SessionBean1 property.
Tip:
To add additional managed beans, expand the Source Packages node in the
Projects window, right-click the package node, choose New >
Files/Folders, select the Managed Beans category, select the scope, and
complete the remaining wizard steps.
Adding Properties to the Managed Beans
The pages in this web application require access to the following values:
ballotOptions .
This array contains the ballot choices. Because the list remains the
same for all sessions, this property goes in application scope.
tally . Because the tally accumulates all the session votes, it must be in application scope.
hasVoted .
This boolean property tracks whether the user has voted. Because the
application needs to persist the value across several requests, the
application stores the value in session scope.
timestamp .
When the user submits a vote, the application records the time for use
by the next page. Because the application does not need the value after
the next page is rendered, the application stores the value in request
scope.
Complete the following steps to add the properties to the managed beans.
- From the main menu, choose File > New Project.
- In the New Project Wizard, select Web from the Categories list and select Visual Web Application from the Projects list.
- Click Next.
- Name the project
Scopes and click Finish.
-
In the Outline window, right-click ApplicationBean1 and choose Add > Property from the pop-up menu.
A New Property Pattern dialog box appears as shown in the following figure.
Figure 3: New Property Pattern Dialog Box |
-
Set the property's Name and Type as follows, and click OK.
Text Field |
Value |
Name |
ballotOptions |
Type |
Option[] |
|
-
Use similar steps to add another property to the application bean. Set the property's Name and Type as follows, and click OK.
Text Field |
Value |
Name |
tally |
Type |
HashMap |
|
- In the Outline window, right-click ApplicationBean1 and choose Edit Java Source from the pop-up window.
-
Right-click in the source and choose Fix Imports from the pop-up menu.
Because there is more than one package that contains the Option class, the Fix Imports dialog appears.
-
Select com.sun.webui.jsf.model.Option from the Fully Qualified Name drop-down list, and click OK.
The IDE adds import statements for the following classes to the source:
com.sun.webui.jsf.model.Option
java.util.HashMap
-
Scroll to the init method and add the following code at the bottom of the method.
Code Sample 2: Code to Add to the Application Bean's init Method |
// populate ballot items
ballotOptions = new Option[] {
new Option("java", "Java Programming Language"),
new Option("cpp", "C++"),
new Option("fortran", "Fortran")
};
// initialize counters for ballot choices
tally = new HashMap();
for (int i=0; i < ballotOptions.length; i++) {
this.tally.put(ballotOptions[i].getValue(), "0");
} |
-
Add the following methods at the end of the file, just before the last end brace.
Code Sample 3: Application Bean Vote Counting Methods |
/**
* Vote counter for property tally.
*/
public void incrementTallyFor(String category) {
int count = getTallyFor(category);
count++;
this.tally.put(category, Integer.toString(count));
}
/**
* Getter for value in property tally.
* @param category HashMap key
* @return Value to which the specified key is mapped
*/
public int getTallyFor(String category) {
String stringCount = (String) this.tally.get(category);
if (stringCount == null) {
return 0;
} else {
int count = Integer.valueOf(stringCount).intValue();
return count;
}
}
|
- Press Ctrl-S to save your changes, and press Ctrl-F4 to close the file.
-
In the Outline window, right-click SessionBean1 and choose Add > Property from the pop-up menu.
If the Outline window is not open, click the Page1 tab in the editing
area and click Design in the editing toolbar. The Outline window
appears when the IDE is in design mode.
-
Set the property's Name and Type as follows, and click OK.
Text Field |
Value |
Name |
hasVoted |
Type |
boolean |
|
- In the Outline window, right-click SessionBean1 and choose Edit Java Source from the pop-up menu.
-
Scroll to the init method and add the following code at the bottom of the method.
Code Sample 4: Code to Add to the Session Bean's init Method |
setHasVoted(false); |
- Press Ctrl-S to save your changes, and press Ctrl-F4 to close the file.
- In the Outline window, right-click RequestBean1 and choose Add > Property from the pop-up menu.
-
Set the property's Name and Type as follows, and click OK.
Text Field |
Value |
Name |
timestamp |
Type |
java.util.Date |
|
-
Check
the Outline window to ensure that the properties in the request bean,
session bean, and application bean match the following figure. You
might need to open and save the Java source code for RequestBean1 to make the timestamp property appear.
Figure 4: Request, Session, and Application Bean Properties |
Creating the Start Page
Follow
these steps to create the page shown in the following figure. This page
submits the user's vote. Once the user has voted, the button becomes
disabled so that the user cannot vote again in that session.
Figure 5: Page1 |
- Drag
a Label component from the Basic section of the Palette, drop it onto
the top center of the page, and set the label's text to
Reader's Poll: What Is Your Favorite Programming Language? .
- Drop a Radio Button Group component beneath the Label component.
- In the Properties window, set the component's
id to voteRBGroup .
-
Right-click the Radio Button Group component and choose Bind to Data from the pop-up menu.
A Bind to Data dialog box appears.
- In the Bind to an Object tab of the dialog box, select ApplicationBean1 > ballotOptions, and click OK.
- Drop a Button under the Radio Button Group component, and set its text to
View Results .
- In the Properties window, set the
id to viewButton .
-
Click the ellipsis (... ) button for the action property, select viewButton_action from the drop-down list, and click OK.
The IDE adds the viewButton_action event handler, which returns null.
- Drop a Button component to the right of the View Results button, and set its text to
Submit Vote .
- In the Properties window, set the
id to voteButton .
-
Click the ellipsis (... ) button for the disabled property.
A dialog box appears.
-
In
the dialog box, select Use Binding, click Bind to an Object, select
SessionBean1 > hasVoted, as shown in the following figure, and click
OK.
Figure 6: Binding the disabled Property |
-
Double-click the Submit Vote button.
The IDE adds the voteButton_action action handler, opens the Java source for the page, and displays the method.
-
Replace the body of the method with the following code that is shown in bold.
Code Sample 5: voteButton_action Method |
public String voteButton_action() {
if (voteRBGroup.getSelected() == null) {
return null;
}
// Tallies are kept across all user sessions
String votedFor = voteRBGroup.getSelected().toString();
getApplicationBean1().incrementTallyFor(votedFor);
// User can only vote one time per session
getSessionBean1().setHasVoted(true);
// Don't need the timestamp after the next request ends
Date now = new Date();
getRequestBean1().setTimestamp(now);
return null;
} |
- Right-click in the source and choose Fix Imports from the pop-up menu.
- Select java.util.Date from the Fully Qualified Name drop-down list, and click OK.
Creating the Results Page
Follow
these steps to create the page shown in the following figure. This page
displays the current tally. The user can click the Refresh Results
button to get the latest tally, which includes the votes that have been
submitted by other users since the page was last displayed.
Figure 7: Results |
- Create a new page and name it
Results .
- Drop a Label component on the top center of the Results page, and set the text to
Results .
- Drop a Button component to the left of the Label component and set its text to
Home.
- Set the Button component's
id to homeButton .
- Click the ellipsis (
... ) button for the action property, select homeButton_action from the drop-down list, and click OK.
- Drop a Button component to the right of the Label component and set its text to
Refresh Results.
- Set the Button component's
id to refreshButton .
- Click the ellipsis (
... ) button for the action property, select refreshButton_action from the drop-down list, and click OK.
- Drag a Grid Panel component from the Layout section of the Palette and drop it under the Label Component.
- In the Properties window, set the
cellspacing property to 10 .
- Set the
columns property to 1 .
-
Drag
a Static Text component inside the Grid Layout component. When the
outline of the Grid Layout component becomes a solid blue line, drop
the Static Text component, as shown in the following figure.
Figure 8: Dropping a Component Into a Grid Panel Component |
- In the Properties window, set the
id to resultsST . Leave its text property blank.
-
Clear the checkbox for the escape property.
Later, you add code to put HTML in the component's text property. By setting the escape property to false, the HTML code will be passed to the browser unaltered.
- Drag
another Static Text component onto the Grid Panel component, and, when
the outline of the Grid Layout component becomes a solid blue line,
drop the Static Text component.
- Set the Static Text component's
id to messageST . Leave its text property blank.
- Click Java in the editing toolbar to view the Java source for the page.
-
Scroll to the prerender method and add the following code shown in bold.
Code Sample 6: prerender Method |
public void prerender() {
// Display latest poll results
ApplicationBean1 appBean = getApplicationBean1();
Option[] choices = appBean.getBallotOptions();
String str = "<table border=\"0\" cellpadding=\"5\">";
for (int i = 0; i < choices.length; i++) {
int count = appBean.getTallyFor(choices[i].getValue().toString());
str = str + "<tr><td>" +
choices[i].getLabel() +
"</td><td>" +
count +
"</td></tr>";
}
str = str + "</table>";
resultsST.setText(str);
RequestBean1 reqBean = getRequestBean1();
Date timestamp = (Date) reqBean.getTimestamp();
if (timestamp != null) {
messageST.setText("Your vote was recorded at " +
(String)DateFormat.getTimeInstance(DateFormat.LONG).format(
timestamp));
}
} |
This code creates an HTML table that contains the tally for each vote and puts the HTML table in the text
property for the first Static Text component. If the user just voted,
the second Static Text component displays the date and time the vote
was registered.
- Right-click in the source and choose Fix Imports from the pop-up menu.
- Select
java.util.Date for from the Fully Qualified Name drop-down list for
Class Name Date, select com.sun.webui.jsf.model.Option for Class Name
Option, and click OK.
Specifying Page Navigation
Follow these steps to specify the page navigation for the buttons, as shown in the following figure.
Figure 9 : Navigation Window |
- In the editing area, click the Results tab and click Design to view the page in the Visual Designer.
- Right-click on a blank spot in the page and choose Page Navigation from the pop-up menu.
- Click the Page1.jsp icon to enlarge the icon.
- Click
the connector port next to viewButton and drag to Results.jsp to create
a connector between the button and the Results page.
- Double-click the connector's label to change to edit mode, double-click to select the text, type
view results and press Enter.
- Click the Page1.jsp icon to enlarge the icon again, click the connector port next to voteButton, and drag to Results.jsp.
- Double-click the connector's label to change to edit mode, double-click to select the text, type
vote and press Enter.
- Click the Results.jsp icon to enlarge the icon.
- Click the connector port next to homeButton and drag to Page1.jsp.
- Double-click the connector's label to change to edit mode, double-click to select the text, type
home and press Enter.
Running the Application
To
enable multiple sessions from the same browser, configure the
application to end each session after one minute of inactivity. Then
deploy and run the application.
-
In the Files window, expand Scopes > web >WEB-INF, as shown in the following figure.
Figure 10: Files Window |
- Right-click web.xml and choose Open from the pop-up menu.
-
Type 1 in the Session Timeout text box, as shown in the following figure.
Figure 11: Setting Session Timeout in the web.xml Visual Editor |
- Close the file.
- Click the Run Main Project button in the main toolbar.
-
When the start page appears, select a radio button and click Submit Vote.
The browser displays the results page. Note that the results page shows the time that you submitted your vote.
-
Click Home to return to the start page.
The Submit Vote is disabled because you have voted.
-
Click View Results.
Note that the results page no longer shows the time that you voted.
This is because the previous request bean is out of scope and a new
request bean has been instantiated.
- Wait
one minute for the session to time out. Then type the following URL
into the browser's address text box, and press Enter to start a new
session:
http://localhost:8080/Scopes . You might need to change 8080 to a different port if you are not using the default server configuration.
- Vote again and check the results. The results should include your first vote.
- If you have a different browser application, start that browser, type
http://localhost:8080/Scopes into the browser's address text box, and press Enter. Submit another vote.
-
In the first browser, click Refresh Results from the results page.
The results should include the vote that you submitted from the second browser.
Doing More
Using
what you have learned in this tutorial, build an application that
prompts for a login name. Add a page that displays the number of unique
users who have accessed the web application.
Summary
You use the application bean, the session bean, and the request bean to store information for use by other pages.
- Use the application bean for information that applies to all user sessions, such as a static option list for a Drop Down List component.
- Use the session bean to store information for use by other pages throughout the user's session, such as the user's login name.
- If you only need the information for use by the next page, use the request bean.
Warning: You cannot use the request bean if you have included the <redirect> element inside the <navigation-case> element of a navigation rule.
A
request bean, session bean, or application bean is instantiated as soon
as a page accesses one of its properties. The bean is destroyed when
its scope ends.
To add a property to the Session Bean,
right-click the Session Bean node in the Outline window and choose Add
> Property. Use similar steps to add a property to the Request Bean
or the Application Bean.
This page was last modified: December 6, 2006
|