27
© 2009 Marty Hall JSF 2 0: JSF 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 t htt // lt / courses at http://courses.coreservlets.com/. Taught by the author of Core Servlets and JSP, More Servlets and JSP and this tutorial Available at public Servlets and JSP, and this tutorial. Available at public venues, or customized versions can be held on-site at your organization. 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. Courses developed and taught by Marty Hall Java 5, Java 6, intermediate/beginning servlets/JSP, advanced servlets/JSP, Struts, JSF, Ajax, GWT, custom courses. Courses developed and taught by coreservlets.com experts (edited by Marty) Spring, Hibernate/JPA, EJB3, Ruby/Rails Contact hall@coreservlets.com for details

JSF2 Whirlwind Tour

Embed Size (px)

Citation preview

Page 1: JSF2 Whirlwind Tour

© 2009 Marty Hall

JSF 2 0:JSF 2.0: A Whirlwind TourOriginals 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 t htt // l t /courses at http://courses.coreservlets.com/.

Taught by the author of Core Servlets and JSP, More Servlets and JSP and this tutorial Available at public Servlets and JSP, and this tutorial. Available at public venues, or customized versions can be held on-site

at your organization.

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.

• Courses developed and taught by Marty Hall– Java 5, Java 6, intermediate/beginning servlets/JSP, advanced servlets/JSP, Struts, JSF, Ajax, GWT, custom courses.

• Courses developed and taught by coreservlets.com experts (edited by Marty)– Spring, Hibernate/JPA, EJB3, Ruby/Rails

Contact [email protected] for details

Page 2: JSF2 Whirlwind Tour

Topics in This Section

• Setup• New facelets page format• New annotations for managed beans• New default mappings of return values to

results pagesOld t l li it i f t l• Old-style explicit mappings of return values to results pages

• New more concise way to output bean• New, more concise way to output bean values

• New support for Ajax and incremental pageNew 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.

Page 3: JSF2 Whirlwind Tour

Overview

• This section gives a quick intro to the b i f JSF 2 0basics of JSF 2.0– Facelets as the default

Page navigation with and without defaults– Page navigation with and without defaults– Beans with annotations instead of faces-config settings– Ajax supportj pp

• Later sections give more info– Details on the above topics– Validation– Event handling

P t l ti– Page templating– Custom components

7

Setup

• Summary– Install Java 6 and Glassfish 3– Install Eclipse 3.5 and Glassfish adapter

Create web xml with * jsf url pattern (or similar)– Create web.xml with *.jsf url-pattern (or similar)• Optional, but recommended: Development mode

PROJECT_STAGE setting

f fi l i h l l / d b– Create faces-config.xml with legal start/end tags but empty body

• DetailsDetails– Detailed setup directions in previous tutorial section– Download/import jsf-basics.zip for testingp j p g

• http://www.coreservlets.com/JSF-Tutorial/jsf2/

8

Page 4: JSF2 Whirlwind Tour

© 2009 Marty Hall

Simplest (Warmup) Case: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

• IdeaCli k b i i i i l– Click on button in initial page

– You always get the same results page– No dynamic contenty

• What you need– Basic web.xml settings

url pattern and optionally PROJECT STAGE setting• url-pattern and optionally PROJECT_STAGE setting– faces-config.xml

• Start and end tags but no “real” contentA i– A starting page

• file: test.xhtml; URL: test.jsf.• Contains <h:commandButton action="successful-test"/>

– A results page• successful-test.xhtml, where main part of filename

matches action above10

Page 5: JSF2 Whirlwind Tour

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app … version="2.5"> Must be version 2.5 or later. Glassfish supports servlets pp<servlet>

<servlet-name>Faces Servlet</servlet-name><servlet-class>javax.faces.webapp.FacesServlet</servlet-class>/

ppversion 3.0. This is an updated requirement from JSF 1.x.

</servlet><servlet-mapping>

<servlet-name>Faces Servlet</servlet-name><url-pattern>*.jsf</url-pattern>

Leave unchanged. This is the same as in JSF 1.x.

U JSF f URL th t d i bl h j f Oth u patte .js /u patte

</servlet-mapping><context-param>

<param-name>javax.faces.PROJECT_STAGE</param-name>/

