Tutorial web development (with JSF) VIII: Backstage

In a traditional application, usually the application itself is responsible for the presentation. Even if you should use a special display sever such as X, it is still controlled by the application.

Unlike in a web application. Here the data is passed to a browser, which takes care of the presentation. To do such, the server packs the content to display into in a (X) HTML document. In addition, the server may provide some layout information in the form of cascading style sheets (CSS). Then, everything else is up to the browser. And just as there are different browsers, the representation can be different. The continuous development of standards ensures here fortunately a gradual convergence. But, if the user keeps a local CSS here, then the presentation again might be different.

Not only, that a Web application delegates the output to a client side browser, it normaly does not become active itself! Only when the user via the browser requests a page, the application becomes active, performs some operations and delivers a such. The (apparently) active change of content due to sever side processing is not possible without additional aids. Here is the keyword AJAX (Asynchronous JavaScript and XML). Beside (X) HTML and CSS we have touched another browser-side technology: JavaScript. The browser requests some data in between using JavaScript and exchanges parts of the browser content. This is done via partial request. This kind of magic gives the impression, the server updates the screen. Sure enough, it is erverytime a request from the client side (pull). A real push, which means that the server active changes the representation requires a deeper grip in the bag of tricks: The response to the client is artificially delayed in order to transmit more in information later on, when new info arises on server side. But this is something for a later part of this tutorial.

In a traditional application, the program can respond immediately to a user input. In a web application, the program only detects user input when a new page or (usually in conjunction with AJAX) partial new page is requested. By this time, entries already can be made in various fields. Not hard to imagine, that the application has to handle this in a different way. At this point, JSF supports the programmer and raises corresponding events on the server for each entry, so that the programming model is not entirely different to the one developers often use.

     

And yet another difference: A web application usually runs in an execution environment, which provides a number of services. Such a runtime environment is denoted as container. In the case of JSF it is a so-called servlet container. This points to the underlying technology of the servlets. Even in the development with JSF, the direct use of servlets might be appropriate sometimes. So, it can’t hurt if you familiarize yourself with this technique. But this is out of scope of this lesson.

The servlet container provides the application with interfaces to other services. It is part of an application or web server. Many servers principally comprise a container and then the container and application server concepts often used interchangeably. In fact, a server can host multiple containers. For example, GlassFish, does not host only a servlet container only, but an EJB container too. In the following, we first look from the outside to the application server.

Now, when a user wants to use the web application, in his browser he calls the application URL. The client makes a request to the server. This recognizes, depending on that URL, that it must not simply deliver a static page. So the server forwards the request over the container to the application, here the JSF servlet and the user code. There, it is processed. The output is generated as (X) HTML document and sent to the browser, where it is displayed.

     

From this perspective, we consider the application server as a black box. It is interesting also what happens inside of it. Recall briefly the previous applications: Here you have defined a JSF page. Facelets were used as the page language. Beside HTML, every page contained some JSF specific tags, such as “f: InputText”. Within the browser, we specified the URL of such a page. Either directly or indirectly as a specification of the application URL, but referring internally a specific page.

The server determines the page to be rendered based on the URL, parses its contents and resolves the tags. In the simplest case, these are replaced by appropriate data. The resulting page is sent to the browser. This is only half of the truth. The browser indeed could have displayed data of the application before. Therefore JSF checks first if there is already a session. If so, the component tree, the logical representation to the view model, is restored. Entries are validated and the data model is updated. In total, JSF has six different phases for the one denoted “2. Processing” in the image above. So let’s dig a bit deeper and take a look inside processing.

The picture above shows these six main phases and in between some smaller boxes indicating an event processing. The blue arrows show the sequential proceccing, which indicates the normal flow. It might differ for a new page or in case of exceptions or programmatic fork (magenta arrows).

When the client sends a request to the server, the server uses a pattern matching to decide how to proceed. Remember part II, where I suggested to set this pattern to “*.xhtml”

The picture above repeats this setting by the example of NetBeans. Thus, if not overwritten for special usage (e.g. upload page), all URLs ending with the extension of .xhtml are directed to the JSF servlet. You may change this pattern within the web.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
  xmlns="http://java.sun.com/xml/ns/javaee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>calculator.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Let’s assume, the calculator page is requested for the first time. Processing calculator.xhtml, JSF builds up the component tree. This tree is compound by the outer html tag and it’s nested tags from the various JSF libraries. In a former lesson (part III), it seemed to be no difference between <head> and <h:head>. Both had been rendered to <head>. But the first one is not included into the component tree, whilst the later one is. I suggested allways to use this <h:head> (and <h:body> as well). In lesson IV, I showed an exampled where it had been needed. And I hope, the reason why became clear now: Only a valid JSF tag will be added to the component tree and can be processed further on.

The first phase is called “Restore View”. In fact, it restores a view only within an existing context. When a page is called for the first time, there is no tree to be restored. Thus, it will be created. Since no incoming values exist, no apply, validation etc. is needed. Lifecycle follows the magenta arrow directly to render response. This phase will render the response. Even though you may use a different renderer, the default is a HTML renderer, which creates a valid HTML page and delivers it to the client.

Since the component tree is created from scratch, you may expect only empty values to be displayed. In the eample of TinyCalculator, both parameters are displayed with a value of “0″.  Remember the binding:

<h:inputText id="param1" value="#{calculatorBean.param1}" required="true"/>

By this binding, the value is provided by CalulatorBean, getParam1. And this delivers the default value, which is “0″. If you initialize param1 of your bean to a different value, this would be used.

Let’s asume the user enters some values for the parameters and clicks onto the “add” button. Now the same page is requested, or more precise, send via a post. In terms of JSF, this usually is called a “postback”. Now the server finds an existing component tree and is able to restore this. Subsequently the “Apply Request Values” phase is processed. What will happen, if you enter an invalid string? To examine this in detail, we’ll add a simple dump:

Insert this code onto the h:head section of calculaterTemplate.xhtml

 <f:metadata>
    <f:phaseListener id="phaseListener" type="calculator.LifeCycleListener"/>
</f:metadata>

This will register a listener, where we add our code to examine what happens.

Next, create a new Java class. With NetBeans this might be done by a secondary mouse-click onto the calculator package and selecting New->Java Class…

Give this new class the name of “LifeCycleListener.java” and enter the following code (Ok, it’s for demonstration only, without comments and some parts repeated. This is no tutorial for perfect code. Feel free to refactor. ;-))

package calculator;

import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

public class LifeCycleListener implements PhaseListener {

    private final boolean _isVerbose = false;

    @Override
    public void beforePhase(PhaseEvent event) {
        FacesContext context = event.getFacesContext();
        UIViewRoot root = context.getViewRoot();
        Helper.print("LifeCycleListener for " + root.getViewId() + " before Phase " + event.getPhaseId());
        if (_isVerbose) {
            Helper.printComponent(root, 0);
            Helper.print("LifeCycleListener after dump");
        }
    }

    @Override
    public void afterPhase(PhaseEvent event) {
        FacesContext context = event.getFacesContext();
        UIViewRoot root = context.getViewRoot();
        Helper.print("LifeCycleListener for " + root.getViewId() + "  after Phase " + event.getPhaseId());
        if (_isVerbose || event.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES) {
            Helper.printComponent(root, 0);
            Helper.print("LifeCycleListener after dump");
        }
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.ANY_PHASE;
    }
}

Take a look at _isVerbose. Setting this to true will create a huge output. Try it, if you want to examine more details. For this tutorial, the state after the “Apply Request Values” (compare bold face code) is the most important. And here is the Helper needed:

package calculator;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;

public class Helper {

    private static final Logger _logger = Logger.getLogger("Helper");

    /**
     * Dumps the whole component tree, beginning with the parameter component,
     * to the log
     * "Quick'n'dirty" code, for demonstration of component tree only
     * @param component
     * @param level
     */
    public static void printComponent(UIComponent component, int level) {
        String msg = "Id: " + component.getClientId() + " Class: " + component.getClass().getSimpleName();
        if (component instanceof UIInput) {
            UIInput input = (UIInput) component;
            msg += " Value: " + input.getValue() + " submitted value: " + input.getSubmittedValue();
        }
        print(msg, level);
        if (component.getChildren().size() > 0) {
            print("Children: " + component.getChildren().size(), level);
        }
        for (UIComponent child : component.getChildren()) {
            printComponent(child, level + 1);
        }
    }

    public static void print(String text) {
        print(text, 0);
    }

    public static void print(String text, int level) {
        String prefix = "";
        for (int i = 0; i < level; i++) {
            prefix += "  ";
        }
        _logger.log(Level.INFO, prefix + text);
    }
}

Now run the calculator and enter a string for one parameter. Click onto add. You’ll get a message indicating the parameter must be a number. No result is displayed. In the log, a dump of the component tree is available. For the invalid parameter there is a line such as below recorded:

[#|2012-12-30T22:39:04.217+0100|INFO|glassfish3.1.2|Helper|_ThreadID=102;_ThreadName=Thread-2;|      
Id: calculator:param2 Class: HtmlInputText Value: 0 submitted value: abc|#]

The value of the component is still “0″, whilst the submitted value is “abc” (or whatever you entered). What happened during Apply Request Values? JSF matched all incoming values to the submittedValues of the corresponding components of the tree. The Value still stays “0″, regardless whether the incoming value is valid or not. Internally accessing Value will perform a get of the bound property, which is still unchanged at this time.

Next phase is “Process Validation” (I’ll skip the “Proces Event” box for now). JSF tries to convert the incoming value to the type of the binding property. In case of our TinyCalculator the string representation is converted into an Integer. In case of error, a ConverterException is thrown.

Next, this value is validated. For example, the value range might be restricted from -100 to 100. Then every value out of this range will be treated as invalid and a ValidatorException be thrown.

All these failueres will be collected. In the “Process events” (this applies to all of them) they will be processed. In case of at least one exception the flow normaly is immediatly directed to “Render Response”. Watch this in the recorded log:

[#|2012-12-30T22:39:04.309+0100|INFO|glassfish3.1.2|Helper|_ThreadID=102;_ThreadName=Thread-2;|
LifeCycleListener for /calculator.xhtml  after Phase PROCESS_VALIDATIONS 3|#]

[#|2012-12-30T22:39:04.317+0100|INFO|glassfish3.1.2|Helper|_ThreadID=102;_ThreadName=Thread-2;|
LifeCycleListener for /calculator.xhtml before Phase RENDER_RESPONSE 6|#]

RENDER_RESPONSE follows immediatly after PROCESS_VALIDATIONS. The same page will be displayed, together with some messages (as the one discussed above). Or, depending on the programmers code, the response is set to complete, which “terminates” further processing without a Render Response phase. These two different flows are indicated by the magenta double arrows.

Conversion and validation are usually performed during “Processes Validations”. But, if the component is set to immediate=”true”, these actions will be performed during the prior phase.

If conversion and validation processed successfully, then the model gets updated. All incoming values will be transferred to the bounded properties. Next, within “Invoke Application” all listeners and actions are processed. That is, where your program code takes action. If everything is ok, the output will be rendered and send to the client.

Enough for this lesson. It provided you an overview of the JSF lifecycle.

 

To web development content.

 

This entry was posted in NetBeans, Tutorial, Web development and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>