How to initialize Velocity DateTool within spring webapp?

jakarta-mail, java, spring, templates, velocity

Solution

After few hours of searching it turns out to be quite trivial: just add one more line when initializing model:

private void sendMail(final Object backingObject) {     
    MimeMessagePreparator preparator = new MimeMessagePreparator() {
        public void prepare(MimeMessage mimeMessage) throws Exception {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);

            // Set subject, from, to, ....

            // Set model, which then will be used in velocity's mail template
            Map<String, Object> model = new HashMap<String, Object>();
            model.put("backingObject", backingObject);

            // Add this line in order to initialize DateTool
            model.put("date", new DateTool());

            String text = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "mail_template.vm", model);
            message.setText(text, true);

        }
    };
    this.javaMailSender.send(preparator);
}

After that you can use $date inside your template.

Problem

Recently I needed to initialize Velocity's DateTool in order to properly format date in resulting e-mail. Usually you do this with VelocityContext, however, since I was using spring's VelocityEngineFactoryBean configured in xml, I got to figure out - how can you initialize VelocityContext, when using VelocityEngineFactoryBean? In other words, my setup: webmvc-config.xml ``` <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> ``` MailSender.java ``` public class CustomMailSender { @Autowired private VelocityEngine velocityEngine; private void sendMail(final Object backingObject) { MimeMessagePreparator preparator = new MimeMessagePreparator() { public void prepare(MimeMessage mimeMessage) throws Exception { MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true); // Set subject, from, to, .... // Set model, which then will be used in velocity's mail template Map<String, Object> model = new HashMap<String, Object>(); model.put("backingObject", backingObject); String text = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "mail_template.vm", model); message.setText(text, true); } }; this.javaMailSender.send(preparator); } ``` In mail_template.vm you want to use something like: ``` <li>Transfer start date: $date.format('medium_date', $backingObject.creationDate)</li> ``` How to ensure, that DateTool will be properly initialized and used, when parsing template?

Original source