Apr 04, 2018
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.