September 23, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Quick Start to Reasonable Server Faces (RSF), a Java Web Programming Framework

  • April 16, 2009
  • By Ryan Lowe
  • Send Email »
  • More Articles »

Introduction

Reasonable Server Faces (RSF) is Java open source Web framework built upon of the Spring framework. It is an extremely light weight framework that allows for pure XHTML templating and complete lifecycle handling. This article defines and demonstrates three of RSF's primary tenets: primacy of markup, zero server state, correct use of POST/GET.

RSF, unlike other Java web frameworks, places a primary emphasis on markup and the role of the web designer. The web designer is not constrained by framework generated markup nor are they she forced to design around inline code or pseudo code. Templates are pure XHTML and require no framework knowledge to create or maintain. This creates a complete separation from the presentation and Java code-behind. The web designer and the developer can work independently without needing to coordinate their efforts as you will see in the sample app.

RSF aims to create a framework with zero server context thus saving valuable server resources by throwing away the component tree at the end of every render cycle. This differs from many common Java frameworks, such as JSF, whereby the first action performed by the framework is to deserialize the incoming component tree from the previous request. Session state is thus minimized allowing for a lower utilization of server resources.

RSF aims to follow the correct and efficient browser behavior on the server by following a strict POST->GET redirect in order to keep all GET requests idempotent. In this way, POST is used solely to send data to the server, and GET is used solely to return data to the browser. This resolves many issues that other frameworks face with browser back button behavior or deep linking issues.

Recipe List Application

To demonstrate these primary goals along with RSF's core components, a very simple recipe list application will be built. The application will create a list of items by allowing users to add additional items via a web form. This easy task will showcase many features including: template construction, link behavior, simple internationalization, and form posts.

To start off the simple application, first you need to prepare the environment for RSF. RSF's wiki web site has a great guide to setting up the RSF Development Environment, and is out of the scope of this article. Once that has been completed, you can start by creating the XHTML templates used in the application. As mentioned before, these are pure XHTML templates constructed with presentation as their only concern. For this simple app, there will be two pages, so you need to create two XHTML templates:

recipelist.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns:rsf="http://ponder.org.uk/rsf" xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    <title rsf:id="msg=title">Recipe List</title> 
    <link href="../css/styles.css" type="text/css" rel="stylesheet" media="all"/>
</head> 
<body> 
    <h1 rsf:id="msg=header">Recipe List</h1>
    <ul rsf:id="message-for:*" style="margin:0px;">
        <li>Message for user here</li>
    </ul>
    <h4 rsf:id="current_count">There are currently {0} item(s).</h4>
    <ul>
        <li rsf:id="current_items:">
            <span rsf:id="row_item">An Item</span>
        </li>
    </ul>
    <a rsf:id="add_item">Add an Item</a>
</body>
</html>
    

itemForm.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns:rsf="http://ponder.org.uk/rsf" xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    <title rsf:id="msg=title">Recipe List</title> 
    <link href="../css/styles.css" type="text/css" rel="stylesheet" media="all"/>
</head> 
<body> 
    <h1 rsf:id="msg=header">Recipe List</h1>
    <ul rsf:id="message-for:*" style="margin:0px;">
        <li>Message for user here</li>
    </ul>
    <form rsf:id="form">
        <fieldset>
            <legend rsf:id="msg=form_legend">Add an Item to the List</legend>
            <ol>
                <li>
                    <label rsf:id="msg=label_item">Item:</label>
                    <input type="text" rsf:id="item" />
                </li>
            </ol>
            <div class="buttonwrap">
                <input type="submit" rsf:id="submit" value="Submit" />
            </div>
        </fieldset>
    </form>
</body>
</html>
    

As can be seen above, these are nearly completely valid XHTML documents except for the addition of one single attribute, rsf:id="". This is the only mechanism in which RSF is represented in the templates. In fact, these templates can be viewed in any web browser as-is (browsers will simply ignore the extra attribute) and can also be validated. Any text or other properties in the template in nodes that contain the rsf:id attribute will be overwritten via RSF, so templates can contain as much "dummy-data" as you wish. This can be extremely useful to allow the designer to communicate the intent of the markup structure to the developer by allowing dummy content to exist. The list of appropriate rsf:id values is the only contract that the designer and developer must maintain with each other. As long as the same ids are used in the semantically same way, the view will work.

The rsf:id tags specify an id that allows the RSF rendering engine a location to wire up its data. The use of an id with a colon (:) is a special convention that tells the rendering engine that this XHTML node (and its children) may be repeated. To support internationalization another special tag convention is used to pull text directly out of a standard Java properties bundle. This allows the developer to directly wire an rsf:id to a properties bundle key by simply specifying a special rsf:id="msg=property_key". For this application, all of the page text has been pulled into the following property bundle:

messages.properties

title = Recipe List
header = Recipe List
form_legend = Add an Item to the List
label_item = Item:
current_items_count = There are currently {0} item(s).
    

Once you have a templates in place, you must create a Component Producer for each template. A component producer in RSF is the mechanism in which the component tree in Java is built. Each producer implements the ViewComponentProducer interface and has a corresponding ViewID, which should match the filename of the template. The overridden method fillComponents is where the component tree is built to match the rsf:ids in the template. The parameter UIContainer tofill acts as a parent element of the component tree where all of the components will be added. The producer to build the component tree for the recipe list items is below:

RecipeListProducer

...
public class RecipeListProducer implements ViewComponentProducer, DefaultView {
    public static String VIEW_ID = "recipelist";
    public String getViewID() {
        return VIEW_ID;
    }
    
    private RecipeListService service;
    public void setService(RecipeListService service) {
        this.service = service;
    }
    
    public void fillComponents(UIContainer tofill, ViewParameters viewparams,
            ComponentChecker checker) {
        
        //Build Recipe List
        List<String> items = service.getItems();
        UIMessage.make(tofill, "current_count", "current_items_count", new Object[] {items.size()});
        for (String item : items){
            //Create a new <li> element
            UIBranchContainer row = UIBranchContainer.make(tofill, "current_items:");
            UIOutput.make(row, "row_item", item);
        }
        
        //Create Link to Add Item Form
        UIInternalLink.make(tofill, "add_item", new SimpleViewParameters(ItemFormProducer.VIEW_ID));
    }
}

With this producer, a few key concepts are introduced as well as a few of RSF's built in components. The RecipeListService above simply returns a list of strings that represent each item of the recipe list. Previously, it was shown that the message bundle text for internationalization can be utilized directly by the template. If, however, you need to do more than just output static text, you have the option of using RSF's UIMessage component that will perform the bundle lookup. Here, after retrieving the list of recipe items from the service, you want to display the total count of items using the message bundle with key "current_items_count". Using the UIMessage component, you look up the bundle string "current_items_count", format the text adding in the items.size() into a placeholder, and attach that to the DOM node with the rsf:id="current_count".





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel