Thursday, April 8, 2010

Sending Emails using Spring-Mail

Some applications are required to send emails. What can I say? These are the things we have to do for money…

The JavaMail API is pretty much boring and a little cumbersome to use. Once again you find yourself fiddling with connection management, exception handling, etc. And once again Spring comes to the rescue :)

Spring-Mail has neat and easy to use email API, including MIME messages support.

Let’s imagine we need to implement “forgot my password” feature. So here goes.
The EmailFacade:

package mail;

public interface EmailFacade {

    public void sendPasswordReminderEmailTemplate(String user, String password, String email);
}
The implementations:
package mail;

import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.util.Assert;


class EmailFacadeImpl implements EmailFacade {

    private final MailSender mailSender;
    private final SimpleMailMessage passwordReminderEmailTemplate;


    public EmailFacadeImpl(MailSender mailSender, SimpleMailMessage passwordReminderEmailTemplate) {
        Assert.notNull(mailSender, "mailSender may not be null");
        Assert.notNull(passwordReminderEmailTemplate,
                       "passwordReminderEmailTemplate may not be null");

        this.mailSender = mailSender;
        this.passwordReminderEmailTemplate = passwordReminderEmailTemplate;
    }

    public void sendPasswordReminderEmailTemplate(String user, String password, String email) {
        // Create a thread safe instance of the template message and customize it
        SimpleMailMessage msg = new SimpleMailMessage(passwordReminderEmailTemplate);
        String formatedText = String.format(passwordReminderEmailTemplate.getText(), user, password);
        msg.setText(formatedText);
        msg.setTo(email);
        mailSender.send(msg);
    }
}
And the Spring Configuration:
  <bean id="emailFacade" class="mail.EmailFacadeImpl">
        <constructor-arg>
     <bean class="org.springframework.mail.javamail.JavaMailSenderImpl">
   <property name="host" value="${emailServerURL}"/>
   <property name="username" value="${emailPrincipal}"/>
   <property name="password" value="${emailPassword}"/>
     </bean>
        </constructor-arg>
        <constructor-arg ref="passwordReminderEmailTemplate"/>
  </bean> 
 
  <bean id="passwordReminderEmailTemplate" class="org.springframework.mail.SimpleMailMessage">
    <property name="from" value="me@mycompany.com"/>
    <property name="subject" value="Password Reminder"/>
    <property name="text">
      <!-- Text template to be used with String.format() -->
      <value><![CDATA[Hi %s,
Your password is
%s]]>
      </value>
    </property>
  </bean>
TADA!

For some use cases it would be better to replace the String.format() call with some templating engine such as Velocity. I left it here for brevity.

1 comment:

  1. A very nice templating engine (far better than velocity) is StringTemplate http://www.stringtemplate.org/

    ReplyDelete