Send Email with Spring using Velocity template

Posted On: 01/29/2013

Posted By: Baljit Garcha

Sending an HTML email using Spring (JavaMailSender interface), velocity template engine for message body, and Gmail SMTP for sending email. 

Spring Framework provides nice and helpful integration for sending emails from Java applications. 

Velocity template helps create nice and beautiful HTML email with images.

Email Sender

package com.blog.cavalr.web.mail;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Service;
import org.springframework.ui.velocity.VelocityEngineUtils;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

package com.blog.cavalr.web.mail;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Component;
import org.springframework.ui.velocity.VelocityEngineUtils;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

@Component("emailSender")
public class EmailSender {

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private VelocityEngine velocityEngine;


    public void sendEmail(final String toEmailAddresses, final String fromEmailAddress,
                          final String subject) {

        sendEmail(toEmailAddresses, fromEmailAddress, subject, null, null);

    }

    public void sendEmailWithAttachment(final String toEmailAddresses, final String fromEmailAddress,
                                        final String subject, final String attachmentPath,
                                        final String attachmentName) {

        sendEmail(toEmailAddresses, fromEmailAddress, subject, attachmentPath, attachmentName);

    }

    private void sendEmail(final String toEmailAddresses, final String fromEmailAddress,
                           final String subject, final String attachmentPath,
                           final String attachmentName) {

        MimeMessagePreparator preparator = new MimeMessagePreparator() {

            public void prepare(MimeMessage mimeMessage) throws Exception {

                MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);
                message.setTo(toEmailAddresses);
                message.setFrom(new InternetAddress(fromEmailAddress));
                message.setSubject(subject);

                String body = VelocityEngineUtils.mergeTemplateIntoString(
                        velocityEngine, "templates/reminder.vm", "UTF-8", null);
                message.setText(body, true);

                if (!StringUtils.isBlank(attachmentPath)) {
                    FileSystemResource file = new FileSystemResource(attachmentPath);
                    message.addAttachment(attachmentName, file);
                }
            }
        };
        this.mailSender.send(preparator);
    }
}
	

EmailSender class, uses Spring's org.springframework.mail.javamail.JavaMailSender to add MIME message support to the emails. JavaMailSender provides a callback interface MimeMessagePreparator for preparation of JavaMail MIME messages.

MimeMessageHelper makes its easier to create MimeMessage, use MimeMessageHelper to set sender's address, subject of the message, body of the message and attachements.

Spring Application Context

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.blog.cavalr.web"/>

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">true</prop>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.smtp.host">smtp.gmail.com</prop>
                <prop key="mail.smtp.port">587</prop>
            </props>
        </property>
        <property name="username" value="username" />
        <property name="password" value="password" />
    </bean>

    <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>
</beans>

Here's the bean definition for this example

<context:component-scan base-package="com.blog.cavalr.web" /> tells Spring to scan all the classes under package com.blog.cavalr.web and detect the classes with annotations @Controller, @Repository, @Service, or @Component and register them as beans.

Velocity Template

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
	<body>
		Dear Registered User,<p/>

		This is a reminder email. Please remember to submit your application by EOD today.<p/>

		Thanks<br/>
		Development Team.

	</body>
</html>
To use Velocity to create your email template, you will need to have the Velocity libraries available on your classpath. You will also need to create one or more Velocity templates for the email content that your application needs.

Run the sample code

Before running the sample code to send an email, in applicationContext.xml file, change the STMP server settings for the email server, if you are using Gmail for sending emails, just update the username and password to send emails.

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">true</prop>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.smtp.host">smtp.gmail.com</prop>
                <prop key="mail.smtp.port">587</prop>
            </props>
        </property>
        <property name="username" value="<your_username_to_email_server>" />
        <property name="password" value="<your_password_to_email_server>" />
    </bean> 

And then run EmailSenderTest.testSendEmail() and testSendEmailWithAttachment() to send emails with and without attachment. The attachment file attachement.txt can found at the root folder of the project.

So, that's it, enjoy your time with Spring and Velocity and feel free to drop any comments below.

Download Source Code

Attachement: Spring-Email-Velocity.zip (size: 24 Kb)

GitHub: https://github.com/cavalr/emailer

comments powered by Disqus