Skip to content

Example code, sending emails using Spring SimpleMailMessage, MimeMessagePreparator and Velocity Templates

When I first wrote my custom Email utlity 4 years back using JavaMail, it spread well over hundred lines of code. Looking at Spring’s out of the box functionality for sending Emails with attachements & velocity templates makes you wanna feel sorry for your old code. The reference doc by Spring for Email is quite comprehensive, however if you want even simpler Email handler with custom to/from/template with spring config, here is the code. I assume a generic object called ‘DomainObject’ in your application. (All domain objects should extend this. If you use annotations, this is the way to go for domain driven development). The email utility would accept a domain object, use it’s properties like name, lastUpdatedBy, createdBy to complete the email body, the rest of which is in a velocity template. All the other beans and To/From/Host properties are set in a context file called applicationContext-mail.xml. (Another good practice, have seperate context files in your web-app).

EmailService

package com.reverttoconsole.mail;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import javax.mail.internet.MimeMessage;

import org.apache.log4j.Logger;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.ui.velocity.VelocityEngineUtils;

import com.reverttoconsole.common.DomainObject;

public class EmailService {
	private static final Logger logger = Logger.getLogger(EmailService.class);

	private VelocityEngine velocityEngine;
	private String velocityTemplate;
	private JavaMailSender mailSender;
	private SimpleMailMessage templateMessage;
	private Boolean isEnabled;

	public void sendMail(final DomainObject object, final String subject) throws Exception{
    	if (!isEnabled.booleanValue()) {
    		logger.warn("Mail is not enabled. Check your applicationContext-mail.xml isEnabled Settings");
    		return;
    	}

    	MimeMessagePreparator preparator = new MimeMessagePreparator() {
            public void prepare(MimeMessage mimeMessage) throws Exception {
               MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
               message.setTo(templateMessage.getTo());
               message.setFrom(templateMessage.getFrom());
               message.setSubject(subject);
               Map model = new HashMap();
               model.put("object", object);
               String text = VelocityEngineUtils.mergeTemplateIntoString(
                  velocityEngine, velocityTemplate, model);
               message.setText(text, true); //true means enable html email
            }
         };
         this.mailSender.send(preparator);
    }

	public JavaMailSender getMailSender() {
		return mailSender;
	}
	public void setMailSender(JavaMailSender mailSender) {
		this.mailSender = mailSender;
	}
	public SimpleMailMessage getTemplateMessage() {
		return templateMessage;
	}
	public void setTemplateMessage(SimpleMailMessage templateMessage) {
		this.templateMessage = templateMessage;
	}
	public VelocityEngine getVelocityEngine() {
		return velocityEngine;
	}
	public void setVelocityEngine(VelocityEngine velocityEngine) {
		this.velocityEngine = velocityEngine;
	}
	public String getVelocityTemplate() {
		return velocityTemplate;
	}
	public void setVelocityTemplate(String velocityTemplate) {
		this.velocityTemplate = velocityTemplate;
	}
	public Boolean getIsEnabled() {
		return isEnabled;
	}
	public void setIsEnabled(Boolean isEnabled) {
		this.isEnabled = isEnabled;
	}
        public String getFrom() {
               return getTemplateMessage().getFrom();
        }
        public String[] getTo() {
                 return getTemplateMessage().getTo();
        }
}

applicationContext-mail.xml

<!--l version="1.0" encoding="utf-8-->
<beans xmlns="http://www.springframework.org/schema/beans"></beans>	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"&gt;
	<description></description>
		This file defines Email beans and their dependencies .
    <bean autowire="byName" id="emailManager" class="com.reverttoconsole.EmailService"></bean>
       <!-- set to true for enabling email -->
<property name="isEnabled" value="true"></property>
	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"></bean>
<property name="host" value="fe1psb1.i.fmedr.com"></property>
	<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage"></bean>
<property name="from" value="youremail@mail.com"></property>
<property name="to" value="youremail@mail.com"></property>
<property name="subject" value="Confirmation: "></property>
	<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"></bean>
<property name="velocityProperties">
         <value></value>
            resource.loader=class           class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
      </property></pre>
<strong>Velocity Template</strong>

Make sure you place this file (.vm) in the same location as the EmailService. Stick to convention. It’s easier

Hello,

The ${object.shortName} is created by ${object.createdBy} on ${object.createdDate}.

This is a system-generated notification. Please do not reply to this email.

Please contact Support with any questions.

Thank you.

That’s it. Set your email parameters, call EmailService.sendMail(..) from your controller or application code and you’re all done!

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

4 Comments

  1. mahendar wrote:

    Example is good . I need to send subject also as templates . Can you please provide the code.
    Thanks in advance

    Monday, December 17, 2007 at 8:40 am | Permalink
  2. Priyatam wrote:

    Template usually serves one purpose at a time. If you want it to be associated for multiple contexts (body, email to/from, subject etc.) then it really is not a template! However a quick dirty solution I can think of is to add an anchor like “Subject:Mail Notification” at the end of velocity template and later strip it off using regex or StringUtils

    Monday, December 17, 2007 at 10:07 am | Permalink
  3. raju wrote:

    how to print email body in multiple parts.
    Ex:
    some body text.
    [attachment]
    again some text.

    i am using sprig and java

    Wednesday, June 16, 2010 at 3:21 am | Permalink
  4. Lakshmi wrote:

    Example is good.I need to send an email to multiple people and I am cofiguring the email id’s in a property file as a string(seperated by ,).
    Can you provide some example for this

    Monday, March 26, 2012 at 7:48 am | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*