© 2005 Marty Hall
JSF: Managed Beans Core Servlets & JSP book: www.coreservlets.com More Servlets & JSP book: www.moreservlets.com Servlet/JSP/Struts/JSF Training: courses.coreservlets.com http://courses.coreservlets.com/ -- 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 http://courses.coreservlets.com/. 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. http://courses.coreservlets.com/ -- Hands-on, customized training for Java, servlets, JSP, Struts, and JSF.
Topics in This Section • Using beans to represent request parameters • Declaring beans in faces-config.xml • Outputting bean properties – Standard JSF approach – JSP 2.0 expression language
• Using properties files – Standard prompts/strings – Internationalized text
4
J2EE training and tutorials: http://www.coreservlets.com
Background: What Are 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
– Should have no public instance variables (fields) • I hope you already follow this practice and use accessor methods instead of allowing direct access to fields
– Persistent values should be accessed through methods called getXxx and setXxx • If class has method getTitle that returns a String, class is said to have a String property named title • Boolean properties use isXxx instead of getXxx
– For more on beans, see http://java.sun.com/beans/docs/ 5
J2EE training and tutorials: http://www.coreservlets.com
Why You Should Use Accessors, Not Public Fields • To be a bean, you cannot have public fields • So, you should replace public double speed;
• with private double speed; public double getSpeed() { return(speed); } public void setSpeed(double newSpeed) { speed = newSpeed; }
• You should do this in all your Java code anyhow. Why? 6
J2EE training and tutorials: http://www.coreservlets.com
Why You Should Use Accessors, Not Public Fields • You can put constraints on values public 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.
7
J2EE training and tutorials: http://www.coreservlets.com
Why You Should Use Accessors, Not Public Fields • You can change your internal representation without changing interface // Now using metric units (kph, not mph) public void setSpeed(double newSpeed) { setSpeedInKPH = convert(newSpeed); } public void setSpeedInKPH(double newSpeed) { speedInKPH = newSpeed; }
8
J2EE training and tutorials: http://www.coreservlets.com
Why You Should Use Accessors, Not Public Fields • You can perform arbitrary side effects public 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 be inconsistent from actual values.
9
J2EE training and tutorials: http://www.coreservlets.com
Steps in Using JSF 1. Create a bean to represent the form data 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 faces-config.xml to declare the form bean and navigation rules 6. Create JSP pages corresponding to each return condition •
Access bean properties in these pages
7. Protect raw JSP pages from access 10
J2EE training and tutorials: http://www.coreservlets.com
Example 1: Using Beans • Similar to previous example – Original URL will be http://hostname/jsftest/register3.faces – When form submitted, three possible results • Error message re illegal email address • Error message re illegal password • Success
• Differences – Action controller obtains request data from bean – Output pages access bean properties
• Main points – Creating a bean – Declaring beans in faces-config.xml – Outputting bean properties 11
J2EE training and tutorials: http://www.coreservlets.com
Main Points of This Example • Make bean representing the request parameters public class MyBean { public String getBlah() {…} public void setBlah(String newValue) {…} … }
• Use faces-config.xml to declare beans beanName package.MyBean request …
• Use h:inputText to associate textfield with property
• Use h:outputText to output bean properties 12
J2EE training and tutorials: http://www.coreservlets.com
Step 1: Create Form Bean • One property for each request parameter – If input form says value="#{name.foo}",then bean should have getFoo and setFoo methods.
• Additional properties for output values • Populating bean – System will fill in property values automatically – Strings converted as with jsp:setProperty • Form redisplayed if there are errors: see validation section
• Action controller
13
– Method can access bean properties instead of calling request.getParameter. – ExternalContext only needed if you want to access request headers, cookies, session data, or other HTTPrelated info. – Method also creates business objects and stores them in the properties reserved for output values J2EE training and tutorials: http://www.coreservlets.com
Step 1: Example Code • Code for request parameter representation package coreservlets; public class RegistrationBean { private String email = "user@host"; private String password = ""; public String getEmail() { return(email); } public void setEmail(String email) { this.email = email; } public String getPassword() { return(password); } public void setPassword(String password) { this.password = password; } 14
J2EE training and tutorials: http://www.coreservlets.com
Step 1: Example Code • Code for output values private SuggestionBean suggestion; public SuggestionBean getSuggestion() { return(suggestion); }
• See www.coreservlets.com for code for SuggestionBean – Merely creates a randomized suggested email address and password
15
J2EE training and tutorials: http://www.coreservlets.com
Step 2: Create Input Form • Same as previous example, except – h:inputBlah tags given a value attribute identifying the corresponding bean property • Also gives initial value to textfield
– id attribute not needed
• Example code … Email address:
Password:
… 16
J2EE training and tutorials: http://www.coreservlets.com
Step 3: Specify Action Controller • Same approach as in previous example Email address:
Password:
17
J2EE training and tutorials: http://www.coreservlets.com
Steps 2 & 3: Example Results • File is tomcat_dir/webapps/jsf-test/register3.jsp • URL is http://localhost/jsf-test/register3.faces • The user@host value comes from the bean
18
J2EE training and tutorials: http://www.coreservlets.com
Step 4: Create an Action Controller • Can access the bean properties directly – System automatically fills them in before calling the action method – No need to access ExternalContext or call request.getParameter
• Fills in properties corresponding to output values – These are the results-beans used in traditional MVC
• Still returns strings corresponding to each of the possible outcomes – As in previous example
• ExternalContext still often used – To access cookies, session data, request headers, etc. 19
J2EE training and tutorials: http://www.coreservlets.com
Step 4: Example Code public class RegistrationBean { // Properties shown on earlier slides public String register() { if ((email == null) || (email.trim().length() < 3) || (email.indexOf("@") == -1)) { suggestion = SuggestionUtils.getSuggestionBean(); return("bad-address"); } else if ((password == null) || (password.trim().length() < 6)) { suggestion = SuggestionUtils.getSuggestionBean(); return("bad-password"); } else { return("success"); } } } 20
J2EE training and tutorials: http://www.coreservlets.com
Step 5: Update faces-config.xml • Declaring bean … registrationBean coreservlets.RegistrationBean request …
21
J2EE training and tutorials: http://www.coreservlets.com
Step 5: Update faces-config.xml • Specifying navigation rules … … /register3.jsp bad-address /WEB-INF/results/bad-address3.jsp bad-password /WEB-INF/results/bad-password3.jsp success /WEB-INF/results/result3.jsp 22
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Create Output JSP Pages • Use h:outputText to access bean properties … …
23
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Create Output JSP Pages • …/jsf-test/WEB-INF/results/bad-address3.jsp …
The address "" is not of the form username@hostname (e.g., ).
Please try again. … 24
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Email Address • Input
25
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Email Address • Output
26
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Create Output JSP Pages • …/jsf-test/WEB-INF/results/bad-password3.jsp
27
…
The password "" is too short; it must contain at least six characters. Here is a possible password: .
Please try again. … J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Password • Input
28
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Password • Output
29
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Create Output JSP Pages • …/jsf-test/WEB-INF/results/result3.jsp
30
…
You have registered successfully.
(Version 3) …
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Good Input • Input
31
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Good Input • Output
32
J2EE training and tutorials: http://www.coreservlets.com
Step 7: Protect Raw JSP Pages … Prevent access to raw JSP pages that are for JSF pages. Raw-JSF-JSP-Pages /welcome.jsp /register1.jsp /register2.jsp /register3.jsp No roles, so no direct access
33
J2EE training and tutorials: http://www.coreservlets.com
Alternative Approaches • Preview: using the JSP 2.0 EL – If output pages only display bean properties (rather than manipulating a form or using form elements): • Why bother with f:view and associated taglib declaration? • Why use h:outputText and associated taglib declaration when the JSP 2.0 EL is simpler?
– If you use the JSP 2.0 EL, you must: • Be in a JSP 2.0 container (e.g., Tomcat 5, not Tomcat 4) • Use the JSP 2.0 declaration for web.xml (see later section)
• Separating request parameters from action controller – If you use two separate classes, how does controller class get access to bean that represents request params? • Get ExternalContext and call getSessionMap • Wire beans together in faces-config.xml 34
J2EE training and tutorials: http://www.coreservlets.com
Using the JSP 2.0 Expression Language • Standard JSF approach …
You have registered successfully.
(Version 3) … 35
J2EE training and tutorials: http://www.coreservlets.com
Using the JSP 2.0 Expression Language • JSP 2.0 approach – Omit taglib declarations and f:view tags – Shorten expression that outputs bean properties …
You have registered successfully.
- Email Address: ${registrationBean.email}
- Password: ${registrationBean.password}
(Version 3) … 36
J2EE training and tutorials: http://www.coreservlets.com
Example 2: Properties Files • This example is very similar to the previous one. – However, some of the standard prompts and messages are taken from a properties file instead of being hardcoded in the JSP pages.
• Steps – Load a properties file with f:loadBundle – Output values with #{bundleName.propertyName}
• Advantages to using messages from properties files – If a message is used in several places, it can be updated with a single change. This is consistent with the JSF philosophy of making as many changes as possible in config files, not in Java or JSP code. – If you use messages pervasively in your JSP pages, you can internationalize your application by having multiple properties files corresponding to the locale (e.g., application.properties, application_es.properties, applications_jp.properties, etc., as with standard I18N in Java). 37
J2EE training and tutorials: http://www.coreservlets.com
Main Points of This Example • Put standard messages in a normal Java properties file under WEB-INF/classes – Note that names should not contain dots as in Struts name1=value1 name2=value2 …
• Load the properties file with f:loadBundle – Suppose the properties file is WEB-INF/classes/someDir/foo.properties – Load it with the following
– Notice that you do not list WEB-INF/classes or the file extension
• You still use h:outputText 38
J2EE training and tutorials: http://www.coreservlets.com
Properties File for This Example • WEB-INF/classes/coreservlets/prompts.properties formTitle=New Account Registration emailPrompt=Email Address passwordPrompt=Password buttonLabel=Sign Me Up! emailError=Illegal Email Address passwordError=Illegal Password passwordLength=six
39
J2EE training and tutorials: http://www.coreservlets.com
Step 1: Create Form Bean • Same bean as in previous example
40
J2EE training and tutorials: http://www.coreservlets.com
Step 2: Create Input Form • Same as previous example, except title and prompts taken from properties file – Actual file is WEB-INF/classes/coreservlets/prompts.properties
– Remember you have to do h:loadBundle in each file • Unlike in Struts • On the other hand, Struts requires you to declare properties file in the config file, and JSF does not
41
J2EE training and tutorials: http://www.coreservlets.com
Step 2: Example Code … …
:
:
42
J2EE training and tutorials: http://www.coreservlets.com
Step 3: Specify Action Controller • Exactly the same as in previous example :
:
43
J2EE training and tutorials: http://www.coreservlets.com
Steps 2 & 3: Example Results • File is tomcat_dir/webapps/jsf-test/register4.jsp • URL is http://localhost/jsf-test/register4.faces • The user@host value comes from the bean
44
J2EE training and tutorials: http://www.coreservlets.com
Step 4: Create an Action Controller • Same as before – The same bean is used in this example and the previous one. – This illustrates the advantages of both JSF and Struts over standard MVC: you can reuse the same controller but map return conditions to different output pages
45
J2EE training and tutorials: http://www.coreservlets.com
Step 5: Update faces-config.xml • Declaring bean already done – No need to repeat previous declaration … registrationBean coreservlets.RegistrationBean request … 46
J2EE training and tutorials: http://www.coreservlets.com
Step 5: Update faces-config.xml • Specifying navigation rules – You do need a new entry for this … … /register4.jsp bad-address /WEB-INF/results/bad-address4.jsp bad-password /WEB-INF/results/bad-password4.jsp success /WEB-INF/results/result4.jsp 47
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Create Output JSP Pages • …/jsf-test/WEB-INF/results/bad-address4.jsp
48
… …
The address "" is not of the form username@hostname (e.g., ).
Please try again. … J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Email Address • Input
49
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Email Address • Output
50
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Create Output JSP Pages • …/jsf-test/WEB-INF/results/bad-password4.jsp … …
The password "" is too short; it must contain at least characters. Here is a possible password: .
Please try again. … 51
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Password • Input
52
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Bad Password • Output
53
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Create Output JSP Pages • …/jsf-test/WEB-INF/results/result4.jsp
54
…
You have registered successfully.
(Version 4) … J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Good Input • Input
55
J2EE training and tutorials: http://www.coreservlets.com
Step 6: Example Result for Good Input • Output
56
J2EE training and tutorials: http://www.coreservlets.com
Step 7: Protect Raw JSP Pages … … Raw-JSF-JSP-Pages /welcome.jsp /register1.jsp /register2.jsp /register3.jsp /register4.jsp No roles, so no direct access
57
J2EE training and tutorials: http://www.coreservlets.com
Summary • Create a bean – Properties for each request parameter – Action controller method – Properties to hold results objects
• Declare bean in faces-config.xml – Use managed-beans declaration
• Use h:outputText to output bean properties – The JSP 2.0 expression language is often better, however
• If you have standard prompts (or internationalized text) – Put prompts/text in properties file – Load file with f:loadBundle – Output properties with h:outputText 58
J2EE training and tutorials: http://www.coreservlets.com
© 2005 Marty Hall
Questions? Core Servlets & JSP book: www.coreservlets.com More Servlets & JSP book: www.moreservlets.com Servlet/JSP/Struts/JSF Training: courses.coreservlets.com http://courses.coreservlets.com/ -- Hands-on, customized training for Java, servlets, JSP, Struts, and JSF.