meljun cortes jedi coursenotes web programming lesson9 javaserver faces
TRANSCRIPT
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
1/18
MVC Frameworks II JavaServer Faces
In the previous chapters, we have looked at Struts, an open-source framework for webapplications implementing the Model 2 Architecture. Let us now take a look at anotherframework: Java Server Faces (JSF).
Introduction to JSF
JSF is a framework for building user interfaces for web applications. It builds on conceptsintroduced by the Struts framework and brings together the benefits of an architecturethat cleanly separates presentation from business logic and a standard component-based
user interface set similar in many ways to that of Swing widgets.
Below is a figure detailing how the Faces framework works.
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
2/18
As we can see, JSF also has a clean separation between the components for the Model,
View, and Controller layers. Like Struts, JSF has a front controller servlet, calledFacesServlet, that is responsible for receiving requests from clients and then performingthe appropriate actions needed as dictated by the framework. Another similarity between
Struts and JSF is that they both make use of action handlers separate from the frontcontroller servlet, although, Faces handles this a bit differently as compared to Struts.
Faces and Struts similarity ends with regard to the View layer. Here, Struts only providesonly a set of tag libraries that added on top of standard HTML functionality. Faces, on theother hand, provides its own set of interface components, along with a set of taglibraries to express these components as tags and a rendering component that translatesthe UI components into HTML.
Figure 1: JavaServerFaces Framework (image from Mastering JavaServerFaces, Wiley Publishing)
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
3/18
Let us go into the different aspects of Faces.
CONTROLLER
The controller layer of Faces is made up of the controller servlet (FacesServlet), a set of
XML configuration files, and a set of action handlers.
. FacesServlet
FacesServlet is responsible for accepting requests from the client and performingoperations needed to produce the response. These operations include preparing the UI
components required for the request, updating the state of the components, calling therequired action handlers (if any), and rendering the UI components that are part of the
response.
FacesServlet is provided to us by the JSF framework, and only requires configuration inan application's deployment descriptor before it is ready for use.
Below is a snippet that shows us how to configure FacesServlet for our application.
...
FacesServletjavax.faces.webapp.FacesServlet1
...
FacesServlet
*.jsf
...
. Action Handlers
It was been mentioned earlier that Faces makes use of action handlers independent fromthe front controller servlet, similar to Struts. Faces performs this function differentlythough.
In Faces, there are two possible ways of creating an action handler. One is by binding amethod of a JavaBean to serve as the action handler. Another is by creating an instanceof a class implementing the ActionListener interface.
Application method
A method that has been bound to a UI component to serve as its action handler is calledan application method. Later, in the View section, we will see how this binding is done.
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
4/18
Meantime, there are some rules required for creating an application method:
The method must be declared public.
The method must take no parameters. The return type of the method must be a String.
Below is a method that we could possibly use for handling an event resulting from a userattempting to login.
...public String performLogin() {
// forward user to failure use case if loginName is emptyif (loginName == null || loginName.length() < 1) {return "failure"
}
User user = null;
// create business object that will handle actual authorization checkUserService service = new UserService();user = service.login(loginName, password);
// forward user to failure use case if user is not authorizedif (user == null) {
return "failure";}
// retrieve an instance of the FacesContext object// that will give us access to other contexts
FacesContext ctx = FacesContext.getCurrentInstance();
// place the result into session scope for use by other components
Map sessionMap = ctx.getExternalContext().getSessionMap();sessionMap.put(ApplicationConstants.USER_OBJECT, user);
// since user has successfully completed login, forward to success
return "success";}}...
One of the advantages of this type of action handling is that it lessens the number of
objects that developers need to maintain. This method can be in any JavaBeanrecognized by the framework, though commonly, it can be found in the bean used as
backing modelfor a particular form page. (More on backing models later).
The String returned by the method informs the FacesServlet which view will next beseen by the user. The Strings are logical names, sometimes called outcomes. Theseoutcomes are matched against navigation rules defined in the configuration file.
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
5/18
WORKING WITH SESSION SCOPE OBJECTS IN FACES
The JSF framework has a different method of accessing session scope compared towhatever we have seen before. Previous examples we have seen so far have retrievedinstances of the HttpSession object in order to work with session scope. For example, inStruts, we retrieve it using the HttpServletRequest object passed in as a parameter to
its execute method.
Since application methods are defined such that they do not take in any parameters, wedo NOT have any valid instances of the HttpServletRequest object from which toretrieve an HttpSession object. JSF goes around this limitation by providing access tothe session context (as well as other contexts) with the use of a FacesContext object.
Our earlier example used this method to save an object into session scope. The relevant
code is reproduced below:
FacesContext ctx = FacesContext.getCurrentInstance();
...
Map sessionMap = ctx.getExternalContext().getSessionMap();sessionMap.put(ApplicationConstants.USER_OBJECT, user);
As we can see from the example, obtaining a valid instance of the FacesContext objectis simple. Just call a static method from the FacesContext class. A Map representing
objects placed in session scope can then be retrieved by calling on.
There are other scopes that can be accessed. For more information, check out theJavaDoc entry for the FacesContext object.
ActionListener
The other way of implementing an action handler in JSF is to create a class implementingthe ActionListener interface. This interface defines a single method:
public void processAction(ActionEvent event)
The ActionEvent object passed as a parameter in the method provides the implementingclass access to the component that caused the event. This is similar in a way to how
Event objects work in Swing programming.
Below is an example of an ActionListener implementation used for logging user actions.
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
6/18
public class PerformedActionListener implements ActionListener {public void processAction(ActionEvent event) {
// retrieve the component that fired the eventUICommand component = (UICommand)event.getComponent();
// retrieve the name of the button or link
String commandName = (String)component.getValue();// create the business object performing functionalityLoggingService service = new LoggingService();
// perform logging operationservice.logUserAction(commandName);}}
Most of the time, it is more appropriate to use application methods to serve as actionhandlers. For one, they can be located in the same class which serves as the backingmodelof a form, and thus have easier access to user-provided data. Second, being inthe backing model allows the developer to group together the data and the methods thatoperate on it in one class, making it easier to maintain. Third, application methods areable to return "outcomes" which inform the FacesServlet the next view to display.ActionListeners cannot, and so can only bring the user back to the original page after
handling the event.
ActionListeners are the more appropriate choice though, if you want to refactor commonfunctionality that you can reuse across multiple action sources.
As we can see later, it is possible to have an application method and one or moreActionListeners to act as handlers for a particular action. It is then possible to gain thebest aspects of both approaches: have an application method to perform handlingspecific to the action, and then have ActionListeners to perform general-purposefunctionality.
. faces-config.xml
This serves as the primary configuration file for the controller layer of the JSF
Framework. As opposed to its counterpart in the Struts framework, it does NOT containany configuration entries for its action handlers. It does contain configuration entries fornavigation rules, as well as for JavaBeans that will be recognized by the framework.
Below is a complete sample of such configuration file, for an imaginary applicationimplementing the login use case.
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
7/18
This bean serves as the backing model for our login formloginPagesample.LoginPageBeanrequest
The property that will store the user's login nameloginName
The property that will store the user's password
password
/login.jsfAny failure result should bring the user to an error pagefailure
/error.jsp
Successful login should bring user to welcome pagesuccess/welcome.jsp
Let's go through the above elements one at a time.
http://java.sun.com/dtd/web-facesconfig_1_0.dtdhttp://java.sun.com/dtd/web-facesconfig_1_0.dtd -
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
8/18
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
9/18
For one time setup:
Configure the FacesServlet for use in your application.
For each web page containing JSF UI Components:
Create a configuration entry for the managed bean that will serve as the page's
backing model. Create navigation rules which define where application could possibly go next
after the page.
MODEL
In Faces it is required to have classes that will store the state of the UI components in
each of the pages. These classes are called the backing model.
These classes are not Model classes when viewed strictly under the perspective of theMVC architecture. MVC defines the Model to be the set of classes that implement thecore business logic of the application. However, when thinking only of UI components, itmakes sense to call these classes part of the Model, especially if we are to compare it tothe MVC implementation of Swing UI component classes. Remember, in Swing, therendering layer is called the View, the component's state is the Model, and the action
handler part is the Controller.
Even though they are called part of the Model, care must be taken in the development ofthese classes such that they do not influence the core functionality of your application
(the real Model). It is best to keep in mind that these components are meant to savestate for UI components and perhaps define basic operations that access the data itstores which can serve as application methods. They are NOT meant to perform heavy-duty processing, or any processing that can be reused in other applications.
Creating a backing model for pages containing JSF UI components is very easy. It is as
simple as creating a JavaBean with properties corresponding to each component in thepage. They are very similar to ActionForm objects in the Struts framework, with the
exception that they do not need to extend any base class provided by the framework.
Below is an example of a backing model for a login form.
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
10/18
public class LoginPageBean {private String loginName;private String password;
public String getLoginName() {return loginName;
}
public void setLoginName(String loginName) {this.loginName = loginName;}
public String getPassword() {return password;
}
public void setPassword(String password) {this.password = password;
}}
This model can then be accessed by our pages after it has been configured properly in
the faces-config.xml configuration file. The configuration entry for this bean is replicatedbelow for reference.
This bean serves as the backing model for our login form
loginPage
sample.LoginPageBeanrequest
The property that will store the user's login nameloginName
The property that will store the user's password
password
VIEW
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
11/18
The View is undoubtedly the layer where JSF mostly makes its mark. In this layer, JSFnot only provides us with custom tags we can use to display our interface using JSPs, italso provides us with a component set and a standardized API for accessing and
manipulating them.
Discussion of JSF components can be very complicated if we try to explain everything atthe same time. Instead, we will have to deal with the basics first, incorporating morecomplicated ideas as we go on.
JSF-JSP Integration
Let's start with how to display JSF components to the user. The following is a listing for aJSP page containing JSF components which serves as the login page for our previousexamples:
Login Page
Please login with your login name and password :
To make use of JSF components in our JSP pages, we need to include two tag libraries:core and html. The core tag library defines core functionality, such as how to managethe JSF components that they may be able to save state, etc. The html library definestags that tells the browser how to render our JSF components into their HTMLequivalents.
Once we have included these two tag libraries, we make use of the custom tags thatthey define. Let us look at the tags we have used in the preceding example:
mailto:%25@taglibhttp://java.sun.com/jsf/core/mailto:%25@taglibhttp://java.sun.com/jsf/core/mailto:%25@taglibhttp://java.sun.com/jsf/core/mailto:%25@taglibhttp://java.sun.com/jsf/core/ -
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
12/18
- defined in the core library. All tags defining JSF components must beenlosed within this tag. This tag provides a place for JSF implementations to be
able to save the state of our UI components. REMEMBER: no , no savedstate for our components.
- defined in the html library. Renders a form in HTML.
- defines a label component that is associated with another JSFcomponent. The component it is associated with is indicated by the value in the
for attribute while the value it displays as its label is the output of the field enclosed within it.
- simply renders the text within its value attribute into its HTMLequivalent.
- renders an HTML input element of type text. - renders an HTML input element of type password. - renders an HTML button which defaults to SUBMIT.
Below is a screenshot of the output resulting from the above JSP page.
The following is the HTML source of the output:
Figure 2: Login page
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
13/18
Login Page
Please login with your login name and password :
Login Name:
Password :
Figure 3: HTML source of the login page
We can see from the above HTML listing how the JSF implementation renders ourcomponents as defined in the tags. The form element is defined to use the POST methodof form submission, with the action pointing to the same page. Also, notice how the idvalues of the HTML elements are prefixed with the name of the form. This ensures thatthe name of the form elements are unique within the application, which is necessary forFaces operation.
VALUE BINDING
The UI components making up the view above require a backing model to be able tostore the data that users would pass into them. The implementation of these backingmodels have been discussed previously. The only question now is how to link our
components to the backing model.
A snippet of the above JSP will be recreated here for easier recall.
...
... -
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
14/18
Take note of the text presented in bold font. The # notation that serves as the value forthe value attribute binds the properties in our LoginPageBean to our UI components,
with our inputText component being bound to the loginName property and theinputSecret component being bound to the password property. In this case, loginPagerefers to an instance of a LoginPageBean that will store the data.
The JSF page is able to associate the loginPage identifier to an instance of a
LoginPageBean due to our entry in the faces-config.xml. The relevant entry is presentedbelow:
This bean serves as the backing model for our login form
loginPagejedi.sample.LoginPageBeanrequest
...
Since the LoginPageBean is declared to be a managed bean in the framework, an
instance of LoginPageBean will be created and placed in the configured scope (if onedoesn't already exist) when the JSF page is evaluated. On page submission, the values
that the user has entered would automatically be placed within the bean's properties.
REGISTERING ACTION HANDLERS TO VIEW COMPONENTS
JSF introduces the concept of event-based programming into the web environment.
Some of the UI components that JSF provides will, given the appropriate user action orinput, generate events that can be processed by action handlers.
In our example above, we have a JSF component: the element.Whenever the user clicks on the button that this component represents, an event isgenerated within the framework which can be processed by registered handlers.
This concept may be better understood if related to another event-based programming
model: Swing. In Swing, if we want to perform some processing whenever the usermakes a button click, we register with the button one or more ActionListeners that
implement the required functionality. Same thing with JSF, if we want to perform somefunctionality on a button click, we register an action handler with the commandButtoncomponent.
The way we do this "registering" of a handler for a commandButton component is shownbelow:
...
...
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
15/18
We find a # notation similar to that used in binding a bean property to a UI component.The intention here is similar as well: we are binding a method named performLoginfound in a bean referenced with the name loginPage to our button. This time, instead of
storing the value for the component, the bound method acts as the action handler forthe button click.
PAGE NAVIGATION
JSF determines the next screen that will be displayed to the user upon form submissionusing the return value of the method that serves as the action handler for the submitbutton. The String value is looked up against navigation rules defined within the
configuration file.
The relevant entries in the configuration file are reproduced below:
/login.jsf
Any failure result should bring the user to an error pagefailure/error.jsp
Successful login should bring user to welcome page
success/welcome.jsp
So, coming in from our JSF page (login.jsf), if the performLogin method were to return avalue or outcome of "failure", the user will be redirected to error.jsp.
As an alternative to using an action handler, it is also possible to statically provide thenavigation rule to be called:
......
Clicking on this button will redirect the user to error.jsp without having to perform anyprocessing.
Other JSF Component tags
There are a lot of other tags available within the JSF framework aside from the tags thatwe have used in our previous example and tags used to render HTML components. Here
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
16/18
are a couple of samples:
This tag acts in a way similar to that of the tag in the Strutsframework. This tag exposes messages from the application into the output text. Forexample, if an input control was to report an internal problem, possibly due to avalidation error (validation is covered in the next chapter), it can be displayed using thistag.
This tag displays an HTML element. What makes this tag useful is that ittakes in an array (or collection of objects) and iterates over them, automatically creatingthe necessary and elements. It defines a child tag named .Content placed inside the body of a tag form the template for the columndefinition for each row in the table.
Take the following example:
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
17/18
collection or array being iterated over. This variable is visible only within the tag. Once outside the tag's body, this variable can no longer beaccessed.
border, cellspacing - standard HTML table attributes. The values placed withinthese attributes will be carried over to the generated table tag.
rowClasses - a comma-delimited list of cascading style sheets(CSS) styles thatwill be alternately applied to each of the rows in the table.
Container tags like only allow JSF tags within their body. This means
that custom tags or even JSTL tags would not work inside of them. This can becircumvented with the use of the tag.
EXERCISES
As an exercise in the use of the Java Server Faces framework, we will be creating avery simple application. Unlike the previous Struts exercise, this is small enough that it
can be accomplished solo.
Consider the following scenario:
A small firm wants to be able to keep track of the comings and goings of its employees.To do this, it decides that it needs a web-based application that can record theiractivities. They want it to be very transparent as well, meaning that the records shouldbe visible to everyone.
Eventually, they came up with the following page concept:
Basically, the main page of the application consists of an input text field and submit
button in the upper left field, with a table of records dominating the rest of the page.
Sample Use Case Scenario 1:Employee A arrives at the office. He enters his employee number in the text field andclicks on the submit button. A new row is added to the top of the table, containing hisname, the keyword 'IN', as well as the timestamp of input submission.
Sample Use Case Scenario 2:
Employee B arrives at the office and tries to enter his employee number in the samemanner as Employee A. However, he became distracted and accidentally made a
mistake in his entry. The application takes him to another page informing him that theid he entered was not valid. It also presents a link so that he could return to the main
page and try to correct his mistake.
Sample Use Case Scenario 3:Employee A is leaving the office for lunch. He needs to record this as well, so he entershis ID number again. The application recognizes that his previous entry was an 'IN'.When the app inserts a new row at the table, it again shows his name and the
timestamp of submission, but this time displays 'OUT'.
Create the application described by the use case scenario and page concept describedabove.
-
7/31/2019 MELJUN CORTES JEDI CourseNotes Web Programming Lesson9 JavaServer Faces
18/18