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

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

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

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

The next step is to display each item from the service. As mentioned before, you use the colon notation when creating the rsf:id attribute to designate that the element is to be repeated in the DOM. In the template, you want to repeat an <li> element for every item on the recipe list. To do this, give the element in the template the rsf_id=”current_items:” (note the last colon). Here is another note on the separation of presentation here. The component tree being built in Java is not concerned at all with what markup tag is used; it only knows that the DOM element is to be repeated. A <p> could easily be used instead of an <li> by the discretion of the designer. To create the matching component tree item, you create a UIBranchContainer component. This component instructs the rendering engine which items in the DOM can be “branched” allowing for looping to take place. A new UIBranchContainer needs to be created for each iteration of the loop to tell the component tree how many of these <li> DOM nodes you need to create.


Once you have the branched <li>, you need to output the text of the item. Using the UIBranchContainer row as a parent, you use UIOutput to output the recipe list item’s text into the DOM element with the rsf_id=”row_item”. By setting the parent to the UIBranchContainer, you cause the rsf_id=”row_item” element to be rendered as a child of the rsf_id=”row_item:” element.


The final step in the producer is to create an internal link to the itemform.html page. All links are managed internally by RSF. To create this link, attach to the component tree a UIInternalLink component to the rsf_id=”add_item” of the template. Since you are not passing data in the form of GET parameters, you can utilize RSF’s SimpleViewParameters. However, creating custom ViewParameters is certainly available to pass any data you wish, but is out of the scope of this application.


The next producer you create will build the component tree to handle the form that allows recipe items to be added to the list:


ItemFormProducer.java


public class ItemFormProducer
implements ViewComponentProducer, NavigationCaseReporter {
public static String VIEW_ID = “itemForm”;
public String getViewID() {
return VIEW_ID;
}
public void fillComponents(UIContainer tofill, ViewParameters viewparams,
ComponentChecker checker) {
//Build Form
UIForm form = UIForm.make(tofill, “form”);
UIInput.make(form, “item”, “${RecipeListBean.item}”);
UICommand.make(form, “submit”, “#{RecipeListBean.processActionSubmit}”);
}
public List<NavigationCase> reportNavigationCases() {
List<NavigationCase> nav = new ArrayList<NavigationCase>();
nav.add(new NavigationCase(“success”,
new SimpleViewParameters(RecipeListProducer.VIEW_ID)));
return nav;
}
}

This simple producer builds out the form elements and binding needed to handle a successful POST. First, use the RSF component UIForm to add a form component to the component tree using the same rsf_id=”form” from the template. Next, add a component, UIInput, to the UIForm element that allows input from the user to be received. The submit button is built using the UICommand component similarly. Both the UIInput and UICommand components take a third String parameter that creates a value binding. This is the formation of RSF’s Expression Language. Simpler than the similar EL in JSF, RSF’s EL specifies only a simple bean path. In this way, when the submit button is pressed, the value in the UIInput gets delivered to “item” property of the RecipeListBean directly before a call is made to RecipeListBean.processActionSubmit() as defined by the UICommand value binding.


The last piece of this producer is the implementation of the NavigationCaseReporter interface. Remember that RSF follows every POST submission with a redirect GET. By default, the GET request that follows is that of the same view that they came from. To redirect the user to a different location, RSF’s NavigationCases can be utilized. Navigation cases were inspired by JSF’s similarily named functionality and allow for simple flows from POST submissions. In the form, you want to be redirected to the list of recipe items after successfully adding an item to the list. The NavigationCase tells RSF that when the POST bound method, RecipeListBean.processActionSubmit, returns the String “success” that the GET redirect should go back to RecipeListProducer. RSF also allows for other more advanaced ways of creating flow beyond this simple method.


RecipeListBean.java


public class RecipeListBean {

private RecipeListService service;
private String item;

public String processActionSubmit(){
if (item != null && item.length() > 0) {

service.addRecipe(item);

//Return string for NavigationCase
return “success”;
}else{
return “failure”;
}
}

… Getters and Setters Omitted…


The final steps including adding eans into Spring definitions as defined in web.xml. This follows the simple Spring framework of inversion of control methodology and are rather straight-forward. All of these configurations as well as the full source code are provided for reference. Though this app is simple and trivial, it should highlight a few of the core components of RSF.


Source Files


Download the source files: RecipeListCode.zip


About the Author


Ryan Lowe is a staff member with Crowe Horwath LLP in the Indianapolis office. He can be reached at ryan.lowe@crowehorwath.com


Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories