JSF2 Managed Beans

download JSF2 Managed Beans

If you can't read please download the document

Transcript of JSF2 Managed Beans

2011 Marty Hall

JSF 2 0: Managed Beans 2.0: Classes to Represent Form InfoOriginals 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 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.

2011 Marty Hall

For live training on JSF 2.0, please see courses at htt // t http://courses.coreservlets.com/. l t /Taught by the author of Core Servlets and JSP, More Servlets and JSP and this tutorial. Available at public JSP, tutorial venues, or customized versions can be held on-site at your organization.C Courses d developed and t l d d taught b M t H ll ht by Marty Hall Courses developed and taught by coreservlets.com experts (edited by Marty) JSF, servlets/JSP, Ajax, jQuery, Android development, Java 6 programming, custom mix of topics Ajax courses can concentrate on 1EE Training: http://courses.coreservlets.com/several Customized Java library (jQuery, Prototype/Scriptaculous, Ext-JS, Dojo, etc.) or survey

Servlets, JSP, Hibernate/JPA, EJB3, GWT, jQuery, GWT, RESTful Web Services RESTful Web Services, Android. Spring, JSF 2.0, Java 6, Ajax, SOAP-based and Spring, Hibernate, Contact [email protected] for details Developed and taught by well-known author and developer. At public venues or onsite at your location.

Topics in This Section Basic beans and managed beans Three parts of beans in JSF Prepopulating input fields Accessing the request & response objects Review of bean scopes

5

2011 Marty Hall

Basic Beans and g Managed BeansCustomized Java EE Training: http://courses.coreservlets.com/Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.

Background: Basic Beans Java classes that follow certain conventions Must have a zero-argument (empty) constructor You can satisfy this requirement either by explicitly defining such a constructor or by omitting all constructors g y g

Should have no public instance variables (fields) You should already follow this practice and use accessor methods instead of allowing direct access to fields

Persistent values should be accessed through methods called getBlah and setBlah If class has method getTitle that returns a String, class is said to have a String property named title JSF uses #{book.title} to mean call getTitle on book .

Boolean properties may use isBlah instead of getBlah What matters is method name, not instance variable name7

More on Bean Properties Usual rule to turn method into property D Drop th word get or set and change the next letter to the d t t d h th t l tt t lowercase. Again, instance var name is irrelevant. Method name: getFirstName Property name: firstName Example: #{customer.firstName}

Exception 1: boolean properties If getter returns boolean or Boolean b l B l Method name: getPrime or isPrime Property name: prime Example: #{myNumber prime} #{myNumber.prime}

Exception 2: consecutive uppercase letters If two uppercase letters in a row after get or set Method name: getURL Property name: URL (not uRL) Example: #{webSite.URL}

8

Bean Properties: ExamplesMethod Names N getFirstName setFirstName isExecutive setExecutive (boolean property) getExecutive setExecutive (boolean property) getZIP setZIP Property Name N firstName Example JSF U Usage #{customer.firstName} #{customer.executive} value="#{customer executive}"/> #{customer.executive} value="#{customer executive}"/> #{address.ZIP}

executive

executive

ZIP

Note 1: property name does not exist anywhere in your code. It is just a shortcut for the method name. Note 2: property name is derived only from method name. Instance variable name is irrelevant. 9

Why You Should Use Accessors, Accessors Not Public Fields Bean rules T be a bean, you should not have public fields. To b b h ld h bli fi ld Wrongpublic double speed;

Rightprivate double speed; // Var need not match method name public double getSpeed() { return(speed); } public void setSpeed(double speed) { this.speed = speed; Note: in Eclipse, after you create instance variable, if } you R-click and choose Source, it gives you option to R click Source ,generate getters and setters for you.

OOP design10

You should do this in all your Java code anyhow. Why?

Why You Should Use Accessors, Accessors Not Public Fields 1) You can put constraints on valuespublic void setSpeed(double newSpeed) { if (newSpeed < 0) { sendErrorMessage(...); newSpeed = Math.abs(newSpeed); } speed = newSpeed; }

If users of your class accessed the fields directly, then they would each be responsible for checking constraints.

11

Why You Should Use Accessors, Accessors Not Public Fields 2) You can change your internal representation without changing interface i ih h i i f// Now using metric units ( p , not mph) g (kph, p ) public void setSpeed(double newSpeed) { speedInKPH = convert(newSpeed); } public oid setSpeedInKPH(double newSpeed) p blic void setSpeedInKPH(do ble ne Speed) { speedInKPH = newSpeed; }

12

Why You Should Use Accessors, Accessors Not Public Fields 3) You can perform arbitrary side effectspublic double setSpeed(double newSpeed) { speed = newSpeed; updateSpeedometerDisplay(); }

If users of your class accessed the fields directly, then they would each be responsible for executing side effects. Too much work and runs huge risk of having display inconsistent from actual values.

13

Basic Beans: Bottom Line It is no onerous requirement to be a bean You are probably following most of the conventions already anyhow Zero arg constructor No public instance variables Use getBlah/setBlah or isBlah/setBlah naming conventions

JSF often refers to bean properties ft f t b ti Which are shortcuts for getter/setter methods getFirstName method: refer to firstName firstName #{customer.firstName}

isVeryCool method (boolean): refer to veryCool #{invention veryCool} #{invention.veryCool}

getHTMLString method: refer to HTMLString #{message.HTMLString}14

Managed Beans JSF automatically manages the bean Instantiates it Thus the need for a zero-arg constructor

Controls its lifecycle Scope (request, session, application) determines lifetime

Calls setter methods I.e., f , for #{ f / when form submitted, the value is passed to setFirstName

Calls getter methods #{customer.firstName} results in calling getFirstName

Declaring beans Si l t @ManagedBean before class Simplest: @M dB b f l Most powerful: in faces-config.xml15

See separate section on navigation and faces-config.xml

2011 Marty Hall

The Three Parts of g Managed BeansCustomized Java EE Training: http://courses.coreservlets.com/Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.

Overview Managed beans typically have three parts Bean properties (i.e, pairs of getter and setter methods) One pair for each input element Setter methods called automatically by JSF when form submitted

Action controller methods Often only one, but could be several if the same form has one multiple push buttons Action controller method (corresponding to the button that was pressed) called automatically by JSF

Placeholders for results data Not automatically called by JSF: to be filled in by action controller method b t ll th d based on results of b i d lt f business l i logic.17

JSF Flow of Control (Simplified)balance.xhtmlUses and When form submitted, textfield value passed to setCustomerId. When form first displayed, getCustomerId is called. If it is non-empty, it becomes initial value of the textfield.

Run Setter Methodssubmit form POST request b l t balance.jsf j f

Business Logicresults

The results get stored in the placeholder. E.g., a Customer that corresponds to the customer ID is found and placed in an instance variable of main bean.

Find Bean

Run Action Controller Method

return value l

Choose Page

forward

If bean is request-scoped, instantiate it. But for other scopes (e.g., session), you might use existing bean instance.

This is the method listed in the action of h:commandButton (e.g., findBalance)

result1.xhtml result2.xhtml ... resultN.xhtml

Uses #{ #{bankForm.someProperty} p y} to display bean properties

This could be #{bankForm.customerId}, where customerId was passed in by the user, or it could be #{bankForm.customer.balance}, where getCustomer returns the Customer object found by the business logic, and getBalance returns that customers bank account balance.

18

Example Idea Enter a bank customer ID Get either Page showing first name last name and balance name, name, Error message about invalid customer ID

What managed bean needs Bean property corresponding to input element I.e., getCustomerId and setCustomerId

Action controller method Maps a customer ID to a Customer and stores the Customer in an instance variable

Placeholder for results data l h ld f l d19

An initially empty instance variable (for storing the Customer) and associated getter method.

Input Form (customer-lookup.xhtml) (customer-lookup xhtml) This value plays a dual role. When form is first displayed, BankForm is instantiated and getCustomerId is called. If the value is non empty, non-empty that result is the initial value of the textfield. Otherwise, the textfield is initially empty When the form is submitted textfield Otherwise empty. submitted, BankForm is reinstantiated (since it is request scope) and the value in the textfield is passed to setCustomerId. Enter Your Customer ID Legal ids are id001, id002, and id003. / Customer ID:
value="#{bankForm.customerId}"/>
/

20

BankForm.java: Part 1 (Bean Properties for Input Elements)@ManagedBean public class BankForm { private String customerId; public String getCustomerId() { return(customerId); }Called by JSF when form first displayed. Since it returns null in that case, the textfield is left blank initially.

When form submitted, the bean is instantiated again (since it is requestscoped, not session-scoped) and the value in the textfield is passed to this method. p

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

21

BankForm.java: Part 2 (Action Controller Method)private static CustomerLookupService lookupService = new CustomerSimpleMap(); public String findBalance() { customer = lookupService findCustomer(customerId); lookupService.findCustomer(customerId); if (customer == null) { return("unknown-customer"); } else { l Filled in by JSF before this action controller method is return("show-customer"); called. } }This is the placeholder shown on next slide.

22

BankForm.java: Part 3 (Placeholder for Results)private Customer customer; public Customer getCustomer() { return(customer); } }

Filled in by the action controller method based on the value returned by the business logic.

The getCustomer method is needed because the results page does #{bankForm.customer.firstName} and #{bankForm.customer.otherProperties}. But no setter method is needed since this property does not correspond directly to di tl t iinput d t and thi property iis not automatically fill d iin b JSF t data, d this t t t ti ll filled by JSF.

23

Business Logic (Interface)public interface CustomerLookupService { public Customer findCustomer(String id); }

24

Business Logic (Implementation)public class CustomerSimpleMap implements CustomerLookupService { private Map customers; public CustomerSimpleMap() { customers = new HashMap(); addCustomer(new Customer("id001", "Harry", "Hacker", -3456.78)); , )); addCustomer(new Customer("id002", "Codie", "Coder", 1234.56)); addCustomer(new Customer("id003", "Polly", y "Programmer", 987654.32)); }

Provides some simple hardcoded test cases.

25

Business Logic (Implementation, (Implementation Continued)public Customer findCustomer(String id) { if (id!=null) { return(customers.get(id.toLowerCase())); } else { return(null); } } private void addCustomer(Customer customer) { customers.put(customer.getId(), customer); } }

26

Results Page 1 (show-balance.xhtml) (show-balance xhtml)

  • First name: #{bankForm.customer.firstName}

Last name: #{bankForm.customer.lastName} #{ } / ID: #{bankForm.customer.id} Balance: $#{bankForm.customer.balanceNoSign} 27

Results Page 2 (unknown-customer.xhtml) (unknown-customer xhtml) No customer found with id "#{bankForm.customerId}" Please try again.

28

Results

29

2011 Marty Hall

Prepopulating Input Fields pCustomized Java EE Training: http://courses.coreservlets.com/Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.

Dual Roles Bean property refers to both getter & setter The getter method is called when form is displayed, and affects what is initially displayed to user The value from the input element is passed to the setter method when the form is submitted

Examples p (textfield) If getter returns non-empty (not null or ""), this is initial value inside textfield Not used for password fields textfield. fields.

(checkbox) Getter returns true: initially checked. Otherwise unchecked

(combobox; drop down menu)31

If return value of getter matches an entry in menu, that is initial selection. Otherwise top entry is initially selected.

Textfields Example 1 When form initially displayed, call getSomeProperty. If value is something other than null or empty String, use it g py g, as initial value of textfield. When form submitted, take the value in the textfield and p pass it to setSomeProperty. p y

Example 2 (Chaining) When form initially displayed, call getA, then getB on that result, then getC on that. If value of getC is non-empty, use it as initial value of textfield. Wh form submitted, call getA, then getB on that result. When f b i d ll A h B h l Then take the value in the textfield and pass it to the setC method of that final result. Only last one becomes setter.

32

Checkboxes Example When form initially displayed call the accessor method displayed, method, which must be of type boolean or Boolean. The name could be either isSomeProperty (most common) or g getSomeProperty. If value is true, make checkbox initially p y y checked. If value is false, make checkbox initially unchecked. When form submitted, pass either true or false to setSomeProperty (which expects boolean or Boolean) Note that JSF does not require anything (such as Struts 1.x does) to clear out old values of session-scoped checkboxes or radio buttons. buttons

33

Drop Down Menus (Comboboxes) Example When form initially displayed, call getChoices (which should return List or SelectItem[]). This gives SelectItem[]) the entries in the drop down menu. Then call getSomeProperty. If result matches any of the entries, make that initially shown item. Otherwise use top item. y p There are several forms of the SelectItem constructor, but the simplest just takes a String: the value that will go in the menu.

When form submitted, pass the current selection to setSomeProperty.34

Note that, due to the f:selectItems tag, you must add an entry for the f: namespace to the html start tag at top of file

Example Idea Collect input about programming background and ll i b i b k d d preferences. Give recommended computer study plan.

Input form Textfield for favorite language. Prepopulate based on most popular language in the application Drop do n men for second-favorite language. Make down menu second fa orite lang age choices be the languages for which app has study guides. Make initial choice the second most popular language in the th application. li ti Two checkboxes. Initial selection based on logic in app

Results page List of recommended languages. Requires looping tag. Shown briefly here but covered in detail in later section35

Input Form Top (study-plan-input.xhtml) (study-plan-input xhtml) Since we use the f:selectItems tag for the drop down menu, we must declare the f: namespace.

36

Input Form Bottom (study-plan-input.xhtml) (study-plan-input xhtml) Email address:
Favorite language:
Second favorite language: # /
Programmed for 5+ years?
Personally know Larry Page, Steve Balmer, and James Gosling?
action="#{trainingForm showTrainingPlan}"/>

37

Managed Bean (Part 1 Properties for Input Elements)@ManagedBean public class TrainingForm { private String emailAddress; private String favoriteLanguage = LanguageUtils.findMostPopularLanguage(0); LanguageUtils findMostPopularLanguage(0); private String secondFavoriteLanguage = LanguageUtils.findMostPopularLanguage(1); private pri ate boolean isE pert = tr e isExpert true; private boolean isLiar = false; // G tt Getters and setters f d tt for all. Th getters f ll The tt for // the boolean properties start with is, not get public Li t S l tIt bli List getAvailableLanguages() { tA il bl L () return(LanguageUtils.languageList()); } // Options for dropdown box. See later slide.

38

Managed Bean (Part 2 Action Controller)public String showTrainingPlan() { int numLanguagesToStudy; if (isExpert) { numLanguagesToStudy = 4; } else { numLanguagesToStudy = 2; } ( ) if (isLiar) { This List is the placeholder that is filled in. Since it can be of varying length, return("liar"); the results page will need to use a loop. } else { languagesToStudy = LanguageUtils.randomLanguages(numLanguagesToStudy); return("study-plan"); } }39

Managed Bean (Part 3 Placeholder for Results)private List languagesToStudy; public List getLanguagesToStudy() { return(languagesToStudy); }

40

Helper Class (Code for Options in Dropdown)public class LanguageUtils { private static String[] languages = { "Java", "JavaScript", "C#", "C++", "PHP", "Python", "Perl", "Ruby", "Scala" }; p private static List availableLanguages; g g static { availableLanguages = new ArrayList(); for(String language: languages) { availableLanguages.add(new SelectItem(language)); } } public static List languageList() { return(availableLanguages); }41

Main Results Page (study-plan.xhtml) (study-plan xhtml)

  • #{language}

There Th iis a whole separate tutoriall section on llooping and h dli variableh l t t t i ti i d handling i bl length data. But the basic idea is simple: identical to the JSTL c:forEach loopand very similar to the Java for(Blah b: collectionOfBlahs) loop. This uses JSTL behind the scenes, so if you are using a non-Java-EE-6 server, you must include the JSTL JAR files with your app. 42

Error Page (liar.xhtml) (liar xhtml) Yeah, right. And you know more JavaScript than g , pp Brendan Eich or Doug Crockford, I suppose? Please try again, but be honest this time.

Insulting your users is not generally considered a recommended practice.

43

Results (Input Form)

44

Results (Results Pages)

45

2011 Marty Hall

Getting the Request p j and Response ObjectsCustomized Java EE Training: http://courses.coreservlets.com/Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.

Problem No automatic access to request & response JSF action controller methods do not have direct access Unlike in Struts, where action controller method (execute) gets request and response automatically

Why this matters Uses for request object Explicit session manipulation E.g., changing inactive interval or invalidating session

Explicit cookie manipulation (e.g., long-lived cookies) Reading request headers (e g User Agent) (e.g., User-Agent) Looking up requesting host name

Uses for response object S Setting status codes Setting response headers Setting long-lived cookies

47

Solution Static methods If they are needed, use static method calls to get them h d d i h d ll hExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); HttpServletRequest request = (HttpServletRequest)context.getRequest(); HttpServletResponse response = (HttpServletResponse)context.getResponse();

Note In some environments you cast results of getRequest and environments, getResponse to values other than HttpServletRequest and HttpServletResponse E g in a portlet environment you might cast result to E.g., environment, PortletRequest and PortletResponse48

Example Idea Collect a search string and a search engine name, show the results of a search with that search engine.

Input form Use textfield for arbitrary search string. Use drop down menu to list only search engines that app supports. y g pp pp

Managed bean Construct a URL by concatenating a base URL (e.g., http://www.google.com/search?q=) with the URLh // l / h? ) i h h URL encoded search string Do response.sendRedirect Must use static methods to get the HttpServletResponse49

Return normal strings for error pages

Input Form (search-engine-form.xhtml) (search-engine-form xhtml) h b d Search String: g
Search Engine:
50

Managed Bean (Part 1 Properties for Input Elements)@ManagedBean p public class SearchController { private String searchString, searchEngine; public String getSearchString() { return(searchString); } public void setSearchString(String searchString) { this.searchString = searchString; } public String getSearchEngine() { return(searchEngine); } public void setSearchEngine(String searchEngine) { this.searchEngine = searchEngine; } public List getSearchEngineNames() { return(SearchUtilities.searchEngineNames()); }

51

Managed Bean (Part 2 Action Controller)public String doSearch() throws IOException { if ((searchString.trim().length() == 0)) { return("no-search-string"); } searchString = URLEncoder.encode(searchString, "utf-8"); String searchURL = SearchUtilities.makeURL(searchEngine, searchString); if (searchURL != null) { ExternalContext context = t lC t t t t FacesContext.getCurrentInstance().getExternalContext(); HttpServletResponse response = (HttpServletResponse)context.getResponse(); (HttpServletResponse)context getResponse(); response.sendRedirect(searchURL); return(null); } else { return("unknown-search-engine"); } }

52

Results (Input Form)

53

Results (Forwarding Results)

54

2011 Marty Hall

Review of Bean ScopesCustomized Java EE Training: http://courses.coreservlets.com/Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.

Bean Scopes Idea Designates how long managed beans will stay alive, and which users and requests can access previous bean instances.

JSF 1.x scopes Request, session, application q pp Specified in faces-config.xml Request scope is the defaultExamples of the use of bean scopes given in tutorial section on JSF 2.0 basics with annotations.

JSF 2.0 scopes 20 Request, session, application, view, none, custom Specified either in faces-config.xml or by one of the new faces config xml annotations (e.g., @SessionScoped) Request scope is still the default

56

Annotations to Specify Bean Scope @RequestScoped Default. Make a new instance for every HTTP request. Since beans are also used for initial values in input form, this means bean is generally instantiated twice (once when form is displayed, once when form is submitted).

@SessionScoped Put bean in session scope. If same user with same cookie returns before session timeout, same bean instance is used. You should make bean Serializable.

@ApplicationScoped Put bean in application scope. Shared by all users. Bean pp p y either should have no state or you must carefully synchronize access.57

Annotations to Specify Bean Scope (Continued) @ViewScoped Same bean instance is used as long as same user is on same page (e.g., with event handlers or Ajax). New scope in JSF 2 0 2.0. Bean should implement Serializable

@CustomScoped(value="#{someMap}") Bean is stored in the Map, and programmer can control lifecycle. New scope in JSF 2.0

@NoneScoped Bean is not placed in a scope. Useful for beans that are p p referenced by other beans that are in scopes. New scope in JSF 2.058

2011 Marty Hall

Wrap-UpCustomized Java EE Training: http://courses.coreservlets.com/Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.

Summary Beans generally have three sections Bean properties to represent input elements A pair of getter and setter methods for each

Action controller method Placeholder for results data

Prepopulating input elements p p g p When form displayed, getFirstName called When form submitted, value passed to setFirstName s bmitted al e

Getting the request and response objectsExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); HttpServletRequest request = (HttpServletRequest)context.getRequest(); HttpServletResponse response = (HttpServletResponse)context.getResponse();

60

2011 Marty Hall

Questions?Customized Java EE Training: http://courses.coreservlets.com/Servlets, JSP, JSF 2.0, Java 6, Ajax, jQuery, GWT, Spring, Hibernate, RESTful Web Services, Android. Developed and taught by well-known author and developer. At public venues or onsite at your location.