0% found this document useful (0 votes)
137 views

Controller of MVC and Select

JSF life-cycle life-cycle is important in JSF. EL, converter, validator and other components will be discussed later. Select component is similar to HTML Select tag but at run time, they are all converted to HTML Select / options tag.

Uploaded by

Adibah Syuhadah
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
137 views

Controller of MVC and Select

JSF life-cycle life-cycle is important in JSF. EL, converter, validator and other components will be discussed later. Select component is similar to HTML Select tag but at run time, they are all converted to HTML Select / options tag.

Uploaded by

Adibah Syuhadah
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 67

03Controller of MVC and select component

Objective of this chapter


MVC Architecture Use of Select Component JSF life-cycle (incomplete yet)

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

If it is a revisit, only the UITree is updated with new information

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

JSF Select Components


Similar to HTML select tag We have seen h:inputText, h:outputText, h:commandButton and their attribute value, label and action Now we are going to use selectOneMenu, SelectOneListBox, SelectOneRadio (and SelectMany) Contain more attribute than HTML Select but at run time, they are all converted to HTML select / options tag (view source shows only html) Use Unified Expression Language (EL) (Unified means it adopts ecmascript)

EL Unified Expression Language


We have seen #{backingBean.variable.property} and JSF implements getVariable from the backing bean and if variable is an object (entity), then JSF will use getProperty of the object at apply request phase and similarly use setVariable and setProperty at update model phase

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)

SelectItem of Select Component


This is a JSF object that has two parts, label and value Label is what to be displayed and value is the value or object/objects selected Two ways to assigned SelectItem object to selectItem component
1. List the f:selectItem tag directly as follows within the select component tag <f:selectItem itemLabel=Book" itemValue=20 /> <f:selectItem itemLabel=Pencil" itemValue="2" /> 2. Get the Collection<SelectItem> or Array of SelectItem from the backing bean to be attached to the <f:selectItems > value attribute

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

Requirements of select tag


Format: <f:selectOneMenu value= #,bb.selectedSweet- /> <f:selectItems value= #,bb.sweetOptions- /> </f:selectOneMenu> In class bb, we must have a variable name selectedSweet selectItem require a collection named sweetOptions of type List<SelectItem> (or other type of collection) We also need the appropriate setter and getter

Standardization of variable naming for Select Component


To simplify our discussion, lets standardize our variable naming Let E stands for Entity EArray is the name of the variable to store an array of E ( E[] ) Controller obtain EArray using the faade findAll method selectedE is the variable used by the view to save the value chosen by user EOptions is of type List<SelectItem> to be used in <f:selectItems value =#,bb.EOptions- /> We need to convert EArray to EOptions

Converting EArray to EOptions


List<SelectItem> eOptions = new ArrayList<SelectItem>(); For (i=0;i<EArray.length();i++){ E e = EArray(i); SelectItem se= new SelectItem(e.getName(),e.getName()) eOptions.add(se); }

Converting from EArray to List<SelectItem>


As mentioned earlier, EOptions is of type List<SelectItem> We can do the above conversion in backing bean constructor (once) or in getEOptions () method First we get EArray using findAll we iterate through EArray and create a new SelectItem for each E, and add it to EOptions

Converting EList to EOptions


Iterate using get List<SelectItem> eOptions = new ArrayList<SelectItem>(); For (i=0;i<EList.size();i++){ E e = EList.get(i); SelectItem se= new SelectItem(e.getName(),e) eOptions.add(se); } Iterate using iterator List<SelectItem> eOptions = new ArrayList<SelectItem>(); for (ListIterator<E> it = EList.listIterator(); it.hasNext(); ) E e = it.next(); SelectItem se= new SelectItem(e.getName(),e) eOptions.add(se); }

Summary of Select Component Usage


1. Faade stores FindAll method which returns EArray 2. Controller convert EArray to EOptions which is of List<SelectItem> type 3. Controller prepare selectedE, EOptions together with the setter and getter 4. The faces prepare the select tag using the selectedE and eOptions variables in controller

