Using Velocity in your Spring Applications

October 1, 2008

Have you ever found yourself doing something like this in some code you’ve been writing?


String xml = "<adocument><anelement>" + someproperty + "</anelement><anotherelement>" 
                 + anotherproperty + "</anotherelement></adocument>";

Yuck!

I’m a lazy developer. And I know from experience that at some point, I’m going to have to change this embedded xml generating pile of crap. Someone will ask me to add an element, or remove an element, or add a namespace, or change the formatting, or …… Ugh! Maintaining this kind of code is what makes maintenance programmers go insane….

Fortunately, I’ve spent enough time doing maintenance development that I know that a little time spent upfront will save a lot of time and frustration down the road and I try to avoid naive solutions like the above in favor of something that appeals to my laziness.

One simple, yet effective, solution to the above problem is to use Velocity. Velocity is a powerful scripting language and makes short work of the simple example above. The main advantage is that the template is just text and text is easy to maintain.

Here’s how we’d go about refactoring the above solution…

First, I’d create a velocity template adocument.vm with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<adocument>
  <anelement>${someproperty}</anelement>
  <anotherelement>${anotherproperty}</anotherelement>
</adocument>

Then, I’d configure my velocity engine in my spring context:

    <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
      <property name="velocityProperties">
       <value>
        resource.loader=class
        class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
       </value>
      </property>
    </bean>

The properties tell Velocity how to find the template files when I give it the template file path. I’ve specified that I want Velocity to use the ClasspathResourceLoader to find my templates, which are likely packaged up inside my application archive (war, jar).

Now, I just wire up the class that is generating the xml to the engine:

private VelocityEngine engine;

public void setVelocityEngine(VelocityEngine engine)
{
    this.engine = engine;
}
<property name="velocityEngine" ref="velocityEngine"/>

And tell it where the template is:

String templateFile;

public void setTemplateFile(String file)
{
    this.templateFile = file;
}
<property name="templateFile" value="myTemplatesDirectory/adocument.vm"/>

myTemplatesDirectory should be a directory in your classpath (packaged in your jar?) that contains your template.

Then, I change how I’m generating the xml:

Map model = new HashMap();
model.put("someproperty", someproperty);
model.put("anotherproperty", anotherproperty);
String xml = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templateFile, model);

Note that this solution still violates the open closed principle but that can be solved by making the generation code a reuseable module and having the client pass in the variables:

public String generateContent(Map model, String template)
{
    return VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, template, model);
}

You may still need to update how the model is generated if the view needs to change (e.g. to add a new field) but you won’t have to muck around with any of the software to make simple textual changes to the xml. That’s a solution that appeals to my laziness.

It should be obvious to some of you that this refactoring is essentially a simple MVC solution. Velocity can be, and frequently is, used in place of solutions like jsp to generate views. However, as shown above, it is a powerful tool in your toolbox that can easily be used in your middleware for generating content that could, for instance, become the payload of a JMS message.

Cheers!

Advertisements

6 Responses to “Using Velocity in your Spring Applications”


  1. Hi, (sorry i couldnt get your name from anywhere)
    Nice example using Velocity!

    I also used Velocity templating engine to generate dynamically XML descriptors for queues and MDBs. I point jBoss deployment service to Velocity template and give it a hashmap of properties, ds creates XML descriptor for me in the file system based on the template. After that I am asking jBoss main deployer to create deployment based on the XML descriptor.

    You can have a read about it here:
    http://javabeans.asia/2008/05/01/using_template_to_deploy_a_jboss_queue.html


  2. […] as I discussed yesterday, it turns out that I had to change these canned document because somewhere along the way, we had […]

  3. David Says:

    I have a stupid question how to xml encoded string value in the template ?
    Sample : if someproperty contains a “&”, the XML isn’t valid anymore.
    (yes I can encode it before I pass the value to the template but if I have a bean with many properties, I don’t want to do it because I’m lazy).

  4. heuristicexception Says:

    If you think that you are going to have markup characters in your element content, you can just wrap your element content in a CDATA tag so it is not processed by the parser.


  5. […] Using Velocity in your Spring Applications « Heuristic Exception (tags: velocity spring) […]

  6. jelaoufi Says:

    thanks a lot for this tuto !!!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: