SMTP: Spring Mail To Program

0

All Java developers know, or should know, the Spring framework contains a lot of gems. Recently I discovered a new gem: an easy way to send an email. With the use of one single POJO mail class, you can easily let your application send an email and wire/inject al the mail configuration with the Spring applicationContext.xml.

Let’s first look at the simple POJO mail class.

package nl.amis.blog.mail;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

@Configurable
public class MailMessage {

    @Autowired
    private MailSender mailSender;

    private final SimpleMailMessage message = new SimpleMailMessage();

    public MailMessage(final String from) {
        message.setFrom(from);
    }

    public MailMessage setReply(final String replyTo) {
        message.setReplyTo(replyTo);
        return this;
    }

    public MailMessage setTo(final String to) {
        message.setTo(to);
        return this;
    }

    public MailMessage setCc(final String cc) {
        message.setCc(cc);
        return this;
    }

    public MailMessage setBcc(final String bcc) {
        message.setBcc(bcc);
        return this;
    }

    public MailMessage setSubject(final String subject) {
        message.setSubject(subject);
        return this;
    }

    public MailMessage setBody(final String body) {
        message.setText(body);
        return this;
    }

    public void send() {
        mailSender.send(message);
    }
}

It only contains setters for the mail properties and one method, the send method.
All the setters are delegated (composition pattern [1]) to the SimpleMailMessage class provided by the Spring framework and return the current instance implementing the builder pattern [2].
The send method sends the real mail using the MailSender which is also part of the Spring framework.

This results in nice clean code when using it:

MailMessage message = new MailMessage("abc.def@gmail.com").setTo("ghi.jkl@gmail.com");
message.setSubject("Hello").setBody("Hello World!").send();

The only thing to do is wiring the mail configuration (smtp settings) to the Spring MailSender class in the Spring applicationContext.xml. I’ve chosen to read them from a separate properties file:

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

  <context:annotation-config />
  <context:spring-configured />
  <context:load-time-weaver />
  <context:component-scan base-package="nl.amis.blog.mail" />

  <context:property-placeholder location="file:${oracle.j2ee.home}/config/myApp.properties" />

  <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host">
      <value>${mail.smtp.host.name}</value>
    </property>
    <property name="port">
      <value>${mail.smtp.host.port}</value>
    </property>
    <property name="username">
      <value>${mail.smtp.username}</value>
    </property>
    <property name="password">
      <value>${mail.smtp.password}</value>
    </property>
    <property name="javaMailProperties">
      <props>
        <!-- Use SMTP transport protocol -->
        <prop key="mail.transport.protocol">smtp</prop>
        <!-- Use SMTP-AUTH to authenticate to SMTP server -->
        <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
        <!-- Use TLS to encrypt communication with SMTP server -->
        <prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>
        <prop key="mail.debug">${mail.debug}</prop>
      </props>
    </property>
  </bean>
</beans>

So part of my properties file looks like this:

# Hostname of mail server
mail.smtp.host.name= ABC001
# Port nr of mail server
mail.smtp.host.port= 25
# Username to connect to mailserver (can be empty for anonymous connection)
mail.smtp.username=
# Password to connect to mailserver (can be empty for anonymous connection)
mail.smtp.password=
# Switch authorisation on (true) or off (false)
mail.smtp.auth= false
# Switch TLS encryption on (true) or off (false)
mail.smtp.starttls.enable = false
# Switch debug logging of spring mailcomponent on (true) or off (false)
mail.debug= true

Note that using the @Configurable annotation, Spring loadtime waving is used. This is needed to be able to inject in a POJO at creation with AspectJ. This means that the Spring loadtime waving jars have to be added besides the normal Spring library jars:

  • org.aspectj.aspectjweaver-x.y.z.jar
  • org.aspectj.aspectjrt-x.y.z.jar
  • org.springframework.spring-aspects-x.y.z.jar

Don’t forget to include the loadtime waving configuration tags in the Spring applicationContext.xml where the component-scan tag defines which packages have to be scanned for loadtime waving (you don’t want to scan all your jar libraries).

[1] Item 16: Favor composition over inheritance – Effective Java 2nd Edition – Joshua Bloch
[2] Item 2: Consider a builder when faced with many constructor parameters – Effective Java 2nd Edition – Joshua Bloch

 

Share.

About Author

Emiel is a senior Java & SOA consultant at AMIS, Nieuwegein (The Netherlands).

Comments are closed.