WebApp with Two Faces Problem


In the first face we have a label, selectOneMenu and button component
Ali Abu Bakar Atan

Pick your name

Welcome Abu Bakar

OK

Student select name and click OK Welcome.xhtml will be displayed as seen

Student Controller (SC)


SC plays two roles
1. as backing bean to store the variables and actions for the two faces 2. as a controller to access the faade and
1. Store the new values into our model or 2. Retrieve the values from our model and populate components presented in the view

Inserting selectItems into SelectItem component (recall life-cycle)


Index.xhtml selectOneMenu Value = sc.selectedStudemt selectItems = sc.studentOptions sc StudentController constructor { 1 s = f.findAll(); 2 studentOptions = Convert s to List<selectItem> } getSelectedStudent setSelectedStudent getStudentOptions{ return studentOptions} Student Name,age get,set List<Student> findAll() f students Facade

3 null

4 selectItems

3.Identify the required variables


The selectOneMenu component provided by JSF can take a series of selectItem objects or a list or array of selectItem Let us name this list<SelectItem> as studentOptions Secondly, we need to store the selected Item chosen by the user in another variable Let us called this item selectedStudent The submit button does not have any value to store

Student Controller (SC)


SC needs to declare the students and selectedStudent Our studentList is a list of Student objects Need to convert each Student object into SelectItem object of of type (label , value) and add it to studentOptions list Normally label and value are different. E.g. (Shah Alam,700), (Kelang,600) for population selectItems. But In the Student application case they are the same. Finally SC has to do navigation to display the welcome page

Creating the Student Welcome Application


Start a new web application (JSF framework) Create the student entity class under model package Create the student faade class under model package Create the student controller class under the controller package Create the index and welcome pages under the web folder

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

How to create a managed bean?


In EE5, we have to create an xml file named the deployment descriptor to a create a managed bean In EE6, it is much easier, we annotate @ManagedBean before the class name If the class name is StudentController then the default managed bean name is studentController ( with small s) We can give a different name using (name = sc) format

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

Convert student array to selectItems


studentArray = sf.findAll(); for (int i = 0; i < studentList.length; i++) { SelectItem selectItem = new SelectItem(studentList[i].getName(),studentList[i].getName()); studentOptions.add(selectItem); }

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

doClick { return Welcome4.2 render 4

Welcome.xhtml
Simply use the backing bean to display the selected student name

What happens when index.xhtml is first called?


JSF Builds the UITree Value of sc.selectedStudents is populated using sc.getStudents in the backing bean (initially it is null) Value of sc.studentOtions is populated because sc has been instantiated by container, sc has instantiated sf, and sf has instantiated students Index then call getStudentOptions Once UiTree has been populated, index.xhtml is rendered

JSF Sequence Diagram


container
Instantiate sc

:sc

:sf

List: students
students

:s1

:index

constructor
sf constructor findAll()
students[]

Students.add(s1)

Convert students to List<SelectItem>

Index (prepare UiTree)


studentOptions getSelectedStudent, getStudentOptions

Populate UITree (selectedStudent=null, studentOptions)


render

How the application works? (sequence number as in diagram)


1. When index.html is rendered, selectOneMenu gets the selectItems using ___________ method of __________ 2. Once, the button is clicked, java run the _____ method in _______
a. But before the method is run, java update the selectedStudent variable of ___________ using __________ method

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

Continue - JSF Sequence Diagram


container :sc :index
Button.onclick doOK

welcome

Validate, convert, update sc variables


doOK welcome

welcome(prepare UiTree, populate vars, render)


getSelectedStudent

selectedStudent=Abu Bakar

What happens when OK is clicked?


When the okButton is clicked, JSF first do all required validations (We have one required component) getSelectedStudent is invoked, and the selectedStudent variable is populated The doClick is invoked and return Welcome string JSF calls Welcome.xhtml JSF Builds the UITree (next chapter) Value of sc.selectedStudent is populated from the backing bean Welcome.xhtml is rendered

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

Select Component Using Object


In previous example, we use String as label and String also as value String is not flexible Suppose we want to the select component to return object Then we can use object.name or object.price like other OOP Look at next example

SelectOne using Object


In the page
<f:selectOneMenu value= #,bb.selectedSweet- /> <f:selectItems value= #,bb.sweetOptions- /> </f:selectOneMenu>

And in MB
Iterate through sweets[] { SelectItem si = new SelectItem(sweets[i].name, sweets[i]); sweetOptions.add(si); }

Select One using Object


The label will appear as expected but the value is the object itself However the value bound to selectedSweet will be the string associated to the toString method of Sweet object The default value is some hashed value (some sort of unique value for each object so that ordering the object will be very fast) Remember JSF will bind this string with setSelectedSweet(Sweet s) method This will produce error because string does not match object

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 }

