© 2005 Marty Hall
JSF: Controlling
Page Navigation
Core Servlets & JSP book: [Link]
More Servlets & JSP book: [Link]
Servlet/JSP/Struts/JSF Training: [Link]
[Link] -- Hands-on, customized training for Java, servlets, JSP, Struts, and JSF.
© 2005 Marty Hall
For live JSF training, please see
JSP/servlet/Struts/JSF training courses at
[Link]
Taught by the author of Core Servlets and JSP, More
Servlets and JSP, and this tutorial. Available at
public venues, or customized versions can be held
on-site at your organization.
[Link] -- Hands-on, customized training for Java, servlets, JSP, Struts, and JSF.
Topics in This Chapter
• JSF flow of control
• The basic steps in using JSF
• Static navigation
– One result mapping
• Dynamic navigation
– Multiple result mappings
4 J2EE training and tutorials: [Link]
JSF Flow of Control
• A form is built from a palette of GUI
components and displayed to the user
• The form is submitted to itself
– I.e., both original URL and ACTION URL are
[Link]
• A bean is created that represents the form
data
• The action designated by the form is
invoked
– This method uses the data from the form bean, invokes
business-logic and data-access logic, and creates/stores
results beans
• The action method returns a condition
• The page corresponding to the condition is
5
displayed J2EE training and tutorials: [Link]
Steps in Using JSF
1. Create a bean to represent the form data
• Postponed until next section
2. Use f:view and h:form to create an input
form
3. Specify the action controller with the
action attribute of h:commandButton
4. Create an action controller that reads the
form data, invokes business logic, stores
results beans, and returns conditions
5. Use [Link] to declare the form
bean and navigation rules
6. Create JSP pages corresponding to each
return condition
7. Protect raw JSP pages from access
6 J2EE training and tutorials: [Link]
Example 1: Static Navigation
• Started by copying jsf-blank and renaming it
to jsf-test
• Original URL will be
[Link]
• When form submitted, a static page
([Link]) is displayed
• No business logic, beans, or Java code of
any sort
• Main points
– Format of original form
– Use of the [Link] file
7 J2EE training and tutorials: [Link]
Main Points of This Example
• Input form has following format:
<%@ taglib uri="[Link] prefix="f" %>
<%@ taglib uri="[Link] prefix="h" %>
<f:view>
HTML markup
<h:form>
HTML markup and h: tags
</h:form>
HTML markup
</f:view>
• You use [Link] to declare mappings:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC …>
<faces-config>
<navigation-rule>
<from-view-id>/[Link]</from-view-id>
<navigation-case>
<from-outcome>some string</from-outcome>
<to-view-id>/WEB-INF/results/[Link]</to-view-id>
</navigation-case>
</navigation-rule>
8 </faces-config> J2EE training and tutorials: [Link]
Step 1: Create Form Bean
• Postponed until next section
– This example ignores form data
9 J2EE training and tutorials: [Link]
Step 2: Create Input Form
• Basic format
<%@ taglib uri="[Link] prefix="f" %>
<%@ taglib uri="[Link] prefix="h" %>
<f:view>
…
<BODY>
…
<h:form>
…
</h:form>
…
</BODY>
</f:view>
• Invoking page
– Actual file is [Link]
– URL is [Link]
10 J2EE training and tutorials: [Link]
Step 2: Create Input Form
• The h:form element
– ACTION is automatically self (current URL)
– METHOD is automatically POST
• Elements inside h:form
– Use special tags to represent input elements
• h:inputText corresponds to <INPUT TYPE="TEXT">
• h:inputSecret corresponds to <INPUT TYPE="PASSWORD">
• h:commandButton corresponds to <INPUT TYPE="SUBMIT">
– In later sections, we will see that input elements will be
automatically associated with bean properties
– For static navigation, specify arbitrary string as action of
h:commandButton
• String must match navigation rule from [Link]
• More info on h:blah elements
– [Link]
11 J2EE training and tutorials: [Link]
Step 2: Example Code
<%@ taglib uri="[Link] prefix="f" %>
<%@ taglib uri="[Link] prefix="h" %>
<f:view>
<!DOCTYPE …>
<HTML>
<HEAD>…</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">New Account Registration</TH></TR>
</TABLE>
<P>
<h:form>
Email address: <h:inputText/><BR>
Password: <h:inputSecret/><BR>
<h:commandButton value="Sign Me Up!" action="register"/>
</h:form>
</CENTER></BODY></HTML>
</f:view>
12 J2EE training and tutorials: [Link]
Step 3: Specify Action Controller
• Use the action attribute of h:commandButton
• For most real cases, you specify a method to be
called when form is submitted
– The method returns various strings, and [Link] maps the
strings to output pages
– See upcoming example for details
• For static navigation, you specify a simple string
– [Link] maps the string to an output page
• Example
<h:form>
Email address: <h:inputText/><BR>
Password: <h:inputSecret/><BR>
<h:commandButton value="Sign Me Up!" action="register"/>
</h:form>
13 J2EE training and tutorials: [Link]
Steps 2 & 3: Example Results
• File is tomcat_dir/webapps/jsf-test/[Link]
• URL is [Link]
14 J2EE training and tutorials: [Link]
Step 4: Create an Action
Controller
• Postponed until next section
– This example ignores form data and invokes no logic or
Java code of any sort
15 J2EE training and tutorials: [Link]
Step 5: Update [Link]
• General format
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC …>
<faces-config>
…
</faces-config>
• Specifying the navigation rule
…
<faces-config>
<navigation-rule>
<from-view-id>/[Link]</from-view-id>
<navigation-case>
<from-outcome>string-from-action</from-outcome>
<to-view-id>/WEB-INF/…/[Link]</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
16 J2EE training and tutorials: [Link]
Step 5: Example Code
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC …>
<faces-config>
<navigation-rule>
<from-view-id>/[Link]</from-view-id>
<navigation-case>
<from-outcome>register</from-outcome>
<to-view-id>/WEB-INF/results/[Link]</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
17 J2EE training and tutorials: [Link]
Step 6: Create Output JSP Page
• Note that [Link] is
used behind the scenes
– So page can be in WEB-INF
• Example code:
– …/jsf-test/WEB-INF/results/[Link]
<!DOCTYPE …>
<HTML>
<HEAD>…</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">Success</TH></TR>
</TABLE>
<H2>You have registered successfully.<BR>
(Version 1)</H2>
</CENTER>
</BODY></HTML>
18 J2EE training and tutorials: [Link]
Step 6: Example Result
• Note that URL is unchanged
19 J2EE training and tutorials: [Link]
Step 7: Protect Raw JSP Pages
• Filename/URL correspondence
– Actual files are of the form [Link]
– URLs used are of the form [Link]
– You must prevent clients from directly accessing JSP
pages
• Since they would give erroneous results
• Strategies
– You cannot put JSP pages in WEB-INF
• Because URL must correspond directly to file location
– So, use security-constraint entries in [Link]. But:
• Clumsy
• Easy to forget
• Results in confusing error messages
• This is a major drawback to JSF design
20 J2EE training and tutorials: [Link]
Step 7: Example Code
…
<web-app>
…
<security-constraint>
<display-name>
Prevent access to raw JSP pages that are for JSF pages.
</display-name>
<web-resource-collection>
<web-resource-name>Raw-JSF-JSP-Pages</web-resource-name>
<!-- Add url-pattern for EACH raw JSP page -->
<url-pattern>/[Link]</url-pattern>
<url-pattern>/[Link]</url-pattern>
…
</web-resource-collection>
<auth-constraint>
<description>No roles, so no direct access</description>
</auth-constraint>
</security-constraint>
</web-app>
21 J2EE training and tutorials: [Link]
Step 7: Example Results
• In Tomcat, results in confusing error message
• Cannot easily use error-page and error-code to
make a better error page
– Since 500 status code used for many other Tomcat errors
22 J2EE training and tutorials: [Link]
Example 2: Dynamic Navigation
• Original URL will be
[Link]
– Collects info to see if user qualifies for health plan
• When form submitted, one of two possible
results will be displayed
– User is accepted into health plan
– User is rejected from health plan
• Main points
– Specifying an action controller
– Creating an action controller
– Using [Link] to
• Declare controller
• Map results to output pages
23 J2EE training and tutorials: [Link]
Main Points of This Example
• Specify the controller with #{[Link]}
<h:commandButton
value="Sign Me Up!"
action="#{[Link]}"/>
• Controller method returns strings corresponding to conditions
– If null is returned, the form is redisplayed
– Unlike with Struts, the controller need not extend a special class
• Use [Link] to declare the controller as follows
<faces-config>
<managed-bean>
<managed-bean-name>controller name</managed-bean-name>
<managed-bean-class>controller class</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
• Add multiple navigation-rule entries to [Link]
– One for each possible string returned by the controller
– If no string matches, the form is redisplayed
24 J2EE training and tutorials: [Link]
Step 1: Create Form Bean
• Step 1: Create Form Bean
– Postponed until next section
• In this example, we ignore all input data
– Modeled accurately after real health insurance practices
25 J2EE training and tutorials: [Link]
Step 2: Create Input Form
• Same general syntax as in previous example
– Except for action of commandButton
<%@ taglib uri="[Link] prefix="f" %>
<%@ taglib uri="[Link] prefix="h" %>
<f:view>
…
<h:form>
First name: <h:inputText/><BR>
Last name: <h:inputText/><BR>
...
<h:commandButton
value="Sign Me Up!"
action="#{[Link]}"/>
</h:form>…
</f:view>
26 J2EE training and tutorials: [Link]
Step 3: Specify Action
Controller
• Use action attribute of h:commandButton
• Specify #{[Link]}
– The designated method takes no args and returns various
strings. [Link] maps the strings to output pages
– The controller must be declared with a managed-beans
entry in [Link]
• Example
<h:form>
First name: <h:inputText/><BR>
Last name: <h:inputText/><BR>...
<h:commandButton
value="Sign Me Up!"
action="#{[Link]}"/>
</h:form>
27 J2EE training and tutorials: [Link]
Steps 2 & 3: Example Results
• File is tomcat_dir/webapps/jsf-test/[Link]
• URL is [Link]
28 J2EE training and tutorials: [Link]
Step 4: Create an Action Controller
• Does not need to extend any particular
class
– Unlike Struts
• The designated method takes no arguments
and returns a String
– Each string should correspond to navigation rule in
[Link]
– Returning null indicates that the original form should be
redisplayed
• Most controllers access request parameters
via beans
– Covered in next section
– Now, our business logic will be independent of input data
29 J2EE training and tutorials: [Link]
Step 4: Example Code
package coreservlets;
public class HealthPlanController {
public String signup() {
if ([Link]() < 0.2) {
return("accepted");
} else {
return("rejected");
}
}
}
30 J2EE training and tutorials: [Link]
Step 5: Update [Link]
• Declaring action controller
…
<faces-config>
<managed-bean>
<managed-bean-name>
healthPlanController
</managed-bean-name>
<managed-bean-class>
[Link]
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
…
</faces-config>
31 J2EE training and tutorials: [Link]
Step 5: Update [Link]
• Specifying navigation rules
– Outcomes should match return values of controller
…
<faces-config>
…
<navigation-rule>
<from-view-id>/[Link]</from-view-id>
<navigation-case>
<from-outcome>accepted</from-outcome>
<to-view-id>/WEB-INF/results/[Link]</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>rejected</from-outcome>
<to-view-id>/WEB-INF/results/[Link]</to-view-id>
</navigation-case>
</navigation-rule>
…
</faces-config>
32 J2EE training and tutorials: [Link]
Step 6: Create Output JSP
Pages
• …/jsf-test/WEB-INF/results/[Link]
<!DOCTYPE …>
<HTML>
<HEAD>…</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">Accepted!</TH></TR>
</TABLE>
<H2>You are accepted into our health plan.</H2>
Congratulations.
</CENTER>
</BODY></HTML>
33 J2EE training and tutorials: [Link]
Step 6: Create Output JSP
Pages
• …/jsf-test/WEB-INF/results/[Link]
<!DOCTYPE …>
<HTML>
<HEAD>…</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">Rejected!</TH></TR>
</TABLE>
<H2>You are rejected from our health plan.</H2>
Get lost.
</CENTER>
</BODY></HTML>
34 J2EE training and tutorials: [Link]
Step 6: Results
35 J2EE training and tutorials: [Link]
Step 7: Protect Raw JSP Pages
…
<web-app>
…
<security-constraint>
<display-name>
Prevent access to raw JSP pages that are for JSF pages.
</display-name>
<web-resource-collection>
<web-resource-name>Raw-JSF-JSP-Pages</web-resource-name>
<!-- Add url-pattern for EACH raw JSP page -->
<url-pattern>/[Link]</url-pattern>
<url-pattern>/[Link]</url-pattern>
<url-pattern>/[Link]</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>No roles, so no direct access</description>
</auth-constraint>
</security-constraint>
</web-app>
36 J2EE training and tutorials: [Link]
Example 3:
Reading Request Data Manually
• Original URL will be
[Link]
• When form submitted, one of three possible
results will be displayed
– Error message re illegal email address
– Error message re illegal password
– Success
• Main points
– Reading request data "by hand" in action controller
37 J2EE training and tutorials: [Link]
Main Points of This Example
• Most real JSF apps use form beans
– Java classes that are created automatically and
automatically populated based on incoming request
parameters
• See next section
• This example reads by hand
– Requires slightly obscure code
• See next slide
– Done moderately frequently in real apps
• To read request headers or to access scoped variables that
are not related to form bean
38 J2EE training and tutorials: [Link]
Step 1: Create Form Bean
• Postponed until next section
– This example reads form data the old fashioned way:
by directly calling [Link].
– To do so, you first look up the ExternalContext, which
gives you access to the standard servlet and JSP objects
(request, response, ServletContext, session, etc.) Eg:
ExternalContext context =
[Link]().getExternalContext();
HttpServletRequest request =
(HttpServletRequest)[Link]();
String param1 = [Link]("name1");
– The ExternalContext also has methods to access params
and other data out hash tables.
• Request data
– getRequestParameterMap, getRequestCookieMap,
getRequestHeaderMap, etc
• Scoped variables
39 – getRequestMap, getSessionMap, getApplicationMap
J2EE training and tutorials: [Link]
Step 2: Create Input Form
• Same as previous example, except
– h:form is given an id attribute
– h:inputText and h:inputSecret are also given an id
– The actual request param name is formID:elementID
• Only needed if you read request params manually!
• Example code
<%@ taglib uri="[Link] prefix="f" %>
<%@ taglib uri="[Link] prefix="h" %>
<f:view>
…
<h:form id="form2">
Email address: <h:inputText id="email"/><BR>
Password: <h:inputSecret id="password"/><BR>
<h:commandButton value="Sign Me Up!"
action="#{[Link]}"/>
</h:form>…
</f:view>
40 J2EE training and tutorials: [Link]
Step 3: Specify Action
Controller
• Use the action attribute of
h:commandButton
• Specify #{[Link]}
– Same as last example
• The designated method takes no args and returns various
strings. [Link] maps the strings to output pages
• The controller must be declared with a managed-beans
entry in [Link]
• Example
<h:form id="form2">
Email address: <h:inputText id="email"/><BR>
Password: <h:inputSecret id="password"/><BR>
<h:commandButton value="Sign Me Up!"
action="#{[Link]}"/>
</h:form>
41 J2EE training and tutorials: [Link]
Steps 2 & 3: Example Results
• File is tomcat_dir/webapps/jsf-test/[Link]
• URL is [Link]
42 J2EE training and tutorials: [Link]
Step 4: Create an Action Controller
• Does not need to extend any particular
class
– Unlike Struts
• The designated method takes no arguments
and returns a String
– Each string should correspond to navigation rule in
[Link]
– Returning null indicates that the original form should be
redisplayed
• Most controllers access request parameters
via beans
– We have not covered this yet
– We will use the manual approach via the ExternalContext
– ExternalContext useful in real life anyhow
• Cookies, session data, request headers, etc.
43 J2EE training and tutorials: [Link]
Step 4: Example Code
package coreservlets;
import [Link].*;
import [Link].*;
import [Link].*;
public class RegistrationController {
public String register() {
ExternalContext context =
[Link]().getExternalContext();
HttpServletRequest request =
(HttpServletRequest)[Link]();
String email = [Link]("form2:email");
String password = [Link]("form2:password");
if ((email == null) ||
([Link]().length() < 3) ||
([Link]("@") == -1)) {
return("bad-address");
} else if ((password == null) ||
([Link]().length() < 6)) {
return("bad-password");
} else {
return("success");
44 }}} J2EE training and tutorials: [Link]
Step 5: Update [Link]
• Declaring action controller
…
<faces-config>
<managed-bean>
<managed-bean-name>
registrationController
</managed-bean-name>
<managed-bean-class>
[Link]
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
…
</faces-config>
45 J2EE training and tutorials: [Link]
Step 5: Update [Link]
• Specifying navigation rules
– Outcomes should match return values of action
…
<faces-config>
…
<navigation-rule>
<from-view-id>/[Link]</from-view-id>
<navigation-case>
<from-outcome>bad-address</from-outcome>
<to-view-id>/WEB-INF/results/[Link]</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>bad-password</from-outcome>
<to-view-id>/WEB-INF/results/[Link]</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/WEB-INF/results/[Link]</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
46 J2EE training and tutorials: [Link]
Step 6: Create Output JSP
Pages
• …/jsf-test/WEB-INF/results/[Link]
<!DOCTYPE …>
<HTML>
<HEAD>…</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">Illegal Email Address</TH></TR>
</TABLE>
<P>
Address must be of the form username@host.
Please <A HREF="[Link]">try again</A>.
</CENTER>
</BODY></HTML>
47 J2EE training and tutorials: [Link]
Step 6: Example Result for Bad
Email Address
• Input
48 J2EE training and tutorials: [Link]
Step 6: Example Result for Bad
Email Address
• Output
49 J2EE training and tutorials: [Link]
Step 6: Create Output JSP
Pages
• …/jsf-test/WEB-INF/results/bad-
[Link]
<!DOCTYPE …>
<HTML>
<HEAD>…</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">Illegal Password</TH></TR>
</TABLE>
<P>
Password must contain at least six characters.
Please <A HREF="[Link]">try again</A>.
</CENTER>
</BODY></HTML>
50 J2EE training and tutorials: [Link]
Step 6: Example Result for Bad
Password
• Input
51 J2EE training and tutorials: [Link]
Step 6: Example Result for Bad
Password
• Output
52 J2EE training and tutorials: [Link]
Step 6: Create Output JSP
Pages
• …/jsf-test/WEB-INF/results/[Link]
<!DOCTYPE …>
<HTML>
<HEAD>…</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">Success</TH></TR>
</TABLE>
<H2>You have registered successfully.<BR>
(Version 2)</H2>
</CENTER>
</BODY></HTML>
53 J2EE training and tutorials: [Link]
Step 6: Example Result for
Good Input
• Input
54 J2EE training and tutorials: [Link]
Step 6: Example Result for
Good Input
• Output
55 J2EE training and tutorials: [Link]
Step 7: Protect Raw JSP Pages
…
<web-app>
…
<security-constraint>
<display-name>
Prevent access to raw JSP pages that are for JSF pages.
</display-name>
<web-resource-collection>
<web-resource-name>Raw-JSF-JSP-Pages</web-resource-name>
<!-- Add url-pattern for EACH raw JSP page -->
<url-pattern>/[Link]</url-pattern>
<url-pattern>/[Link]</url-pattern>
<url-pattern>/[Link]</url-pattern>
<url-pattern>/[Link]</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>No roles, so no direct access</description>
</auth-constraint>
</security-constraint>
</web-app>
56 J2EE training and tutorials: [Link]
Value-Change Listeners
• All our examples used action attribute of
h:commandButton
– Specifies code to run when form is submitted
• How to respond to finer-grained events?
– Textfield value has changed
• E.g., fill in state automatically when ZIP code is entered
– New list entry has been selected
• Necessary ingredients
– Specify code that should run
• <h:inputText valueChangeListener="#{[Link]}"…/>
• Note that code runs before action controller
– Force form to be submitted when events occur
• <h:inputText valueChangeListener="#{[Link]}"
onclick="submit()" …/>
57 J2EE training and tutorials: [Link]
Summary
• Basic steps to using JSF
– Create a bean to represent the form data
– Use f:view and h:form to create an input form
– Specify action controller with action of h:commandButton
– Create an action controller
– Use [Link] to declare form bean and navigation rules
– Create JSP pages corresponding to each return condition
– Protect raw JSP pages from access
• Static navigation
– Specify outcome as action of button
• Outcome mapped by [Link] to output page
• Dynamic navigation
– Specify method as action of button
– Method returns outcomes
• Outcomes mapped by [Link] to output pages
58 J2EE training and tutorials: [Link]
© 2005 Marty Hall
Questions?
Core Servlets & JSP book: [Link]
More Servlets & JSP book: [Link]
Servlet/JSP/Struts/JSF Training: [Link]
[Link] -- Hands-on, customized training for Java, servlets, JSP, Struts, and JSF.