Ajaxify a Spring MVC Application

Spring is one of the most popular of the many open source MVC and application frameworks. This example page shows how to ajaxify a Spring application using Backbase Enterprise Ajax.

Prerequisites and Intended Audience

Software

To deploy the example page, the following software is required:

  • Java SE 5
  • Tomcat 5.5

Note: The Spring libraries are bundled with the example page WAR.

Competencies

Experience to the indicated level is required with the following technologies:

  • Beginner Java
  • Beginner Spring Framework
  • Beginner Backbase Client Framework

Overview

The Forms Application is bundled with the Spring Framework distribution. The application is located in the samples folder of the distribution.

The Forms Application showcases the new form tag library introduced in Spring 2.0. The web application is simplistic, because the intent is to convey the essence of the new form tags themselves and nothing else. The application consists of three pages: list, about, and form. The about and list pages have no special logic, and the application mainly relies on the form page.

The application is designed to display personal details to the user, which can then be edited. When the application is deployed, three sections are visible:

  • A navigation menu at the top of the page;
  • A feature menu that provides a list of characters and links to the other pages;
  • The content area that contains character details or page content if clicked.

The objective of this examples page is to create an ajaxified version of the Forms Application. This examples page demonstrates several use cases that Backbase has extended from the existing Forms Application, namely:

  • application based on the SPI model;
  • client-side form validations over server-side validations;
  • panelSet structure with splitters;
  • tooltips within the form elements;
  • SMIL animations;
  • KeyDown event handled for the firstName field;
  • custom behaviors;
  • JSP source appears in a window.

Backbase and Ajaxification

AJAX provides a way to load information in a web page without having to reload the whole page. Ajaxification is the process of adding AJAX features and functionalities to a web application.

The Backbase Client Framework is the answer to all your ajaxification needs. Managed by a lightweight Client Runtime embedded in the client web browser, the Backbase Client Framework provides a complete suite of reusable, extensible widgets and an extensive events system that allow you to efficiently build rich AJAX applications.

Backbase technologies allow AJAX applications to be developed with minimal investment. Some examples of AJAX functionality supported by Backbase Enterprise Ajax include:

  • Converting MPI applications to SPI applications;
  • Enhancing existing page components by prefabricated or custom widgets;
  • Creating custom events and behaviors;
  • Using enhancer techniques to minimalize code changes;
  • Adding visual effects like sliding and fading.

Converting the Forms Application from MPI to SPI

Objective

The objective is to Backbase-enable the Forms Application, and convert the application to an SPI with as little impact as possible on the original code. This transformation is achieved by implementing the following steps:

  1. Add a Backbase area, which is recognized and processed by the Backbase Client Runtime.
  2. Add Backbase features using tags from the Backbase tag libraries.
  3. Create container elements to hold page fragments.
  4. Reload fragment files on user interaction.

Implementation

In the WEB-INF/jsp folder, create a JSP file named ajaxified.jsp. To enable Backbase, you must create a Backbase area within the body section. This is illustrated in the fragment of data listed below.

<body xmlns:spring="http://www.backbase.com/2008/spring">
  <script type="application/backbase+xml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:b="http://www.backbase.com/2006/btl"
    xmlns:c="http://www.backbase.com/2006/command"
    xmlns:d="http://www.backbase.com/2006/tdl"
    xmlns:e="http://www.backbase.com/2006/xel"
    xmlns:smil="http://www.backbase.com/2006/smil">


    <xi:include href="<core:out value="${CLIENT_BOOT_DIR}"/>/bindings/config.xml"/>
    <xi:include href="<core:out value="${CLIENT_BOOT_DIR}"/>/bindings/www.w3.org.1999.xhtml/formsProfile.xml"/>
    <xi:include href="<core:out value="${CLIENT_BOOT_DIR}"/>/bindings/www.backbase.com.2006.btl/formsProfile.xml"/>    

    <!-- actual content goes here -->

  </script>
</body>
                       

The next step is to add the Backbase engine to the header section in order to start the engine. This is illustrated in the fragment of data listed below.

<head>
  <!-- keep old tags here, and add only following line -->
  <script type="text/javascript" src="/Backbase/engine/boot.js"></script>
</head>

The application parts (i.e., header, left, and content) that are described in the overview must be implemented using the Backbase panelSet widget, which partitions the screen layout into rows and columns. This is illustrated in the fragment of data listed below.

<div id="panel-groups">
  <b:panelSet rows="70px *">
    <b:panel id="header-panel">
      <div id="topmenu">
        <a href="http://www.interface21.com">Interface21</a><a href="http://www.springframework.org">Spring home</a>
        <a href="http://forum.springframework.org">Spring forum</a>
        <a href="http://www.dzone.com">Dzone.com</a>
        <a href="http://www.infoq.com">Infoq.com</a>
      </div>
      <div id="header">
        <span class="title">spring<span class="darktitle">2.0</span> form tags</span><br/>
      </div>
    </b:panel>
    <b:panel id="body-panel">
      <b:panelSet columns="200px *" splitter="true">
        <b:panel id="menu-panel">
          <div class="lefty">
            <div class="menu">
              <core:forEach items="${userList}" var="user">
                <a href="#">
                  <core:out value="${user.lastName}"/>, <core:out value="${user.firstName}"/>
                  <e:handler event="click" type="application/javascript">
                      bb.command.load("form.htm", "GET", "id=<core:out value="${user.id}"/>", null, bb.document.getElementById("content-panel"), "replaceChildren");
                  </e:handler>
                </a>
              </core:forEach>
            </div>
            <p>New JSP tags in Spring 2.0 make building forms with Spring MVC much easier</p>
            <div class="menu">
              <a href="#">
                  About
                <e:handler event="click" type="application/javascript">
                    bb.command.load("about.htm", "GET", "", null, bb.document.getElementById("content-panel"), "replaceChildren");
                </e:handler>
              </a>
            </div>
            <div class="menu">
              <a href="#">
                  Home
                <e:handler event="click" type="application/javascript">
                    bb.command.load("list.htm", "GET", "", null, bb.document.getElementById("content-panel"), "replaceChildren");
                </e:handler>
              </a>
            </div>
          </div>
        </b:panel>
        <b:panel id="content-panel">
          <div id="content">
            <div id="block">
              <p>Welcome to this Spring 2.0 showcase application that demonstrates the use of new JSP tags for creating form elements.</p>
              <p>Choose an apprentice magician on the left-hand side to continue.</p>
            </div>
          </div>
        </b:panel>
      </b:panelSet>
    </b:panel>
  </b:panelSet>
</div>

Although the basic changes to support SPI are in place, a full page refresh is still performed (MPI model). To enable partial page updates, the parts of the page that are updated selectively need to be identified using named div tags, such as "content" and "block". This is illustrated in the fragment of data listed below.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- this is about.jsp -->
<div xmlns="http://www.w3.org/1999/xhtml" id="content">
 <div id="block">
  <p>
    The Spring MVC form tags application showcases the new
    form tag library introduced in Spring 2.0.
  </p>
  <p>
    The web application is simplistic because the intent is to convey the essence of the new
    form tags themselves and nothing else.
  </p>
 </div>
</div>

Once you have identified the parts of the page to be updated selectively, you must include the code that is required to load these views into the content section. This involves adding onclick event handlers to load subviews into the content section. This is illustrated in the fragment of data listed below.

<div class="lefty">
  <div class="menu">
    <core:forEach items="${userList}" var="user">
      <a href="#">
        <core:out value="${user.lastName}"/>, <core:out value="${user.firstName}"/>
        <e:handler event="click" type="application/javascript">
          bb.command.load("form.htm", "GET", "id=<core:out value="${user.id}"/>", null, bb.document.getElementById("content-panel"), "replaceChildren");
        </e:handler>
      </a>
    </core:forEach>
  </div>
  <p>New JSP tags in Spring 2.0 make building forms with Spring MVC much easier</p>
  <div class="menu">
    <a href="#">
        About
      <e:handler event="click" type="application/javascript">
        bb.command.load("about.htm", "GET", "", null, bb.document.getElementById("content-panel"), "replaceChildren");
      </e:handler>
    </a>
  </div>
  <div class="menu">
    <a href="#">
        Home
      <e:handler event="click" type="application/javascript">
        bb.command.load("list.htm", "GET", "", null, bb.document.getElementById("content-panel"), "replaceChildren");
      </e:handler>
    </a>
  </div>
</div>

Note: The application uses the JSTL core taglib with a default c prefix, which should not be confused with the Backbase command binding. Because Backbase already implements a default c prefix for the command binding, the prefix specified in the fragment of data listed below was changed from c: to core:.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

In order to use Backbase features inside the page fragments, you must declare a number of specific namespaces for the wrapping div, namely TDL, XEL, BTL, Forms, Command, and SMIL. This is illustrated in the fragment of data listed below.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div id="content"
     xmlns="http://www.w3.org/1999/xhtml"
     xmlns:d="http://www.backbase.com/2006/tdl"
     xmlns:e="http://www.backbase.com/2006/xel"
     xmlns:b="http://www.backbase.com/2006/btl"
     xmlns:bf="http://www.backbase.com/2007/forms"
     xmlns:c="http://www.backbase.com/2006/command"
     xmlns:smil="http://www.w3.org/2005/SMIL21/BasicAnimation">


        <!-- content goes here -->
</div>
                       

For successful page submission, you must include the bf:destination attribute in your form. However, adding new attributes to the existing spring tags is not possible, because the Spring taglibs are predefined. To address this issue, you must add the bf:destination attribute to a DOMNodeInsertedIntoDocument event. This is illustrated in the fragment of data listed below.

<form:form action="form.htm" method="post">
  <e:handler event="DOMNodeInsertedIntoDocument" type="application/xml">
    <c:setAttribute name="bf:destination" select="'id('content-panel')'" namespace="http://www.backbase.com/2007/forms"/>
  </e:handler>
  <form:errors path="*" cssClass="errorBox"/>
  ...
                       

Some of the benefits of SPI include:

  • Partial page instead of full page updates
  • Less bandwith
  • Quicker response

For more information, refer to the Technical Overview.

Using Backbase Widgets

Objective

The objective is to take the original application and Backbase-enable it with as little impact as possible on the original code. This process is achieved by implementing the following steps:

  1. Create resizeable areas.
  2. Add a tooltip.
  3. Include an embedded window.

Implementation

To create resizeable areas, you must add a splitter feature, which allows you to resize the panelSet widget. This is illustrated in the fragment of data listed below.

<b:panelSet columns="200px *" splitter="true">
  <!-- body content here -->
</b:panelSet>
                       

In order to improve usability, you can add a toolTip widget to the form elements, which will provide a small piece of informative content when a user hovers over these elements. This is illustrated in the fragment of data listed below.

<div class="first">
  <form:label path="firstName">First Name: </form:label>
  <b>
    <form:input path="firstName"/>
    <b:toolTip>
      This is a Backbase tooltip for the 'First Name' field. It is very easy to add new tooltips.
    </b:toolTip>
  </b>
  <form:errors path="firstName" cssClass="error"/>
</div>

You must include an embedded window to make the underlying XHTML code available. This is illustrated in the fragment of data listed below.

<b>The JSP form tags:</b>
<a href="#">
  Show Code
  <e:handler event="click" type="application/xml">
    <e:with select="id('code-window')">
      <e:call method="setAttribute" name="'open'" value="'true'"/>
    </e:with>
  </e:handler>
</a>
<b:window label="Window" id="code-window" width="400px" height="400px" left="30px" top="20px" open="false">
  <b:codeHighlighter id="jsp-code" class="code-snippets">
    <form:form>
      <form:errors path="*" cssClass="errorBox" />

                ...

    </form:form>
  </b:codeHighlighter>
</b:window>
                       

The benefits of the procedure demonstrated here include:

  • You can add any prefabricated widget or any custom widget to your existing application;
  • You can create new ones and can use them in your future applications;
  • Less investment;
  • Best practiced applications.

Adding Custom Behaviors

Objective

Capturing events on predefined Spring taglibs is not possible. This limitation is easily addressed using the Backbase behavior architecture, which adds new functionality to existing tags.

Implementation

You must define custom behaviors to capture events in Spring. These can either be inline or defined in a separate file (in which case the file is included using xi:include). Inline definitions are used in the fragment of data listed below, with the behaviors defined in the http://www.backbase.com/2008/spring namespace to prevent future conflicts.

<d:tdl>
  <d:namespace name="http://www.backbase.com/2008/spring">
    <d:behavior name="alert-behavior">
      <d:handler event="keydown" type="application/javascript">
        alert('You can handle any event, it\'s very easy!');
      </d:handler>
    </d:behavior>
  </d:namespace>
</d:tdl>
                       

Note: The namespace must be declared in the page fragment wrapper tag (div).

In this example, we are trying to capture a keydown event. Once it is implemented, you must add this behavior to an existing tag, namely the DOMNodeInsertedIntoDocument event. This is illustrated in the fragment of data listed below.

<div class="first">
  <form:label path="firstName">First Name: </form:label>
  <b>
    <form:input path="firstName"/>
    <e:handler event="DOMNodeInsertedIntoDocument" type="application/xml">
      <c:addBehavior with="id('firstName')" select="'spring:alert-behavior'" />
    </e:handler>
    <b:toolTip>
      This is a Backbase tooltip for the 'First Name' field. It is very easy to add new tooltips.
    </b:toolTip>
  </b>
  <form:errors path="firstName" cssClass="error"/>
</div>
                       

Important: According to the taglib definition for form:input, it cannot contain anything between its tags.

Adding behaviors is particularly effective if there is limited scope to modify tags, because any behavior can be added remotely. Alternatively, you can add behaviors to the XHTML tags by adding an e:behavior="my-behavior" attribute.

Adding Animation With SMIL

Objective

The objective is to take advantage of SMIL to add animation and thereby achieve improved application look and feel.

Implementation

There are two options to add SMIL animations:

  1. Use event handlers and add SMIL animations according to the event fired.
  2. Create a custom behavior and add the behavior to any tag.

The best practice is to define a custom behavior, as demonstrated in the fragment of data listed below, which animates a color change on mouseover:

<d:tdl>
  <d:namespace name="http://www.backbase.com/2008/spring">
    <d:behavior name="fx-color">
      <d:handler event="mouseenter" type="application/xml">
        <smil:animate attributeName="background-color" dur="500ms" to="#E0E0E0"/>
      </d:handler>
      <d:handler event="mouseleave" type="application/xml">
        <smil:animate attributeName="background-color" dur="1500ms" to="#F4F4F4"/>
      </d:handler>
    </d:behavior>
  </d:namespace>
</d:tdl>
                       

You must add e:behavior to the wrapping div in order to define the behavior of the SMIL animation. This is illustrated in the fragment of data listed below.

<div class="first" e:behavior="spring:fx-color">
  <form:label path="firstName">First Name<b style="color: red">*</b>: </form:label>
  <!-- rest of code -->
</div>
                       

The result of the SMIL implementation is a crisp, contemporary look and feel to your applications.

Live Demo

This examples page has demonstrated the necessary procedures to integrate Backbase Enterprise Ajax into your existing Spring applications.

In the following live demo, the functionality implemented in the preceding steps is shown: Ajaxify a Spring Application Live Demo.

Having completed this examples page, you should be fully conversant with the key steps that are required to implement an SPI version of a classic MPI application. You should also be comfortable adding Backbase widgets, events, and behaviors to the application.

Note: If there is a need to ajaxify existing Spring applications without the need for a full rewrite of the applications (perhaps because of a significant development investment), Backbase Enterprise Ajax provides enhancers. For more information, please refer to the Backbase documentation on enhanceHTML.

Additional Resources

For more information, please refer to the following documentation, examples and reference material: