Using Velocity

Velocity is another view technology that you can use in the Spring views. Unlike JSP pages, Velocity templates are not compiled into Java classes. They are interpreted by the Velocity engine.

Even though the pages are interpreted, the time needed to generate the output is very short; in fact, in most cases, Velocity templates outperform the JSP pages. However, there are a couple of drawbacks: the JSP custom tags cannot be used in Velocity and the developers have to familiarize themselves with the syntax of the Velocity Template Language.

Velocity is a stand-alone project that is used in many applications that produce text output. You can download the latest version of the Velocity libraries from http://jakarta.apache.org/velocity/. We are going to use version 1.4 in this chapter. In addition to Velocity, you need the VelocityTools you can download from http://jakarta.apache.org/velocity/tools/.

Integrating Velocity and Spring

A Velocity engine must be initialized before you can use it. The VelocityConfigurer class performs this initialization. We need the velocityConfigurer bean to set up resource paths to the Velocity template files.

Once an instance of the VelocityConfigurer class is created in the application context, we can use Velocity just like any other view in our application. Listing 18-10 shows how to declare a velocityConfigurer bean.

Listing 18-10: velocityConfigurer Bean Declaration

image from book
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ¿ "http://www.springframework.org/dtd/spring-beans.dtd">      <beans>     <bean bold">velocityConfigurer"          bold">VelocityConfigurer">         <property name="resourceLoaderPath">             <value>WEB-INF/views/</value></property>     </bean> </beans>
image from book

Next, we add a view definition in the views.properties file, as shown in Listing 18-11.

Listing 18-11: Velocity View Definition

image from book
#product/index product-index.class=org.springframework.web.servlet.view.velocity.VelocityView product-index.url=product/index.vm
image from book

The product-index view is going to be created as an instance of VelocityView and the template file is going to be loaded from WEB-INF/views/product/index.vm. The first part of the path to the template file is defined in the velocityConfigurer bean and the second part is declared in the views.properties file. All that is left to do is create a simple Velocity template (see Listing 18-12).

Listing 18-12: The product/index.vm Velocity Template

image from book
<html> <head> </head> <body>      All products:<br> #foreach($product in $products)     ${product.name}<br> #end      </body> </html>
image from book

Finally, in Listing 18-13, we are going to modify the ProductController from Chapter 17 to make sure it returns an instance of ModelAndView("product-index", …).

Listing 18-13: Modified ProductController

image from book
public class ProductController extends MultiActionController {     private List<Product> products;          public ModelAndView index(HttpServletRequest request,          HttpServletResponse response) {         return new ModelAndView("product-index", "products", products);     }      }
image from book

When the application is rebuilt and deployed, we should see a list of products at /ch18/ product/index.html, as shown in Figure 18-1.

image from book
Figure 18-1: Output of the ProductController.index() method in the browser

Advanced Velocity Concepts

Just a simple View implementation would be a very limited Velocity support. Spring goes much further by allowing you to customize the properties of the Velocity engine by setting its properties through the velocityConfigurer bean, and by providing you with macros that have functionality similar to the Spring JSTL tags introduced in the "Using JSP Pages" section.

You can set the properties of the Velocity Engine in one of two ways: either by providing a standard properties file or by setting the properties directly in the velocityConfigurer bean definition, as shown in Listing 18-14.

Listing 18-14: Setting Velocity Engine Properties

image from book
 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ¿ "http://www.springframework.org/dtd/spring-beans.dtd">      <beans>     <bean bold">velocityConfigurer"          bold">VelocityConfigurer">         <property name="resourceLoaderPath">             <value>WEB-INF/views/</value></property>         <property name="velocityProperties">             <props>                 <prop key="file.resource.loader.cache">false</prop>             </props>         </property>         <property name="configLocation">             <value>/WEB-INF/classes/velocity.properties</value>         </property>     </bean> </beans>
image from book

Naturally, you have to decide whether you want to set the Velocity engine properties in a properties file or whether you want to keep them in the bean definition.

Perhaps the most important Velocity support comes from the Velocity macros Spring exposes in the Velocity templates; these macros work just like the Spring JSTL tags. The most important macro is the #springBind macro. It gives you access to the Spring Validator framework from your Velocity templates. If you need to use the Spring macros in a particular view, you must set Spring's exposeSpringMacroHelpers property to true.

To demonstrate the usage of the Velocity macros, we will now create a Velocity template that allows the users to enter product details. In this template, we provide full validation and error control. We use the ProductFormController from

Listing 18-15: views.properties File

image from book
#products product-index.class=org.springframework.web.servlet.view.velocity.VelocityView product-index.url=product/index.vm product-index-r.class=org.springframework.web.servlet.view.RedirectView product-index-r.url=/ch17/product/index.html product-edit.class=org.springframework.web.servlet.view.velocity.VelocityView product-edit.url=product/edit.vm product-edit.exposeSpringMacroHelpers=true      #other views omitted
image from book

In Listing 18-15, the code in bold shows the lines we added to support the product-edit view as a Velocity template. Notice that we set the exposeSpringMacroHelpers property to true; this allows us to create the edit.vm template, as shown in Listing 18-16.

Listing 18-16: edit.vm template Contents

image from book
<form action="edit.html" method="post"> <input type="hidden" name="productId" value="${command.productId}"> <table>     <tr>         <td>Name</td>         <td>#springBind("command.name")                 <input name="name" value="$!status.value">                 <span >$status.errorMessage</span>         </td>     </tr>     <tr>         <td>Expiration Date</td>         <td>#springBind("command.expirationDate")                 <input name="expirationDate" value="$!status.value">                 <span >$status.errorMessage</span>         </td>     </tr>     <tr>         <td></td>         <td><input type="submit"></td>     </tr> </table> </form>
image from book

Notice that we can use the #springBind macro in the template. This macro does precisely the same work its JSTL counterpart does: it allows us to access the Spring Validator framework from the template. The result is exactly what you would expect—the /product/edit.html file shows a standard HTML form with a working validator (see Figure 18-2).

image from book
Figure 18-2: Edit form with validator message

There is no difference between the ProductFormController code when you are using Velocity views and the code you use in the JSP views; the only differences are the view definition in the views.properties file and the presence of the velocityConfigurer bean in the application context.

The code we used in the edit.vm file in Listing 18-16 still doesn't take full advantage of the available Spring macros. We could further simplify the code by using the #springFormInput, #springFormTextarea, #springFormSingleSelect, #springFormMultiSelect, #springFormRadioButtons, #springCheckboxes, and #showErrors macros, but there is little advantage in doing so. A better solution is to spend a little more time writing the code, and making sure that it does exactly what we need it to, instead of relying on too many tools to do all the work for us.

The final set of properties of the VelocityView that is worth your attention is composed of velocityFormatterAttribute, dateToolAttribute, and numberToolAttribute. If you specify these values in the views.properties file, the instances of the VelocityFormatter, the DateTool, and the NumberTool are inserted into the VelocityContext using the names set in the views.properties file.

Velocity provides a good alternative to JSP pages; the lack of features is well justified by its speed. Unfortunately, you cannot yet use Velocity in Tiles, which is a great disadvantage.



Pro Spring
Pro Spring
ISBN: 1590594614
EAN: 2147483647
Year: 2006
Pages: 189

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net