First Solution using Map


1. Modify the toString method of Sweet
String toString(){ return id; }

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)

setSelectedSweet(String selectedSweet){ this.selectedSweet = sweetMap.get(selectedSweet) }

Second use SweetConverter class


@FacesConverter (value=sweetConverter") public class SweetConverter implements Converter { private static SweetFacade sf = new SweetFacade(); @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { return sf.find(value); } public String getAsString(FacesContext context, UIComponent component, Object o) { return ( (Sweet) 0.toString()); //toString is already default } }

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; }

Summary Using converter


1. Modify the toString method of Sweet
String toString(){ return id; }

2. Set the sweetConverter as component Converter


<f:selectOneMenu value= #,bb.selectedSweet- /> <f:selectItems value= #,bb.sweetOptions- /> <f:converter converterId = sweetConverter /> </f:selectOneMenu>

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)

The get phase


Similarly the getAs String method will be used during the populating the UITree phase

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

Note on using converter


In jdk 1.4 we have to use deployment descriptor in our web.xml Now we only use annotation We have standard converter provided by JSF like date and time We can also build custom converter like how we build SweetConverter to cater for our need

Third method to reference selected object in select component


The third method is to use the index

Using array index


In the page
<f:selectManyMenu value= #,bb.selectedSweetIndex- /> <f:selectItems value= #,bb.sweetOptions- /> </f:selectManyMenu>

And in MB
Sweet selectedSweet;
Void setselectedSweet(int ssi){ this.selectedSweet = sweetOptions.get(ssi); }

Displaying the selected Sweets


<h1>The Choosen sweets are : </h1> <h:dataTable value=#,bb.selectedSweets- var=sweet /> <h:column> <f:facet name=header> Sweet Name </f:facet> ${sweet.name} </h:column> </h:dataTable>

Displaying the selected Sweets


<h1>The Choosen sweet is : </h1> <h:outputText value=#,bb.selectedSweet- />

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)

Using array index


In the page
<f:selectManyMenu value= #,bb.selectedSweetIndices- /> <f:selectItems value= #,bb.sweetOptions- /> </f:selectManyMenu>

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]); }

JSF framework review


It follows MVC Managedbean is managed by container EL use backingbean (managedbean) to managed all the variables JSF has a life-cycle which we will be discussed more in next chapter Everything adds up to a simpler work for programmer

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

The JSP/JSF Folder framework


Path context Project Web Pages WEB-INF web.xml

sun.xml
beans.xml Jsp or xhtml source package Java files

Deployment descriptor

JavaServer faces use xhtml files

Strength of this framework


Very modular e.g. splitting faade and entity enable many controller to access the entity in different manner, or many controller to access different facades Convention over Configuration doing it the same way simplify development and teamwork Since it is html based, it is very widely usable Enable solvability, teamwork, agility, maintainability, reusability, and together with Netbeans it also allows versioning, testing, packaging, robustness and many other ability

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)

You might also like