Controller of MVC and Select

67
03Controller of MVC and select component

Transcript of Controller of MVC and Select

Page 1: Controller of MVC and Select

03Controller of MVC and select component

Page 2: Controller of MVC and Select

Objective of this chapter

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

Page 3: 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

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

Page 4: Controller of MVC and Select

JSF life-cycle• JSF updates the UITree from MB (to be seen)• HTML Page is renderedUser 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 actionThe 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

Page 5: Controller of MVC and Select

MVC Architecture

• In MVC, our Studentsfaçade 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

Page 6: Controller of MVC and Select

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)

Page 7: Controller of MVC and Select

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

Page 8: Controller of MVC and Select

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)

Page 9: Controller of MVC and Select

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

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

Page 10: Controller of MVC and Select

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

Page 11: Controller of MVC and Select

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

Page 12: Controller of MVC and Select

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 façade 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

Page 13: Controller of MVC and Select

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

Page 14: Controller of MVC and Select

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

Page 15: Controller of MVC and Select

Converting EList to EOptions

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 get

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

Iterate using iterator

Page 16: Controller of MVC and Select

Summary of Select Component Usage

1. Façade 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

Page 17: Controller of MVC and Select

WebApp with Two Faces Problem• In the first face we have a label,

selectOneMenu and button component

Abu BakarPick your name

OK

Welcome Abu Bakar

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

Atan

Ali

Page 18: Controller of MVC and Select

Student Controller – (SC)

• SC plays two roles1. as backing bean to store the variables and

actions for the two faces2. as a controller to access the façade and

1. Store the new values into our model or 2. Retrieve the values from our model and populate

components presented in the view

Page 19: Controller of MVC and Select

Inserting selectItems into SelectItem component (recall life-cycle)

Index.xhtmlStudentController

Facade

sc.studentOptions

sc.selectedStudemt

setSelectedStudent

constructor { s = f.findAll();studentOptions = Convert s to List<selectItem>}

findAll()

Name,age

get,set

Student

students

sc

f

List<Student>

getSelectedStudent

3

selectOneMenu

Value =

selectItems =

1

4

getStudentOptions{ return studentOptions}

2

null

selectItems

Page 20: Controller of MVC and Select

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

Page 21: Controller of MVC and Select

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

Page 22: Controller of MVC and Select

Creating the Student Welcome Application

• Start a new web application (JSF framework)• Create the student entity class under model

package• Create the student façade class under model

package• Create the student controller class under the

controller package• Create the index and welcome pages under the

web folder

Page 23: Controller of MVC and Select

Managed Bean

• Student and façade 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

Page 24: Controller of MVC and Select

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

Page 25: Controller of MVC and Select

Student Controller

• studentArray is an array used to take list from the façade• This array is then converted to List<selectItems> required

by JSF. It is a list of <label,value> selectItem objects

Student[] studentArray ; String selectedStudent; List<SelectItem> studentOptions = new ArrayList<SelectItem>(); StudentFacade sf= new StudentFacade();

Page 26: Controller of MVC and Select

Convert student array to selectItems

• 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

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

Page 27: Controller of MVC and Select

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

Page 28: Controller of MVC and Select

On clickIndex.xhtml

StudentController Facade

Welcome.xhtml

sc.selectedStudent

sc.selectedStudent

setSelectedStudent

Name,age

get,set

Student

students

sc

f

doClick { return “Welcome”}

action = “#{ sc.doClick}

*

getSelectedStudent3

2

4

4.1

1

4.2 render

Page 29: Controller of MVC and Select

Welcome.xhtml

• Simply use the backing bean to display the selected student name

Page 30: Controller of MVC and Select

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

Page 31: Controller of MVC and Select

JSF Sequence Diagramcontainer :sf

List:students :s1

Instantiate sc

Populate UITree (selectedStudent=null, studentOptions)

students

sffindAll()

students[]

Index (prepare UiTree)

constructorStudents.add(s1)…

Convert students to List<SelectItem>

render

getSelectedStudent, getStudentOptions

:sc

constructor

:index

studentOptions

Page 32: Controller of MVC and Select

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

Page 33: Controller of MVC and Select

Continue - JSF Sequence Diagram container :index welcome

welcome

doOK

:sc

Validate, convert, update sc variables

doOK

selectedStudent=“Abu Bakar

welcome(prepare UiTree, populate vars, render)

getSelectedStudent

Button.onclick

Page 34: Controller of MVC and Select

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

Page 35: Controller of MVC and Select

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

Page 36: Controller of MVC and Select

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

Page 37: Controller of MVC and Select

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

Page 38: Controller of MVC and Select

SelectOne using Object

• In the page

• And in MB

<f:selectOneMenu value= “#{bb.selectedSweet} “ /> <f:selectItems value= “#{bb.sweetOptions} “ /> </f:selectOneMenu>

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

Page 39: Controller of MVC and Select

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

Page 40: Controller of MVC and Select

Problem• In the page

setSelectedSweet(String selectedSweet){ this.selectedSweet = selectedSweet; }

• And in MB

selectedSweet (type String)

sweetOptions (type Object[])

Hacks

Hudson

Milo

toString returns hash number

error

Page 41: Controller of MVC and Select

First Solution using Map

1. Modify the toString method of Sweet

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

String toString(){ return id; }

Page 42: Controller of MVC and Select

Using Map• In the page

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

• And in MB

selectedSweet (type String)

sweetOptions (type Object[])

Hacks

Hudson

Milo

toString returns id

setSelectedSweet(id)

Page 43: Controller of MVC and Select

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

Page 44: Controller of MVC and Select

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

Page 45: Controller of MVC and Select

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 façade returns

the Sweet[2]• The converter returns Sweet[2] for the

consumption of setSelectedSweet(selectedSweet)

Page 46: Controller of MVC and Select

Using Converter• In the page

setSelectedSweet(Sweet selectedSweet){ this.selectedSweet = selectedSweet; }

• And in MB

selectedSweet (type String)

sweetOptions (type String[])

Hacks

Hudson

Milo

toString returns “2”

Sweet[2]

converter

Select Milo

Page 47: Controller of MVC and Select

Summary – Using converter1. Modify the toString method of Sweet

2. Set the sweetConverter as component Converter

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)

String toString(){ return id; }

<f:selectOneMenu value= “#{bb.selectedSweet} “ /> <f:selectItems value= “#{bb.sweetOptions} “ /> <f:converter converterId = “sweetConverter “ /> </f:selectOneMenu>

Page 48: Controller of MVC and Select

The get phase

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

Page 49: Controller of MVC and Select

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

Page 50: Controller of MVC and Select

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

Page 51: Controller of MVC and Select

Third method to reference selected object in select component

• The third method is to use the index

Page 52: Controller of MVC and Select

Using array index• In the page

• And in MB

<f:selectManyMenu value= “#{bb.selectedSweetIndex} “ /> <f:selectItems value= “#{bb.sweetOptions} “ /> </f:selectManyMenu>

Sweet selectedSweet;

Void setselectedSweet(int ssi){ this.selectedSweet = sweetOptions.get(ssi); }

Page 53: Controller of MVC and Select

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>

Page 54: Controller of MVC and Select

Displaying the selected Sweets

<h1>The Choosen sweet is : </h1>

<h:outputText value=“#{bb.selectedSweet}” />

Page 55: Controller of MVC and Select

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)

Page 56: Controller of MVC and Select

Using array index• In the page

• And in MB

<f:selectManyMenu value= “#{bb.selectedSweetIndices} “ /> <f:selectItems value= “#{bb.sweetOptions} “ /> </f:selectManyMenu>

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

Page 57: Controller of MVC and Select

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

Page 58: Controller of MVC and Select

Using Map• In the page

• And in MB, use the toString to convert to Id• Create sweetMap as in previous example

<f:selectManyMenu value= “#{bb.selectedSweetIds} “ /> <f:selectItems value= “#{bb.sweetOptions} “ /> </f:selectManyMenu>

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

Page 59: Controller of MVC and Select

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

Page 60: Controller of MVC and Select

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

Page 61: Controller of MVC and Select

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

Page 62: Controller of MVC and Select

The JSP/JSF Folder frameworkPath

Project

Web Pages

web.xml

sun.xml Deployment descriptor

context

beans.xml

source

package

Java files

WEB-INF

Jsp or xhtmlJavaServer faces use xhtml files

Page 63: Controller of MVC and Select

Strength of this framework

• Very modular – e.g. splitting façade 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

Page 64: Controller of MVC and Select

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

Page 65: Controller of MVC and Select

Simplified UIViewTree

form

textfield Message SelectRadio

SelectItem

itemLabel

itemValue

SelectMenu

Page 66: Controller of MVC and Select

Validation Process

• Initiated by JSF runtime• processValidators() propagates down the UIViewRoot

tree to each component’s 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

Page 67: Controller of MVC and Select

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)