You are on page 1of 3

Java Email Web

Sending Velocity-based E-Mail with SpringTSS Featured Entry: Sending Velocity-


based E-Mail with Spri

One of the requirements on my current project is to send Job Applicants an e-mail when they apply for a position. Since
we're using Spring, I figured I'd try out its JavaMail and Velocity support to send this e-mail. Below is a short tutorial for
setting up Spring's JavaMail support on a PositionManager class, followed by replacing the e-mail's text with a Velocity
template. It's possible there's easier ways to do this, but this is what worked for me...

One of the requirements on my current project is to send Job Applicants an e-mail when they apply for a position. Since
we're using Spring, I figured I'd try out its JavaMail and Velocity support to send this e-mail. Below is a short tutorial for
setting up Spring's JavaMail support on a PositionManager class, followed by replacing the e-mail's text with a Velocity
template. It's possible there's easier ways to do this, but this is what worked for me. Step 1: Configure the
JavaMailSenderImpl

The first step is to setup a MailSender for the PositionManager. To do this, you need to configure a JavaMailSenderImpl
with a host or a session. For a host, it's rather simple. Add the following to your applicationContext.xml file: <bean
id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host"><value>localhost</value></property>
<!-- If you don't want to hardcode "localhost", load it from a mail.properties file
with PropertyPlaceholderConfigurer -->
</bean>

Optionally, you can also configure it with a Session from JNDI when you're running in a servlet container: <bean
id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:comp/env/mail/Session</value></property>
</bean> <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="session"><ref bean="mailSession"/></property>
</bean> I use the first option for JUnit tests, and the 2nd when running in Tomcat. Step 2: Configure a
SimpleMailMessage with default values

Next you can configure a SimpleMailMessage with some default values in your applicationContext.xml file: <bean
id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from"><value><![CDATA[Human Resources <hr@raibledesigns.com>]]></value></property>
<property name="subject"><value>Your application has been received</value></property>
</bean> Step 3: Configure dependencies in PositionManagerImpl

Then in traditional Spring-style, you need to add variables and setters to the PositionManagerImpl class: private
MailSender mailSender;
private SimpleMailMessage message;

public void setMailSender(MailSender mailSender) {


this.mailSender = mailSender;
}

public void setMessage(SimpleMailMessage message) {


this.message = message;
}

Then configure this class's definition in applicationContext.xml so Spring will inject its dependencies: <bean
id="positionManagerTarget" class="org.appfuse.service.PositionManagerImpl">
...
<property name="mailSender"><ref bean="mailSender"/></property>
<property name="message"><ref bean="mailMessage"/></property>
...
</bean>

Now you should be able to easily send an e-mail in a method of this class: // user and position objects looked up...
SimpleMailMessage msg = new SimpleMailMessage(this.message);
msg.setTo(user.getFullName() + "<" + user.getEmail() + ">");

StringBuffer txt = new StringBuffer();


http://www.java-email.com Powered by Joomla! Generated: 8 September, 2008, 06:50
Java Email Web

txt.append("Dear " + user.getFullName() + ",\n\n");


txt.append("Thank you for application for our ");
txt.append(position.getName() + " position. You can check ");
txt.append(" on the status of this position at the URL below.\n\n");
txt.append(" http://raibledesigns.com/positions/status.jsp\n\n"); // doesn't really exist ;-)
txt.append("Sincerely, \n\nRaible Designs Human Resources");
msg.setText(txt.toString());
try {
mailSender.send(msg);
} catch (MailException ex) {
log.error(ex.getMessage());
}

The only problem with this is that the e-mail message is hard-coded into our Java code - so let's refactor it to use a
Velocity template for the text. Step 4: Configuring Velocity in applicationContext.xml

The next step is to use Spring's Velocity support classes to configure a VelocityEngine. For this, add the following to your
applicationContext.xml file: <bean id="velocityEngine"
class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<props>
<prop key="resource.loader">class</prop>
<prop key="class.resource.loader.class">
org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</prop>
</props>
</property>
</bean>

NOTE: You can also use <property name="configLocation">velocity.properties</property> if velocity.properties file is in


your classpath. However, my velocity.properties file has a webapp.loader defined in it, and since this depends on
javax.servlet.ServletContext, I didn't want to use it in my business logic layer. You could also load velocity.properties with
PropertyPlaceholderConfigurer and then refer to ${class.resource.loader.class}. Step 5: Configure Velocity dependency
in PositionManagerImpl

In order to use this nice little velocityEngine you just configured, you'll need to add a variable and setter to
PositionManagerImpl: private VelocityEngine velocityEngine;

public void setVelocityEngine(VelocityEngine velocityEngine) {


this.velocityEngine = velocityEngine;
}

And configure it's dependency in applicationContext.xml: <bean id="positionManagerTarget"


class="org.appfuse.service.PositionManagerImpl">
...
<property name="velocityEngine"><ref bean="velocityEngine"/></property>
...
</bean>

Now you can refactor the text part of the previous e-mail sending logic to use a template. Map model = new
HashMap();
model.put("user", user);
model.put("position", position);

String result = null;


try {
// notificationTemplate.vm must be in your classpath
result = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine,
"notificationTemplate.vm", model);
} catch (VelocityException e) {
e.printStackTrace();
}
msg.setText(result);

Pretty slick huh? A further configuration option is to use Spring to set the name of the template. If you know of any better
http://www.java-email.com Powered by Joomla! Generated: 8 September, 2008, 06:50
Java Email Web

ways to do JavaMail and e-mail templates with Spring, or find errors in my code - please let me know.

One thing that seems to wrong with this is that when I run my PositionManagerTest JUnit test - it initializes Velocity a
number of times. This is because the PersonManagerImpl is re-initialized each time in my setUp() method. This is a JUnit
issue, not a Spring issue. I could probably do something so the PositionManagerImpl is only created once for the entire
Test run. Either that, or figure out a way to initialize Velocity for only one test. Hints would be great.

Another issue is that I'd like to use Velocity's DataSourceResourceLoader, but it only accepts a JNDI DataSource name.
It'd be nice if there was an alternative version that would allow setting of the DataSource via IoC.
About the author Matt Raible matt@raibledesigns.com
Blog: http://www.raibledesigns.com/page/rd

Matt currently resides in Denver where he consults as a J2EE Developer for Raible Designs and is always striving to find
the easiest solutions for web applications. His current favorite technologies can be found within his open source AppFuse
application. He is actively involved in the Open Source community and loves Java.

http://www.java-email.com Powered by Joomla! Generated: 8 September, 2008, 06:50

You might also like