Вы находитесь на странице: 1из 27

© 2009 Marty Hall

JSF 2.0:
2 0:
A Whirlwind Tour
Originals of Slides and Source Code for Examples:
http://www.coreservlets.com/JSF-Tutorial/jsf2/

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

© 2009 Marty Hall

For live training on JSF 1.x or 2.0, please see


courses att http://courses.coreservlets.com/.
htt // l t /
Taught by the author of Core Servlets and JSP, More
Servlets and JSP,
JSP and this tutorial
tutorial. Available at public
venues, or customized versions can be held on-site
at your organization.
• Courses developed and taught by Marty Hall
– Java 5, Java 6, intermediate/beginning servlets/JSP, advanced servlets/JSP, Struts, JSF, Ajax, GWT, custom courses.
Customized
• Courses developed Java
and taught by EE Training: http://courses.coreservlets.com/
coreservlets.com experts (edited by Marty)
Servlets, –JSP, JSFHibernate/JPA,
Spring, 1.x & JSF 2.0,
EJB3,Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Ruby/Rails

Developed and taught by well-known Contactauthor and developer. At public


hall@coreservlets.com venues or onsite at your location.
for details
Topics in This Section
• Setup
• New facelets page format
• New annotations for managed beans
• New default mappings of return values to
results pages
• Old-style
Old t l explicit
li it mappings
i off return
t values
l
to results pages
• New,
New more concise way to output bean
values
• New support for Ajax and incremental page
updates
5

© 2009 Marty Hall

Introduction

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.
Overview
• This section gives a quick intro to the
b i off JSF 2.0
basics 20
– Facelets as the default
– Page navigation with and without defaults
– Beans with annotations instead of faces-config settings
– j support
Ajax pp
• Later sections give more info
– Details on the above topics
– Validation
– Event handling
– P
Page ttemplating
l ti
– Custom components
7

Setup
• Summary
– Install Java 6 and Glassfish 3
– Install Eclipse 3.5 and Glassfish adapter
– Create web.xml
web xml with *.jsf
* jsf url
url-pattern
pattern (or similar)
• Optional, but recommended: Development mode
PROJECT_STAGE setting
– Create faces-config.xml
f fi l with
i h legal
l l start/end
/ d tags but
b
empty body
• Details
– Detailed setup directions in previous tutorial section
p jjsf-basics.zip
– Download/import p for testing
g
• http://www.coreservlets.com/JSF-Tutorial/jsf2/

8
© 2009 Marty Hall

Simplest (Warmup) Case:


Static Navigation

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Overview
• Idea
– Click
Cli k on button
b in
i initial
i i i l page
– You always get the same results page
– No dynamic
y content
• What you need
– Basic web.xml settings
• url-pattern
url pattern and optionally PROJECT
PROJECT_STAGE
STAGE setting
– faces-config.xml
• Start and end tags but no “real” content
– A starting
i page
• file: test.xhtml; URL: test.jsf.
• Contains <h:commandButton action="successful-test"/>
– A results page
• successful-test.xhtml, where main part of filename
10
matches action above
web.xml
<?xml version="1.0" encoding="UTF-8"?>
pp … version="2.5">
<web-app Must be version 2.5 or later. Glassfish supports
pp servlets
version 3.0. This is an updated requirement from JSF 1.x.
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
/ Leave unchanged. This is the
same as in JSF 1.x.
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
u patte .js /u patte
<url-pattern>*.jsf</url-pattern> U JSF for
Use f URLs
URL that
th t endd in
i blah.jsf.
bl h j f Other
Oth
</servlet-mapping> popular options are .faces and /faces/*.
This is the same as in JSF 1.x.
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
/
</context-param>
<welcome-file-list> Give more and more detailed error
messages. For example, unknown
<welcome-file>index.jsp</welcome-file>
<welcome file>index.jsp</welcome file> outcomes are flagged this way (vs. (vs
<welcome-file>index.html</welcome-file> silently redisplaying input form when
in deployment mode). Optional.
</welcome-file-list> This is new in JSF 2.0.

11
</web-app>

faces-config.xml
<?xml version="1.0"?>
<faces-config
<faces config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns http://java.sun.com/xml/ns/javaee
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_2_0.xsd"
_ _
version="2.0">

</faces-config> File is mostly empty in this example. This simple example


uses default results pages (derived from the outcome listed
for the command button’s action) and no beans at all.

But you are still required to have a faces-config.xml file with


legal start and end tags: the file cannot be missing.

12
Typical JSF Page (blah.xhtml)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/TR/xhtml1/DTD/xhtml1 transitional.dtd >
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
Same header as with facelets in
<h:head> JSF 1.x. But in JSF 2.0, facelets,
It is not necessary to use h:body and h:head in the first few
not JSP, is the standard way of
… examples (regular <body> and <head> are fine). However,
when you use h:outputScript and especially f:ajax, you need making JSF pages. Note that file is
</h:head> those tags. And, it is just as simple to use them as not. So, blah.xhtml, but URL is blah.jsf
you might as well plan ahead and use them routinely. (assuming url-pattern of *.jsf in
<h:body> web.xml).

<h:form>
… Input elements and buttons go here. Most are of
the form <h:somethingg …/>
</h:form>

</h:body></html>

13

test.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" The action is usually #{someBean.someMethod},
where someMethod returns a String that is the
xmlns:h="http://java.sun.com/jsf/html"> outcome. But you can also put a literal outcome here.
Either way, the outcome corresponds to the results
… filename unless you make a navigation rule in faces-
<h:form>
: o config.xml.
g So, when yyou ppress the button,
successful-test.xhtml (from same folder as test.xhtml)
<fieldset> is displayed.
<legend>Valid action</legend>
Click button. You should get success page.<br/>
<h:commandButton value=
value="Click
Click (Good)"
(Good) action=
action="successful-test"
successful test />
</fieldset>
<p/>
<fieldset>
<legend>Invalid action</legend>
Click button. You should get error message about not being
able to find matching navigation case.<br/>
<h:commandButton value="Click (Bad)" action="bogus-outcome" />
</fieldset>
/
</h:form>

14 </h:body></html>
successful-test.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
p // g/ / / /
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head><title>JSF 2.0: Success</title> This simple case has no dynamic content, so
<link href="./css/styles.css"
href=" /css/styles css" technically it could just be a static page without any
JSF-specific tags or attributes. But in real applications
rel="stylesheet" type="text/css"/> you almost always use dynamic content, so you might
as well use the normal JSF template shown earlier.
</h:head>
<h:body>
<div align="center">
<table border="5">
<tr><th class="title">JSF 2.0: Success</th></tr>
</table>
<p/>

<h2>If you got this page after clicking on button in test.jsf,


then your JSF 2.0 app is configured and deployed correctly.</h2>
/

</div></h:body></html>
15

Results

Note that URL is test.jsf in all three cases. For initial page, you use URL test.jsf
because filename is test.xhtml and url-pattern in web.xml is *.jsf. For results
pages, JSF by default uses forwarding, not redirecting, so URL does not change
when you submit the form. The error message on failure page is because we used
Development as the PROJECT_STAGE in web.xml. Otherwise initial page would
16 have been redisplayed with no messages.
© 2009 Marty Hall

Dynamic Navigation with


Default Results Pages

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Overview
• Idea
– Click on button in initial page
– Get one of two results pages, chosen at random
• What you need
– web.xml and faces-config.xml as before
– A starting page
• <h:commandButton…action="#{healthPlanBean.signup}"/>
– A bean
• Name: HealthPlanBean (name above except for case)
• @ManagedBean annotation
• Contains “signup” method that returns two possible Strings
– Two results pages
• Names matching the method return values
18
web.xml
<?xml version="1.0" encoding="UTF-8"?>
Unchanged from previous example. The web.xml file is
pp … version="2.5">
<web-app the same in all examples in this section
section, so it won’t
won t be
<servlet> shown again after this.

<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
/
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
u patte .js /u patte
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
/
</context-param>
<welcome-file-list>
<welcome file>index.jsp</welcome file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
19
</web-app>

faces-config.xml
<?xml version="1.0"?>
<faces-config
<faces config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns http://java.sun.com/xml/ns/javaee
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_2_0.xsd"
_ _
version="2.0">

</faces-config> File is mostly empty in this example. This example uses


default bean names (derived from the bean’s class name
with the first letter changed to lower case) and default
results pages (derived from the action controller’s return
values).

20
health-plan-signup-1.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">

<h:body>
:body

<h:form>
<fieldset>
<legend>Health Insurance Plan Signup</legend>
First name: <h:inputText/><br/> The input elements are ignored in this simplistic
example. Later section will give ‘value’ attributes
Last name: <h:inputText/><br/> corresponding to bean properties.
SSN: <h:inputText/><br/>
Complete medical history since the day you were born:<br/>
<h:inputTextarea/><br/>
<h:commandButton value="Sign Me Up!"
action="#{healthPlanBean.signup}"/>
</fieldset>
/
</h:form> This means that when you press button, JSF instantiates bean whose name is
… healthPlanBean and then runs the signup method. This is same format as in JSF
21 </h:body></html> 1.x, but name of bean is automatically derived from Java class name.

HealthPlanBean.java
package coreservlets;

import javax.faces.bean.*; Declares this as managed bean, without requiring entry in


faces-config.xml.

@ManagedBean Since no name given, name is class name with first letter
changed to lower case (i.e., healthPlanBean). You can also
public class HealthPlanBean { do @ManagedBean(name="someName").
public String signup() {
Since no scope given, it is request scope. You can also use
if (Math.random() < 0.2) { an annotation like @SessionScoped.
return("accepted");
} else {
return("rejected");
}
}
}
Since there are no explicit navigation rules in faces-config,
faces-config
these return values correspond to accepted.xhtml and
rejected.xhtml (in same folder as page that has the form).

22
accepted.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
p // g/ / / /
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"> I don’t actually have any dynamic
code in this simplistic example, but
<h:head> it is a good idea to plan ahead and
… always
l iinclude
l d these.
th
</h:head>
<h:body>

<table border="5">
<tr><th class="title">Accepted (Version 1)</th></tr>
</table>
<p/>

<h2>You are accepted into our health plan.</h2>


<p>Congratulations.</p>

</h:body></html>

23

rejected.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
p // g/ / / /
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
Again, this part plus h:head and
xmlns:h="http://java.sun.com/jsf/html"> h:body are not strictly necessary in
<h:head> this simple example, but it is
recommended practice to include
… them routinely.
</h:head>
<h:body>

<table border="5">
<tr><th class="title">Rejected (Version 1)</th></tr>
</table>
<p/>

<h2>You are rejected from our health plan.</h2>


<p>Get lost.</p>

</h:body></html>

24
index.jsp

<% response
response.sendRedirect(
sendRedirect("health-plan-signup-1
health plan signup 1.jsf
jsf");
); %>

25

Results

26
© 2009 Marty Hall

Dynamic Navigation with


Explicit Mappings of
Results Pages

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Overview
• Idea (same as last example)
– Click on button in initial page
– Get one of two results pages, chosen at random
• What you need
– New in this example
• navigation-rule
navigation rule in faces-config.xml
faces config.xml that maps outcomes
(return values of bean method) to results pages
– Same as last example
• web.xml,
web xml starting page
page, bean
bean, results pages

28
faces-config.xml
<?xml version="1.0"?> Start page

<faces-config
<faces config … version
version="2.0">
2.0 >
<navigation-rule>
<from-view-id>/health-plan-signup2.xhtml</from-view-id>
<navigation-case>
<from-outcome>accepted</from-outcome>
<to-view-id>/page-for-accepted.jsp</to-view-id>
</navigation-case> Return values of Java method that is run
when form on start page is submitted.
<navigation-case>
Results pages corresponding to outcomes.
<from-outcome>rejected</from-outcome>
<to-view-id>/page-for-rejected.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
These navigation rules are exactly the same as in JSF 1.x. Default
i
mappings are simpler,
i l bbutt explicit
li it mappings
i llett you use wildcards,
ild d llett
you look at a single file to see or modify all of the navigation rules in
your project, and with Eclipse tools, let you get a graph of the navigation
rules for your project. So, even in JSF 2, explicit navigation rules are
sometimes used.
29

health-plan-signup-2.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">

<h:body>
:body

<h:form>
<fieldset>
<legend>Health Insurance Plan Signup</legend>
First name: <h:inputText/><br/>
Last name: <h:inputText/><br/>
SSN: <h:inputText/><br/>
Complete medical history since the day you were born:<br/>
<h:inputTextarea/><br/>
<h:commandButton value="Sign Me Up!"
action="#{healthPlanBean.signup}"/>
</fieldset>
/
</h:form>

Except for page title and heading, this is identical to health-plan-signup-1.xhtml from previous example.
30 </h:body></html>
HealthPlanBean.java
package coreservlets;

import javax.faces.bean.*; Same bean as in previous example. The difference is that


the return values will be explicitly mapped to results pages
in faces-config.xml, rather than being treated as the base
@ManagedBean names of the results pages.
public class HealthPlanBean {
public String signup() {
if (Math.random() < 0.2) {
return("accepted");
} else {
return("rejected");
}
}
}

31

page-for-accepted.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
p // g/ / / /
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>

</h:head>
<h:body>

<table border="5">
<tr><th class="title">Accepted (Version 1)</th></tr>
</table>
<p/>

<h2>You are accepted into our health plan.</h2>


<p>Congratulations.</p>

</h:body></html>
Except for page title and heading, this is identical to accepted.xhtml from previous example.
32
page-for-rejected.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
p // g/ / / /
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>

</h:head>
<h:body>

<table border="5">
<tr><th class="title">Rejected (Version 1)</th></tr>
</table>
<p/>

<h2>You are rejected from our health plan.</h2>


<p>Get lost.</p>

</h:body></html>
Except for page title and heading, this is identical to rejected.xhtml from previous example.
33

Results

34
© 2009 Marty Hall

Using Beans to Handle


Request Parameters

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Overview
• Idea
– Enter
E a bank
b k customer id andd a passwordd
– Get either
• Page showing first name, last name, and balance
– Various versions depending on balance
• Error message about missing or invalid data
• What y
you need
– New in this example
• Bean: properties corresponding to request parameters
• Input form: ‘value’
value attribute for h:inputText
• Results pages: #{myBean.myProperty}
– Same as first example
• web.xml
web xml with basic settings
– url-pattern and PROJECT_STAGE
• faces-config.xml with start and end tags and empty body
36
faces-config.xml
<?xml version="1.0"?>
<faces-config
<faces config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns http://java.sun.com/xml/ns/javaee
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_2_0.xsd"
_ _
version="2.0">

</faces-config> The downloadable project has the elements from the last
example (explicit mappings) here. But no entries are
needed for this example.

37

bank-lookup.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">

This value plays a dual role. When form is first displayed, bankingBean is instantiated and
<h:body>
:body getCustomerId is called
called. If the value is non
non-empty,
empty that result is the initial value of the textfield
textfield.
… Otherwise, the textfield is initially empty. When the form is submitted, bankingBean is reinstantiated
(assuming request scope) and the value in the textfield is passed to setCustomerId.
<h:form>
<fieldset>
<legend>Bank Customer Lookup (Results in Separate Page)</legend>
Customer ID:
<h:inputText value="#{bankingBean.customerId}"/><br/>
Password:
<h:inputSecret value="#{bankingBean.password}"/><br/>
value="#{bankingBean password}"/><br/>
<h:commandButton value="Show Current Balance"
action="#{bankingBean.showBalancePage}"/>
</fieldset>
</h:form>
/

</h:body></html>
38
BankingBean.java

@ManagedBean
public class BankingBean {
private String customerId, password, message="";
private BankCustomer customer;

public String getCustomerId() { return(customerId); }

public void setCustomerId(String customerId) {


These will be
this.customerId = customerId; automatically called by
} JSF when form is
submitted.

public String getPassword() { … }


public void setPassword(String password) { … }

public BankCustomer getCustomer() { The customer is initially null. The action


controller method (next page) fills in
return(customer); the customer based on the customerId
} supplied.
39

BankingBean.java (Continued)
public String showBalancePage() {
if (!password.equals("secret"))
(!password.equals( secret )) {
Filled in by JSF before
return("wrong-password"); this action controller
method is called.
}
customer =
BankCustomerLookupService.getCustomer(customerId);
if (customer == null) {
return("unknown-customer");
} else if (customer.getBalance() < 0) {
return("negative-balance");
} else if (customer.getBalance() < 10000) {
return( normal-balance );
return("normal-balance");
The customer is not filled in automatically by
} else { JSF, since it is not directly part of the submitted
return("high-balance"); data, but rather indirectly derived (by the
business logic) from the submitted data. So, it is
} filled in by the action controller method. Just as
in JSF 1.x, beans are typically composed of
} three parts: properties corresponding to the
There are five possible results pages: wrong-password.xhtml, unknown-customer.xhtml, negative-balance.xhtml,
input, action controller methods, and
normal-balance.xhtml, and high-balance.xhtml. We are using the default mapping of return values to file names in placeholders for the results data.
40 all cases (rather than explicit navigation rules in faces-config.xml).
normal-balance.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
p // g/ / / /
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
Note that in JSF you can use #{result} instead of
… <h:outputText
h T value="#{result}"/>.
l "#{ l }"/ B
Bothh approaches
h
</h:head> escape HTML characters, so use the shorter approach
shown here unless you need one of the options to
<h:body> h:outputText like escape (with a value of false), rendered
… (with a computed value), id, converter, etc.

<ul>
<li>First name: #{bankingBean.customer.firstName}</li>
<li>Last name: #{bankingBean.customer.lastName}</li>
<li>ID: #{bankingBean.customer.id}</li>
#{bankingBean customer id}</li>
<li>Balance: $#{bankingBean.customer.balanceNoSign}</li>
</ul>

</h:body></html>
/ /

negative-balance.xhtml and high-balance.xhtml are similar.


41

unknown-customer.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
p // g/ / / /
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
Even though customerId came from the user and could contain
… HTML characters,
h iti is
i safe
f to use #{bankingBean.customerId}
#{b ki B Id}
</h:head> instead of <h:outputText value="#{bankingBean.customerId}"/>.
The same HTML escaping is done for #{result} as for
<h:body> <h:outputText value="#{result}"/>

<h2>No customer found with id "#{bankingBean.customerId}"</h2>
<p>Please <a href="bank-lookup.jsf">try again</a>.</p>

</h:body></html>

unknown-password.xhtml is similar.
42
Results
(Legal ID and Password)

negative
balance

high
balance
normal
balance

43

Results
(Bad Inputs)

44
© 2009 Marty Hall

Using Ajax to Display


Incremental Results in
Current Page

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Overview
• Idea
– E
Enter
t a bank
b k customer
t id andd a passwordd
– In the same page, get either
• First name, last name, and balance
• Error message about missing or invalid data
• What you need
– New in this example
• Changed
Ch d h:commandButton
h dB tt to t have
h separate
t start/end
t t/ d tags
t
• Form: added f:ajax tag inside h:commandButton
• Form: added h:outputText (with id) to use for messages
• Bean: new action controller that sets the message
– Same as previous example
• Bean: same properties for request data
• Form: Same h:inputText
• web.xml with basic settings
– url-pattern and PROJECT_STAGE
46 • faces-config.xml with start and end tags and empty body
faces-config.xml
<?xml version="1.0"?>
<faces-config
<faces config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns http://java.sun.com/xml/ns/javaee
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_2_0.xsd"
_ _
version="2.0">

</faces-config> The downloadable project has the elements from the


second health-plan example (explicit mappings) here. But
no entries are needed for this example.

47

f:ajax: General HTML Format


<!DOCTYPE …> You use f:ajax, so you need to define namespace for f:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head> … </h:head> When you use Ajax, a script is inserted into the
The form elements to submit and process on the
<h:body>
:body … head automatically.y So, yyou must use h:head,
server The default is @this (current element)
server. element), so if you
not just head.
<h:form id="formid"> want a button that just calls a server function with no
form data, you can omit the “execute” attribute. You can
… When you use Ajax, the output region and any also list individual elements (formid:elementid)
individually listed form elements must have ids. separated by whitespace.
<h:inputText …/> The final id is formid:element id. (Or, you can
… tell JSF not to pprepend
p the form id.))

<h:commandButton … action="#{someBean.someMethod}">
<f:ajax execute="@form"
The element or elements (separate by whitespace) to
render="formid:resultid"/> incrementally update.
</h:commandButton>
<br/>
<h2><h:outputText value="#{someBean.someProperty}"
id="resultid"/></h2></fieldset>

Presumably getSomeProperty has a different value after
</h:form> someMethod has been run. And remember that you really run
</h:body></html> getSomeProperty on the server and send the result to the page to be
inserted: the browser doesn’t actually execute getSomeProperty,
48 even though people sometimes think of it in this way.
Understanding f:ajax
• HTML
<h:form
hf id="formid">
id "f id"

<h:commandButton … action="#{bean.someMethod}">
<f:ajax execute="@form" render="formid:resultid"/>
</h:commandButton>
<h:outputText
p id="resultid" value="#{bean.someProp}"/>
{ p}
</h:form>
• Interpretation
– Wh
When bbutton
tt is
i pressed,
d sendd h:inputBlah
hi tBl h elements
l t to
t
server and execute them normally. Then run
someMethod. Then, send the result of getSomeProp to the
browser and have JavaScript insert it where the
h:outputText is.
49

bank-lookup-ajax.xhtml
<!DOCTYPE …>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head> … </h:head>
<h:body>
:body …
<h:form id="bankForm">
… <h:inputText value="#{bankingBean.customerId}"/><br/> …
… <h:inputSecret value="#{bankingBean.password}"/><br/>
<h:commandButton value=
value="Show
Show Current Balance
Balance"
action="#{bankingBean.showBalanceMessage}">
<f:ajax execute="@form"
render="bankForm:ajaxMessage"/>
</h:commandButton>
<br/>
<h2><h:outputText value="#{bankingBean.message}"
id="ajaxMessage"/></h2></fieldset> …
</h:form>
/
When the button is pressed, first run setCustomerId and setPassword.
</h:body></html> Then run showBalanceMessage. Then compute the value of
getMessage, send it to the page, where JavaScript inserts it in the
location of the h:outputText element. Note that getMessage returns an
50 empty string initially (the first time form is displayed to user).
BankingBean.java (Continued:
Other Parts Shown Earlier)
public String showBalanceMessage() {
Sets message that
if (!password.equals("secret"))
(!password.equals( secret )) { h t tT t di
h:outputText displays.
l
message = "Incorrect password";
} else {
customer =
BankCustomerLookupService.getCustomer(customerId);
if (customer == null) {
message = "Unknown customer";
} else {
message =
String.format("Balance for %s %s is $%,2f",
customer getFirstName()
customer.getFirstName(),
customer.getLastName(),
customer.getBalance());
} Normally the return value of an action
Normally,
} controller method determines the page
navigation. But there is no navigation with
return(null); f:ajax: the original page is still displayed. So,
the return value is irrelevant.
51 }

Results

52
© 2009 Marty Hall

Wrap-Up

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Summary
• Facelets for all pages
– Use xhtml
U h l withi h xmlns:h="http://java.sun.com/jsf/html"
l h "h //j /j f/h l"
– Almost always use h:head, h:body, and h:form
– p
Add namespace for f: if you
y use f:ajax
j or other f: tags
g
– For results pages, usually use #{blah} instead of
<h:outputText value="#{blah}"/>
• Default page navigation
– Return value of controller method is the name of the
results page (minus the extension)
• Default
D f lt bean
b name
– Add @ManagedBean before class
– If class name is MyBean,
MyBean use #{myBean
#{myBean.blah}
blah}
• Ajax support
54
– Add f:ajax with id of h:outputText to re-render
© 2009 Marty Hall

Questions?

Customized Java EE Training: http://courses.coreservlets.com/


Servlets, JSP, JSF 1.x & JSF 2.0, Struts Classic & Struts 2, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6.
Developed and taught by well-known author and developer. At public venues or onsite at your location.

Вам также может понравиться