Controller of MVC and Select
Controller of MVC and Select
JSF life-cycle
Life-cycle is important in JSF. When a page is first invoked:
Jsf look for any managed bean (MB) associated to the page. The MB will be intantiated together with the class variables and the whatever in the null constructor JSF builds the User Interface Component Tree called UITree
JSF life-cycle
JSF updates the UITree from MB (to be seen) HTML Page is rendered User change some values and press one of the action component JSF do the conversion and validation for all components (disregard this for the moment) JSF updates MB variables (to be seen) JSF perform action The cycle repeats. We discuss more about the cycle as we discuss EL, converter, validator and other components later but the knowledge of this cycle is required now
MVC Architecture
In MVC, our Studentsfaade is the model The view is the html page (JSF call it JSF face) we need a controller to handle the variables in the view (as backing bean) We need the controller to access the data using the model many views may use the same controller and thus all changes happen in only one place
SelectComponents
All six select components have two important attributes value and selectItem, we call these six components as <f:select> components Value is the backing bean variable name used to bind the value chosen by the user If it is a select one, then the backing bean refer to a single variable If it is a select many, then the backing bean refer to an array or a List (second example)
Example
<f:selectOneMenu value=#,bb.selectedSweet} > <f:selectItem itemLabel=Hudson" itemValue=.20 /> <f:selectItem itemLabel=Hacks" itemValue=.30" /> <f:selectItem itemLabel=Milo" itemValue=.50" /> </f:selectOneMenu> <f:selectOneMenu value= #,bb.selectedSweet- /> <f:selectItems value= #,bb.sweetOptions- /> </f:selectOneMenu> In class bb, we must have a variable name selectedSweet For the second method we need a collection named sweetOptions of type List<SelectItem> (or other type of collection) We also need the appropriate setter and getter
OK
3 null
4 selectItems
Managed Bean
Student and faade object used earlier must be instantiated first The Container (Web Container)
automatically instantiate the managed bean If the page is initially displayed, the variables would be empty If the page is posted back then the variables will retain previous values obtained through the getter Once the page is sent, all the variables will be populated using the setter
Student Controller
Student[] studentArray ; String selectedStudent; List<SelectItem> studentOptions = new ArrayList<SelectItem>(); StudentFacade sf= new StudentFacade();
studentArray is an array used to take list from the faade This array is then converted to List<selectItems> required by JSF. It is a list of <label,value> selectItem objects
Label is the text that will be displayed in the list box while value is the value that will be stored in selectedItem variable. It is then added to the studentOptions list
Index.xhtml
Create h:outputText for enter your name text
Can type label directly but using TextOutput has the advantage of using extra attributes
Create h:SelectOneMenu with selectItem tags getting the <label,value> information from sc.students list and required attribute = true Create h:CommandButton with action = sc.doClick attribute
On click
Index.xhtml sc StudentController Facade
sc.selectedStudent
2
1 action = #, sc.doClick} 3 Welcome.xhtml setSelectedStudent 4.1 getSelectedStudent f students Student * Name,age get,set
sc.selectedStudent
Welcome.xhtml
Simply use the backing bean to display the selected student name
:sc
:sf
List: students
students
:s1
:index
constructor
sf constructor findAll()
students[]
Students.add(s1)
3. The doOk method returns a string value = ________. This makes the server opens _________ .xhtml 4. When _________.xhtml is rendered, the value of selectedStudent is retrieved using _________ method
welcome
selectedStudent=Abu Bakar
Backing Bean
Associated to a view, there is one or many backing beans Backing beans prepare the variables to store information in the view The view simplifies the set, get and actions using Backing Bean and EL In our case the Backing bean, managed bean and controller are actually referring to the same object although their meanings are different
Jsf life-cycle
For new page (non-postback), create server-side component tree. For postback restore the view Apply request values involves only valueHolder components (e.g textfield) not Action source components Process validations and conversions (according to UI-view tree component)(chapter 6) Update model values Invoke application Render response
And in MB
Iterate through sweets[] { SelectItem si = new SelectItem(sweets[i].name, sweets[i]); sweetOptions.add(si); }
Problem
In the page
selectedSweet (type String) Hacks Hudson Milo toString returns hash number sweetOptions (type Object[])
And in MB
setSelectedSweet(String selectedSweet){ this.selectedSweet = selectedSweet; error }
2. In the backing bean create sweetMap and in setSelectedSweet, use sweetMap to get the selected Sweet
Iterate through Sweets[]{ sweetMap.put(sweet[i].id,sweet[i]) } void setSelectedSweet(String ss){ this.selectedSweet = sweetMap.get(ss); }
Using Map
In the page
selectedSweet (type String) Hacks Hudson Milo toString returns id sweetOptions (type Object[])
And in MB
setSelectedSweet(id)
SelectedSweet value
Suppose Milo is selected, then Sweet*2+ is given to SelectedSweet Java use sweet[2].toString to present to selectedSweet Since tostring method returns id, so selectedSweet gets the String = 2 We then go to the converter
SweetConverter
Implements Converter Before the setter is implemented, JSF runs the getAsObject method in the converter first getAsObject takes value from SelectedSweet which is id (String) = 2 Recall our find(2) method in the faade returns the Sweet[2] The converter returns Sweet[2] for the consumption of setSelectedSweet(selectedSweet)
Using Converter
In the page
selectedSweet (type String) Hacks Hudson Milo toString returns 2 sweetOptions (type String[]) Select Milo converter Sweet[2]
And in MB
setSelectedSweet(Sweet selectedSweet){ this.selectedSweet = selectedSweet; }
3. JSF get selectedSweet from BB and use Converter to convert to String before populating the component 4. On click, JSF get the String from component convert to Sweet and called bb.setSelectedSweet(Sweet s)
response.xhtml
This page simply use the selectedSweet to display to the user the selected sweet We can use use the getAsString method of the converter to convert the Sweet object into id first before the getSelectedSweet But it is much easier to simply use getSelectedSweet .getName() Run the application
And in MB
Sweet selectedSweet;
Void setselectedSweet(int ssi){ this.selectedSweet = sweetOptions.get(ssi); }
SelectMany components
Very similar to SelectOne except that the value now returns an array or List We may use the map, the converter or index method The array index method as illustrated on the next slide It is very easy to display an array or a collection using <h:dataTable> (see second slide after this)
And in MB
Int[] selectedSweetIndices; List<Sweet> selectedSweets = new ArrayList<Sweet>();
Void setselectedSweetsIndices(int[] ssi){ selectedSweets.clear(); for (int i = 0; i < ssi.length; i++) { selectedSweets.add(sweetOptions.get(ssi[i]); }
Using converter
The xhtml, toString and converter class is the same as in select one example And in MB
Sweet[] selectedSweets; Void setselectedSweets(Sweet[] selectedSweete){ this.selectedSweets = selectedSweets; }
Note: converter has converter has converted array of id to array of sweets
Using Map
In the page
<f:selectManyMenu value= #,bb.selectedSweetIds- /> <f:selectItems value= #,bb.sweetOptions- /> </f:selectManyMenu>
And in MB, use the toString to convert to Id Create sweetMap as in previous example
String[] selectedSweetIds; List<Sweet> selectedSweets = new ArrayList<Sweet>();
Void setselectedSweetsIndices(String [] ssi){ selectedSweets.clear(); for (int i = 0; i < ssi.length; i++) { selectedSweets.add(sweetMap.get(ssi[i]); }
Lab Assignment
Do the select many for the sweet example
1/3 of class use Map 1/3 of class use Converter 1/3 of class use index
Chapter review
How to use <h:SelectOne> or <h:SelectMany> components To standardize the <h:select> we use
EArray to represent E[] in controller selectedE variable in controller to bind to the <h:select> component EOptions variable of type List<SelectItem> to tie up with the <h:SelectItems> component
We discuss using map, converter, and integer indices to link List<Object> to <h:select> component Use <h:dataTable> to display collection
sun.xml
beans.xml Jsp or xhtml source package Java files
Deployment descriptor
Login application
Index.xhtml has name, dob, gender, email, serviceLevel and (button which requires form) Briefly introduce you to various type of UIcomponents i.e. textField, selectOneRadio, selectOneMenu, CommandButton and how they are attached to the backing bean Also illustrate various validators, convertors and error messages
Simplified UIViewTree
form
textfield
Message
SelectRadio
SelectMenu
SelectItem
itemLabel
itemValue
Validation Process
Initiated by JSF runtime processValidators() propagates down the UIViewRoot tree to each components processValidators() Each validator and convertor is invoked Any component failing validation will have its valid property set to false facesMessage will be queued in the FacesContext The messages can be displayed using Faces Messages
EL for Collection
array.index = array[index] list.index =list.get(index) or list.set(index,value) Map.key = map.get(key) or map.put(key,value)