How to Integrate Velocity Tools 2.0 with Spring

Java Velocity Spring

Spring Framework has built-in Apache Velocity support but it is outdated, uses some now deprecated classes and doesn't support Velocity Tools 2.0 sub-project that contains great amount of useful goodies (it is still in beta but already bulletproof enough for production). Here is an example how to integrate Velocity Tools 2.0 into Spring.

What we need to do is extend VelocityView class and override createVelocityContext() method. Here is our extended class VelocityToolsView:

package ca.sergiy.velocity;

import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.ToolContext;
import org.apache.velocity.tools.ToolManager;
import org.springframework.web.servlet.view.velocity.VelocityView;

public class VelocityToolsView extends VelocityView {

    private static ToolContext toolContext = initVelocityToolContext();

    @Override
    protected Context createVelocityContext(Map model, HttpServletRequest request, HttpServletResponse response) {
        VelocityContext context = new VelocityContext(toolContext);
        if(model != null) {
            for(Map.Entry<String, Object> entry : (Set<Map.Entry<String, Object>>)model.entrySet()) {
                context.put(entry.getKey(), entry.getValue());
            }
        }
        return context;
    }

    private static ToolContext initVelocityToolContext() {
        if(toolContext == null) {
            ToolManager velocityToolManager = new ToolManager();
            velocityToolManager.configure("velocity-tools.xml");
            toolContext = velocityToolManager.createContext();
        }
        return toolContext;
    }
}

Now you can just use this class anywhere instead of default VelocityView and enjoy all benefits of Velocity Tools 2.0.

For performance reasons ToolContext has static initializer so it is getting created only once. If you need to pass some configuration parameters for every instance then just put initialization directly into initVelocityToolContext().

Aug 26, 2009
profile for serg at Stack Overflow, Q&A for professional and enthusiast programmers