Use JSF for URLs that end in blah.jsf. Other popular options are .faces and /faces/*. This is the same as in JSF 1.x.

<param-value>Development</param-value></context-param><welcome-file-list>

<welcome-file>index.jsp</welcome-file>

Give more and more detailed error messages. For example, unknown outcomes are flagged this way (vs <welcome file>index.jsp</welcome file>

<welcome-file>index.html</welcome-file></welcome-file-list>

</web-app>11

outcomes are flagged this way (vs. silently redisplaying input form when in deployment mode). Optional.This is new in JSF 2.0.

faces-config.xml

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

Page 6: JSF2 Whirlwind Tour

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">

<h:head>Same header as with facelets in JSF 1.x. But in JSF 2.0, facelets,

It is not necessary to use h:body and h:head in the first few

…</h:head><h:body>

not JSP, is the standard way of making JSF pages. Note that file is blah.xhtml, but URL is blah.jsf(assuming url-pattern of *.jsf in web.xml).

It is not necessary to use h:body and h:head in the first few examples (regular <body> and <head> are fine). However, when you use h:outputScript and especially f:ajax, you need those tags. And, it is just as simple to use them as not. So, you might as well plan ahead and use them routinely.

…<h:form>…</h:form>

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

…</h:body></html>

g

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"xmlns:h="http://java.sun.com/jsf/html">

…<h:form>

The action is usually #{someBean.someMethod}, where someMethod returns a String that is the 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-config.xml. So, when you press the button, : o

<fieldset><legend>Valid action</legend>Click button. You should get success page.<br/><h:commandButton value="Click (Good)" action="successful-test" />

g y psuccessful-test.xhtml (from same folder as test.xhtml) is displayed.

<h:commandButton value= Click (Good) action= successful test /></fieldset><p/><fieldset><legend>Invalid action</legend><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>…</h:body></html>14

Page 7: JSF2 Whirlwind Tour

successful-test.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">p // g/ / / /

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://java.sun.com/jsf/html">

<h:head><title>JSF 2.0: Success</title><link href=" /css/styles css"

This simple case has no dynamic content, so technically it could just be a static page without any <link href="./css/styles.css"

rel="stylesheet" type="text/css"/></h:head><h:body>

technically it could just be a static page without any JSF-specific tags or attributes. But in real applications you almost always use dynamic content, so you might as well use the normal JSF template shown earlier.

<div align="center"><table border="5">

<tr><th class="title">JSF 2.0: Success</th></tr></table></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

16

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 have been redisplayed with no messages.

Page 8: JSF2 Whirlwind Tour

© 2009 Marty Hall

Dynamic Navigation withDynamic 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• What you need– web.xml and faces-config.xml as before– A starting pageA 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

Page 9: JSF2 Whirlwind Tour

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app … version="2.5">

Unchanged from previous example. The web.xml file is the same in all examples in this section so it won’t be pp

<servlet><servlet-name>Faces Servlet</servlet-name><servlet-class>javax.faces.webapp.FacesServlet</servlet-class>/

the same in all examples in this section, so it won t be shown again after this.

</servlet><servlet-mapping>

<servlet-name>Faces Servlet</servlet-name><url-pattern>*.jsf</url-pattern>u patte .js /u patte

</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></web-app>

19

faces-config.xml

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

Page 10: JSF2 Whirlwind Tour

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><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/>

The input elements are ignored in this simplistic example. Later section will give ‘value’ attributes corresponding to bean properties.

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>…</h:body></html>21

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 1.x, but name of bean is automatically derived from Java class name.

HealthPlanBean.java

package coreservlets;

import javax.faces.bean.*;

@ManagedBean

Declares this as managed bean, without requiring entry in faces-config.xml.

Since no name given, name is class name with first letter

public class HealthPlanBean {public String signup() {

if (Math.random() < 0.2) {

changed to lower case (i.e., healthPlanBean). You can also do @ManagedBean(name="someName").

Since no scope given, it is request scope. You can also use an annotation like @SessionScoped.

return("accepted");} else {

return("rejected");}}

}}

Since there are no explicit navigation rules in faces-config

22

Since there are no explicit navigation rules in faces-config, these return values correspond to accepted.xhtml and rejected.xhtml (in same folder as page that has the form).

Page 11: JSF2 Whirlwind Tour

accepted.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">p // g/ / / /

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://java.sun.com/jsf/html">

<h:head>I don’t actually have any dynamic code in this simplistic example, but it is a good idea to plan ahead and l i l d th…

</h:head><h:body>…

always include these.

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

</table><p/><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""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">p // g/ / / /

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://java.sun.com/jsf/html">

<h:head>

Again, this part plus h:head and h:body are not strictly necessary in this simple example, but it is recommended practice to include

…</h:head><h:body>…

them routinely.

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

</table><p/><p/>

<h2>You are rejected from our health plan.</h2><p>Get lost.</p>…</h:body></html>

24

Page 12: JSF2 Whirlwind Tour

index.jsp

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

25

Results

26

Page 13: JSF2 Whirlwind Tour

© 2009 Marty Hall

Dynamic Navigation with Explicit Mappings of

Results PagesResults 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• What you need– New in this example

• navigation-rule in faces-config.xml that maps outcomesnavigation rule in faces config.xml that maps outcomes (return values of bean method) to results pages

– Same as last example• web xml starting page bean results pages• web.xml, starting page, bean, results pages

28

Page 14: JSF2 Whirlwind Tour

faces-config.xml

<?xml version="1.0"?><faces-config version="2.0">

Start page

<faces config … version 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><from-outcome>rejected</from-outcome><to-view-id>/page-for-rejected.jsp</to-view-id>

</navigation-case>

Results pages corresponding to outcomes.

</navigation-case></navigation-rule>

</faces-config>These navigation rules are exactly the same as in JSF 1.x. Default

i i l b t li it i l t ild d l t

29

mappings are simpler, but explicit mappings let you use wildcards, let 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.

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><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/>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>…</h:body></html>30

Except for page title and heading, this is identical to health-plan-signup-1.xhtml from previous example.

Page 15: JSF2 Whirlwind Tour

HealthPlanBean.java

package coreservlets;

import javax.faces.bean.*;

@ManagedBean

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 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""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">p // g/ / / /

<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/><p/>

<h2>You are accepted into our health plan.</h2><p>Congratulations.</p>…</h:body></html>

32Except for page title and heading, this is identical to accepted.xhtml from previous example.

Page 16: JSF2 Whirlwind Tour

page-for-rejected.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">p // g/ / / /

<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/><p/>

<h2>You are rejected from our health plan.</h2><p>Get lost.</p>…</h:body></html>

33Except for page title and heading, this is identical to rejected.xhtml from previous example.

Results

34

Page 17: JSF2 Whirlwind Tour

© 2009 Marty Hall

Using Beans to HandleUsing 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

• IdeaE b k id d d– Enter a bank customer id and a password

– Get either• Page showing first name, last name, and balance

– Various versions depending on balance• Error message about missing or invalid data

• What you needy– New in this example

• Bean: properties corresponding to request parameters• Input form: ‘value’ attribute for h:inputTextInput form: value attribute for h:inputText• Results pages: #{myBean.myProperty}

– Same as first example• web xml with basic settings• web.xml with basic settings

– url-pattern and PROJECT_STAGE• faces-config.xml with start and end tags and empty body

36

Page 18: JSF2 Whirlwind Tour

faces-config.xml

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

…<h:body> This value plays a dual role. When form is first displayed, bankingBean is instantiated and

getCustomerId is called If the value is non empty that result is the initial value of the textfield :body…<h:form><fieldset><legend>Bank Customer Lookup (Results in Separate Page)</legend>

getCustomerId is called. If the value is non-empty, that result is the initial value of the 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.

<legend>Bank Customer Lookup (Results in Separate Page)</legend>Customer ID: <h:inputText value="#{bankingBean.customerId}"/><br/>Password: <h:inputSecret value="#{bankingBean password}"/><br/><h:inputSecret value="#{bankingBean.password}"/><br/><h:commandButton value="Show Current Balance"

action="#{bankingBean.showBalancePage}"/></fieldset>/</h:form>…</h:body></html>

38

Page 19: JSF2 Whirlwind Tour

BankingBean.java

…@ManagedBean@ManagedBean public class BankingBean {

private String customerId, password, message="";private BankCustomer customer;

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

public void setCustomerId(String customerId) {this.customerId = customerId;

}

These will be automatically called by JSF when form is submitted.

public String getPassword() { … }public void setPassword(String password) { … }

public BankCustomer getCustomer() {return(customer);

}39

The customer is initially null. The action controller method (next page) fills in the customer based on the customerId supplied.

BankingBean.java (Continued)

public String showBalancePage() {if (!password.equals("secret")) {if (!password.equals( secret )) {

return("wrong-password");}customer =

Filled in by JSF before this action controller method is called.

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 );} else {

return("high-balance");}

The customer is not filled in automatically by JSF, since it is not directly part of the submitted 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 }

}

40

filled in by the action controller method. Just as in JSF 1.x, beans are typically composed of three parts: properties corresponding to the input, action controller methods, and placeholders for the results data.

There are five possible results pages: wrong-password.xhtml, unknown-customer.xhtml, negative-balance.xhtml, normal-balance.xhtml, and high-balance.xhtml. We are using the default mapping of return values to file names in all cases (rather than explicit navigation rules in faces-config.xml).

Page 20: JSF2 Whirlwind Tour

normal-balance.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">p // g/ / / /

<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 T l "#{ l }"/ B h h …</h:head><h:body>…

<h:outputText value="#{result}"/>. Both approaches escape HTML characters, so use the shorter approach shown here unless you need one of the options to 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><li>ID: #{bankingBean.customer.id}</li><li>Balance: $#{bankingBean.customer.balanceNoSign}</li>

</ul> …/ /</h:body></html>

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

unknown-customer.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">p // g/ / / /

<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 h i i f #{b ki B Id} …

</h:head><h:body>…

HTML characters, it is safe to use #{bankingBean.customerId} instead of <h:outputText value="#{bankingBean.customerId}"/>. The same HTML escaping is done for #{result} as for <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></h:body></html>

42unknown-password.xhtml is similar.

Page 21: JSF2 Whirlwind Tour

Results (Legal ID and Password)(Legal ID and Password)

negative balancebalance

normal balance

high balance

43

Results (Bad Inputs)(Bad Inputs)

44

Page 22: JSF2 Whirlwind Tour

© 2009 Marty Hall

Using Ajax to Display Incremental Results in

Current PageCurrent 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

• IdeaE t b k t id d d– Enter a bank customer id and a password

– In the same page, get either• First name, last name, and balance• Error message about missing or invalid data• Error message about missing or invalid data

• What you need– New in this example

Ch d h dB tt t h t t t/ d t• Changed h:commandButton to have separate start/end tags• 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• Bean: new action controller that sets the message

– Same as previous example• Bean: same properties for request data• Form: Same h:inputTextForm: Same h:inputText• web.xml with basic settings

– url-pattern and PROJECT_STAGE• faces-config.xml with start and end tags and empty body46

Page 23: JSF2 Whirlwind Tour

faces-config.xml

<?xml version="1.0"?><faces-config xmlns="http://java.sun.com/xml/ns/javaee"<faces config 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 …><html xmlns="http://www.w3.org/1999/xhtml"

You use f:ajax, so you need to define namespace for f:

xmlns:h="http://java.sun.com/jsf/html"xmlns:f="http://java.sun.com/jsf/core">

<h:head> … </h:head><h:body> … The form elements to submit and process on the

server The default is @this (current element) so if you

When you use Ajax, a script is inserted into the head automatically. So, you must use h:head, :body

<h:form id="formid">… <h:inputText …/>

server. The default is @this (current element), so if you want a button that just calls a server function with no form data, you can omit the “execute” attribute. You can also list individual elements (formid:elementid) separated by whitespace.

When you use Ajax, the output region and any individually listed form elements must have ids. The final id is formid:element id. (Or, you can tell JSF not to prepend the form id.)

y ynot just head.

…<h:commandButton … action="#{someBean.someMethod}">

<f:ajax execute="@form" render="formid:resultid"/>

</h:commandButton>

p p )

The element or elements (separate by whitespace) to incrementally update.

</h:commandButton><br/><h2><h:outputText value="#{someBean.someProperty}"

id="resultid"/></h2></fieldset> …

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

48

Presumably getSomeProperty has a different value after someMethod has been run. And remember that you really run getSomeProperty on the server and send the result to the page to be inserted: the browser doesn’t actually execute getSomeProperty, even though people sometimes think of it in this way.

Page 24: JSF2 Whirlwind Tour

Understanding f:ajax

• HTMLh f id "f id"<h:form id="formid">

…<h:commandButton … action="#{bean.someMethod}">

<f:ajax execute="@form" render="formid:resultid"/></h:commandButton><h:outputText id="resultid" value="#{bean.someProp}"/>p { p}</h:form>

• InterpretationWh b tt i d d h i tBl h l t t– When button is pressed, send h:inputBlah elements to 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="Show Current Balance"<h:commandButton value= Show Current Balance

action="#{bankingBean.showBalanceMessage}"><f:ajax execute="@form"

render="bankForm:ajaxMessage"/></h:commandButton></h:commandButton><br/><h2><h:outputText value="#{bankingBean.message}"

id="ajaxMessage"/></h2></fieldset> …/</h:form></h:body></html>

50

When the button is pressed, first run setCustomerId and setPassword. 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 empty string initially (the first time form is displayed to user).

Page 25: JSF2 Whirlwind Tour

BankingBean.java (Continued: Other Parts Shown Earlier)Other Parts Shown Earlier)public String showBalanceMessage() {

if (!password.equals("secret")) { Sets message that h t tT t di lif (!password.equals( secret )) {

message = "Incorrect password";} else {

customer =

h:outputText displays.

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 }}return(null);

}51

Normally, the return value of an action controller method determines the page navigation. But there is no navigation with f:ajax: the original page is still displayed. So, the return value is irrelevant.

Results

52

Page 26: JSF2 Whirlwind Tour

© 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 pagesU h l i h l h "h //j /j f/h l"– Use xhtml with xmlns:h="http://java.sun.com/jsf/html"

– Almost always use h:head, h:body, and h:form– Add namespace for f: if you use f:ajax or other f: tagsp y j g– For results pages, usually use #{blah} instead of

<h:outputText value="#{blah}"/>• Default page navigation• Default page navigation

– Return value of controller method is the name of the results page (minus the extension)

D f lt b• Default bean name– Add @ManagedBean before class– If class name is MyBean use #{myBean blah}If class name is MyBean, use #{myBean.blah}

• Ajax support– Add f:ajax with id of h:outputText to re-render54

Page 27: JSF2 Whirlwind Tour

© 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.