Sending Gmail from Spring

Here’s a working example of how to send an Email (customised for the Gmail client) from a Spring application.

The POM would look like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.dimitrisli</groupId>
  <artifactId>springEmail</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
  	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.6.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
    	<groupId>org.springframework</groupId>
    	<artifactId>spring-support</artifactId>
    	<version>2.0.8</version>
    </dependency>
    <dependency>
    	<groupId>com.sun.mail</groupId>
    	<artifactId>javax.mail</artifactId>
    	<version>1.4.4</version>
    </dependency>
  </dependencies>
  <build>
  	<plugins>
  		<plugin>
  			<artifactId>maven-compiler-plugin</artifactId>
  			<configuration>
  				<source>1.6</source>
  				<target>1.6</target>
  			</configuration>
  		</plugin>
  	</plugins>
  </build>
</project>

Few things to notice on this POM:

  • Specifying UTF-8 platform agnostic source encoding. If this property is not there Maven would complain about system specific encoding.
  • Due to the dependency tree, specifying spring-context is enough to bring the minimal number of Spring related jars that are needed to construct the minimal Spring project that uses the ApplicationContext, therefore Maven saves us from this trouble. Namely, the jars that are absolutely necessary:
    • spring-context
    • spring-beans
    • spring-core
    • spring-expression
    • spring-asm
    • commons-logging
  • Since we would be using Spring’s SimpleMailMessage the jar spring-support is also needed.
  • Also the javax.mail is needed for the despatching of the email.
  • Explicitly specifying java 1.6 for compilation using the maven maven-compiler-plugin plugin.

Our service layer is represented from the following class:

package com.dimitrisli.springEmail;

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

@Service("emailService")
public class EmailService {

	@Autowired
	private MailSender emailSender;
	@Autowired
	private SimpleMailMessage exceptionEmail;

	public void sendEmail(String from, String to, String subj, String body){
		SimpleMailMessage message = new SimpleMailMessage();
		message.setFrom(from);
		message.setTo(to);
		message.setSubject(subj);
		message.setText(body);
		emailSender.send(message);
	}

	public void sendExceptionEmail(String error){
		SimpleMailMessage exceptionEmailMessage = new SimpleMailMessage(exceptionEmail);
		exceptionEmailMessage.setText(error);
		emailSender.send(exceptionEmailMessage);
	}
}

Few things to notice:

  • @Service Spring annotation is another way of saying @Component but has a better representation of the service layer. Also specifying the bean id at that stage in the java bean makes the bean reference in an xml  configuration file unnecessary.
  • @Autowired is taking care of injecting the dependencies of the emailSender and exceptionEmail functionality. Loose coupling at its best.

Under /src/main/resources we store the Spring configuration file:

<?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-3.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
	<!--context namespace and schema for the component-scan to work-->
	<context:component-scan base-package="com.dimitrisli.springEmail" />

	<bean id="emailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host" value="smtp.gmail.com"/>
		<property name="port" value="25"/>
		<property name="username" value="your@gmailhere.com"/>
		<property name="password" value="yourpass"/>
		<property name="javaMailProperties">
			<props>
				<prop key="mail.transport.protocol">smtp</prop>
				<prop key="mail.smtp.auth">true</prop>
				<prop key="mail.smtp.starttls.enable">true</prop>
				<prop key="mail.debug">true</prop>
			</props>
		</property>
	</bean>

	<bean id="exceptionEmail" class="org.springframework.mail.SimpleMailMessage">
		<property name="from">
			<value>from@email.com</value>
		</property>
		<property name="to">
			<value>to@email.com</value>
		</property>
		<property name="subject" value="Something went wrong please investigate"/>
	</bean>

</beans>

Things to notice:

  • Namespaces include the beans reference due to the tags we are using and the context reference due to the component-scan
  • component-scan on the specified package is activating the @Autowired magic.
  • The emailSender bean is tailored for the Gmail specific settings passing all the needed parameters to the JavaMailSenderImpl.
  • The exceptionEmail bean is following another technique having a preconfigured SimpleMailMessage.

Finally the MainSpringContainer which is laying down the two test scenarios creating a Spring Application Context:

package com.dimitrisli.springEmail;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class MainSpringContainer {

	public static void main(String[] args) {
		ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/resources/spring.xml");
		EmailService emailService = (EmailService) context.getBean("emailService");
		emailService.sendEmail("from@email.com", "to@email.com", "test subject", "test body");
		emailService.sendExceptionEmail("something went terribly wrong");
	}
}

You can find the code in this Github repo

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s