Sending an Email

Problem

How to send emails based on templates?

Pre-requisite

Solution

We use Velocity template engine to construct our email messages and use Spring's built-in JavaMailSender to deliver the emails to our email SMTP server.  First, add the following to you web/WEB-INF/config/applicationContext.xml:

<bean id="velocityEngine"
    class="org.springframework.ui.velocity.VelocityEngineFactoryBean"
    p:resourceLoaderPath="/WEB-INF/velocity" />
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"
    p:host="${email.host}" />

This above configuration tells Velocity where to look for the template files and also setup the JavaMailSender.  Noticed that ${email.host} is a variable which you specify in web/WEB-INF/config/webapp.properties.  It is typically smtp.ucsd.edu.

We've also created a email utility class that uses the velocityEngine and mailSender to deliver the mail.  It's a helper utility that is generic to send any types of emails.  First add the email utility bean definition in web/WEB-INF/config/applicationContext.xml:

<bean id="emailUtil" class="edu.ucsd.act.hello.util.EmailUtil" />

And the actual code for this utility class is:

public class EmailUtil {
    /* Email From param */
    public static final String FROM = "from";

    /* Email To param */
    public static final String TO = "to";

    /* Email Subject param */
    public static final String SUBJECT = "subject";

    /* Email CC param */
    public static final String CC_LIST = "ccList";

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private VelocityEngine velocityEngine;

    public void send(final String templateName, final Map<String, Object> model) {
        MimeMessagePreparator preparator = new MimeMessagePreparator() {
            @SuppressWarnings("unchecked")
            public void prepare(MimeMessage mimeMessage) throws Exception {
                String from = (String) model.get(FROM);
                String to = (String) model.get(TO);
                String subject = (String) model.get(SUBJECT);
                Assert.notNull(from);
                Assert.notNull(to);
                Assert.notNull(subject);
                List<String> ccList = (List<String>) model.get(CC_LIST);
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
                message.setFrom(from);
                message.setTo(to);
                message.setSubject(subject);
                if (ccList != null) {
                    for (String cc : ccList) {
                        message.addCc(cc);
                    }
                }

                String text = VelocityEngineUtils.mergeTemplateIntoString(
                        velocityEngine, templateName, model);
                message.setText(text, true);
            }
        };

        mailSender.send(preparator);
    }
}

A sample velocity email template web/WEB-INF/velocity/invalid-tx.vm that displays a list of invalid indexes:

As of todate ($date.format('MM/dd/yyyy', $effectiveDate)), the following list of transactions with its balance are invalid:
#foreach($tx in $txList)
    $tx.indx, $number.format("currency", $tx.amount, $locale)
#end

You can send emails by calling:

emailUtil.send("invalid-tx.vm", model);

where model is a Map containing the effectiveDate and txList keys and each corresponding values of a Dateand List<Tx> object.  It also contains email parameters such as fromtosubject, etc.

Email Handling