Search This Blog

Sunday 6 January 2013

Processing Template Text in Spring

In our previous post we saw Spring's ability to allow us to send mails. With mails comes up the requirement for mail templates. We want to dynamically generate our content using some template generation framework.
I decided to integrate Velocity via Spring for this purpose.
The XML configuration for the same is :
<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>
Here we have defined the configuration for a bean instance of type VelocityEngineFactoryBean which is a FactoryBean. I have also a map entry for
  • "resource.loader" - This tells Velocity to use ClasspathResourceLoader. The ClasspathResourceLoader will load templates placed in the classpath (in jars, for example).
  • "class.resource.loader.class" - This is the class to use for the loading of our vm files from class path
For more details of velocity configurations you can visit this Velocity site link.
The next step is to create our bean to use:
<bean id="templateTester" class="com.test.TemplateTester">
    <property name="velocityEngine" ref="velocityEngine" />
</bean>
This completes the configuration part. The code for these beans is:
public class TemplateTester {
    private VelocityEngine velocityEngine;

    public VelocityEngine getVelocityEngine() {
        return velocityEngine;
    }

    public void setVelocityEngine(VelocityEngine velocityEngine) {
        this.velocityEngine = velocityEngine;
    }

    public String getMessage(final String vmSrc,
            final Map<String, Object> paramMap) {
        final String text = VelocityEngineUtils.mergeTemplateIntoString(
                this.velocityEngine, vmSrc, paramMap);
        return text;
    }
}
The class has a VelocityEngine dependency that is wired based on the configuration. It also exposes a getMessage() method that is capable of reading data from the template and merging it with the passed parameters.
There is one point of note. Our wired dependency was an instance of VelocityEngineFactoryBean whereas the property was of type VelocityEngine. This is a use case of FactoryBean in Spring. It will result in a VelocityEngine instance as a part of the wiring. I decided to test the code:
public static void main(String[] args) {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
            "spring-template.xml");
    TemplateTester templateTester = (TemplateTester) applicationContext.getBean("templateTester");
    final Map<String, Object> paramMap = new HashMap<String, Object>();
    paramMap.put("user", "Robin");
    System.out.println(templateTester.getMessage("test.vm", paramMap));
}
The velocity file, test.vm was added to the classpath:
Hi ${user}, we have successfully generated the template using Velocity.
On executing the code:
444  [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanF
actory  - Returning cached instance of singleton bean 'templateTester'
452  [main] DEBUG org.apache.velocity.app.VelocityEngine  - ResourceManager : fo
und test.vm with loader org.apache.velocity.runtime.resource.loader.ClasspathRes
ourceLoader
Hi Robin, we have successfully generated the template using Velocity

No comments:

Post a Comment