November 21, 2014
Hot Topics:

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

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

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





Page 2 of 2



Comment and Contribute

 


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

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel