Introduction
In this article, we will see how to use Spring’s capability for sending email. The first section of the article deals with sending plain text email content with the help of Spring’s Mail Sender and Mail message classes with the help of a sample application. The latter half of the article deals with sending email with rich text contents like formatted html, inline contents and attachments. The reader of the article is assumed to have basic knowledge on Core Spring with concepts like Dependency Injection and Inversion of Control as the sample applications heavily uses these concepts through configuration files.
also read:
Sending Plain Text Mail
In this section, we will see how to send a simple mail using Spring Library. We will also go through the various interfaces and classes available in Spring to support this. The package org.springframework.mail
defines the MailSender
interface for sending an email. One concrete implemention of this interface is JavaMailSenderImpl
which can be used to send a MailMessage
. We will develop a simple example called UserRegistration
which demonstrates this.
UserRegistration Service
The User Registration class defines the properties mailSender
and userEmailIds
. Property mailSender
which is of type JavaMailSenderImpl
provides the concrete implementation for sending the e-mail. Later on in this article we will see how to write this property with the UserRegistration instance. Note that Spring internally uses the Java Mail API for sending the email. So, the Java Mail API related libraries mail.jar
and activation.jar
have to be there in the class path for running the sample application. Have a look at the following listing.
UserRegistrationService.java
package net.javabeat.articles.spring.core.mail.basic; import java.util.Iterator; import java.util.Set; import org.springframework.mail.MailSender; import org.springframework.mail.SimpleMailMessage; public class UserRegistrationService { private MailSender mailSender; private Set userEmailIds; public Set getUserEmailIds() { return userEmailIds; } public void setUserEmailIds(Set userEmailIds) { this.userEmailIds = userEmailIds; } public MailSender getMailSender() { return mailSender; } public void setMailSender(MailSender mailSender) { this.mailSender = mailSender; } public void uponSuccessfulRegistration(){ SimpleMailMessage[] mailMessageArray = new SimpleMailMessage[userEmailIds.size()]; Iterator iterator = userEmailIds.iterator(); for (int index = 0; iterator.hasNext(); index ++){ SimpleMailMessage message = new SimpleMailMessage(); String toAddress = iterator.next(); message.setTo(toAddress); message.setSubject("User Registration successful"); message.setText("The user '" + toAddress + "' is successfully registered"); mailMessageArray[index] = message; } System.out.println("Sending email ...."); mailSender.send(mailMessageArray); } }
The property userEmailIds
defines a set of user mail ids to which email will be sent assuming that the user registration is successful. Let’s have a look at the method uponSuccessfulRegistration()
which is the core for email sending process. These methods iterate over the set of user ids and creates a SimpleMailMessage instance. It then populates the various attributes like the to field
, subject field
and the text field
. Finally, email is sent by making a call to MailSender.send()
method which takes a set of MailMessage
objects.
Configuration File
The following defines the configuration file for email sending process. It defines two bean declarations, one for mailSender
and the other for userRegistrationService
.
mail-simple.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean id="mailSender" class ="org.springframework.mail.javamail.JavaMailSenderImpl" > <property name="host" value="smtp.gmail.com" /> <property name="port" value="587" /> <property name="username" value="<userId>@gmail.com" /> <property name="password" value="<PasswordForUserId>" /> <property name="javaMailProperties"> <props> <prop key="mail.smtp.starttls.enable">true</prop> </props> </property> </bean> <bean id="userRegistrationService"> <property name="mailSender" ref="mailSender" /> <property name="userEmailIds"> <set> <value><TestUser1>@gmail.com</value> <value><TestUser2>@gmail.com</value> </set> </property> </bean> </beans>
It is seen that the mailSender
is a concrete implementation for org.springframework.mail.javamail.JavaMailSenderImpl
. The properties host
, port
, username
and password
are required and they have to be rightly configured. The property host
represents the name of the mail server. In our example, we will be sending email through Gmail, in which case, the value for this property is smtp.gmail.com
. The value port
represents the port number on which the mail server applications can accept requests and it happens to be 587
for Gmail. The property username
represents a valid Gmail address present in the Gmail server and the property password
represents the password for the same.
Next comes the declaration of the bean userRegistrationService
which is of type UserRegistrationService
. If you could remember that in the class declaration there are two properties mailSender
and userEmailIds
. Both these properties are given proper association here. The property mailSender
is referring to the bean identifier mailSender
that we had already declared. The property userEmailIds
which is a set is declared as follows,
<property name="userEmailIds"> <set> <value><TestUser1>@gmail.com</value> <value><TestUser2>@gmail.com</value> </set> </property>
Note that the values for the ‘userEmailids’ should represent property email identifiers.
Client
Have a look at the client application. The client application in this case loads the spring’s application context defined in the file mail-simple.xml
. It then gets a reference to the bean userRegistrationService
which has proper reference to the mailSender
as well to the set of email ids object. Finally the method uponSuccessfulRegistration()
defined on UserRegistrationService
is called to actually send the mail.
UserRegistrationClient.java
package net.javabeat.articles.spring.core.mail.basic; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserRegistrationClient { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("mail-simple.xml"); UserRegistrationService service = (UserRegistrationService)context.getBean("userRegistrationService"); service.uponSuccessfulRegistration(); } }
Sending Mail with attachments and formatted HTML
As we will in the last example with the help of SimpleMailMessasge
we are able to send a mail which has only plain text. Now imagine a situation where we want to send a mail containing resources, attachments and formatted HTML content, in which case MIMEMessage
class comes into picture. MIME, which is Multipurpose Internet Mail Extensions defines the standard for sending rich text messages which can include attachments and HTML content.
User Model objects
Have a look at the User model object.
User.java
package net.javabeat.articles.spring.core.mail.mime; public class User { private String name; private String emailId; private String dateOfBirth; public String getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(String dateOfBirth) { this.dateOfBirth = dateOfBirth; } public String getEmailId() { return emailId; } public void setEmailId(String emailId) { this.emailId = emailId; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
The above class defines the properties name
, emailId
and dateOfBirth
. We will also be defining a class called UserSet
for representing the set of users. The following listing shows the declaration for the class UserSet.
UserSet.java
package net.javabeat.articles.spring.core.mail.mime; import java.util.Set; public class UserSet { private Set users; public Set getUsers() { return users; } public void setUsers(Set users) { this.users = users; } }
Birthday Service class
We will have a look at the Birthday Service class in this section. Similar to the UserRegistrationService
class that we have seen before, this class also refers to the mail sender object as well as the set of users containing the email ids to which the birthday wish has to be sent. Have a look at the following class.
BirthdayService.java
package net.javabeat.articles.spring.core.mail.mime; import java.util.Iterator; import java.util.Set; import javax.mail.internet.MimeMessage; import org.springframework.mail.javamail.JavaMailSender; public class BirthdayService { private JavaMailSender sender; private Set users; public Set getUsers() { return users; } public void setUsers(Set toEmailAddresses) { this.users = toEmailAddresses; } public JavaMailSender getSender() { return sender; } public void setSender(JavaMailSender sender) { this.sender = sender; } public void birthdayWish(){ try{ Iterator iterator = users.iterator(); for (int index = 0; iterator.hasNext(); index ++){ System.out.println("Wishing birthday for " + iterator.next()); MimeMessage mimeMessage = sender.createMimeMessage(); User user = iterator.next(); BirthdayMessagePreparator birthdayMessagePreparator = new BirthdayMessagePreparator(user); birthdayMessagePreparator.prepare(mimeMessage); sender.send(birthdayMessagePreparator); } }catch (Exception e){ e.printStackTrace(); } } }
The difference lies in the way the email message is sent. Whereas the class UserRegistrationService
makes use of SimpleMailMessage
for sending the email, this class uses MimeMessage
to send the email which is defined in the method birthdayWish()
. While iterating over the list of users we have created a MimeMessage
object by calling MailSender.createMimeMessage()
. After that for populating the mime message, we have delegated the functionality to BirthdayMessagePrepator
class which extends Spring’s MimeMessagePreparator
class, which actually populates the mime message which includes HTML content, attachments etc. We will see the definition of the class in the forthcoming section. After populating the MIME Message, it is a matter of calling the send()
method that takes the MimeMessagePreparator
object. This send()
method internally asks the MimeMessagePreparator
object to return the MimeMessage
object and send it.
Birthday Message Preparator class
Note that in the last section we saw that the Birthday Message Service class internally uses the BirthdayMessagePreparator
class to actually populate the MimeMessage
object. Have a look at the following listing.
BirthdayMessagePreparator.java
package net.javabeat.articles.spring.core.mail.mime; import javax.mail.internet.MimeMessage; import org.springframework.core.io.FileSystemResource; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.mail.javamail.MimeMessagePreparator; public class BirthdayMessagePreparator implements MimeMessagePreparator { private User user; public BirthdayMessagePreparator(User user){ this.user = user; } public void prepare(MimeMessage mimeMessage) throws Exception { MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); mimeMessageHelper.setTo(user.getEmailId()); mimeMessageHelper.setSubject("Birthday Wishes"); StringBuilder text = new StringBuilder(); text.append("<html>"); text.append("<body>"); text.append("<h2>Birthday Wish</h2>"); text.append("<p>Wishing you a very happy birthday " + user.getName() + "."); text.append("<p><img src=\"cid:greetingImage\"/>"); text.append("</body>"); text.append("</html>"); // Sets the text mimeMessageHelper.setText(text.toString(), true); // Inline content FileSystemResource inlineContent = new FileSystemResource("/greetingImage.jpg"); mimeMessageHelper.addInline("greetingImage", inlineContent); //Attachment FileSystemResource greetingImage = new FileSystemResource("/greeting.jpg"); mimeMessageHelper.addAttachment("Greeting", greetingImage); } }
The method prepare()
is overridden to actually prepare the MimeMessage
with the help of MimeMessageHelper
class. Note that a instance of MimeMessage
is passed on to the constructor of MimeMessageHelper
with the second argument being true indicating that this MimeMessage will contain rich text content like images/attachments. Next the to field
, subject
and text
is set with the help of setTo()
, setSubject()
and setText()
methods. Because, we are allowing html content also in the text, the overloaded version of setText()
method is used indicating that the text will contain html contents by passing true
to the second argument. Finally we have added inline content and attachment by calling addInline()
and addAttachment()
defined on MimeHelper
object. Note that both inline content and attachment are loaded and are referred through FileSystemResource objects. One more thing to note is that the inline content is given an identifier ‘greetingImage
, which should match the Common Image Descriptor
identifier that we had previously specified in the html content – i.e cid:greetingImage
.
Configuration
The following configuration file declares the bean definitions for the mailSender
, birthdayService
and userSet
objects. Note that we have created some sample user objects which are referred by UserSet
object.
mail-mime.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean id="mailSender" class ="org.springframework.mail.javamail.JavaMailSenderImpl" > <property name="host" value="smtp.gmail.com" /> <property name="port" value="587" /> <property name="username" value="TestUser@gmail.com" /> <property name="password" value="PasswordForTestUser" /> <property name="javaMailProperties"> <props> <prop key="mail.smtp.starttls.enable">true</prop> </props> </property> </bean> <bean id="birthdayService"> <property name="sender" ref="mailSender" /> </bean> <bean id="userSet"> <property name="users"> <set> <ref bean="testuser1"/> <ref bean="testuser2"/> </set> </property> </bean> <bean id="testuser1"> <property name="name" value="testUser1" /> <property name="emailId" value="testuser1@gmail.com" /> <property name="dateOfBirth" value="19750-08-25" /> </bean> <bean id="testuser2"> <property name="name" value="testUser2" /> <property name="emailId" value="testuser2@gmail.com" /> <property name = "dateOfBirth" value="1980-08-10"/> </bean> </beans>
Client
BirthdayServiceClient.java
package net.javabeat.articles.spring.core.mail.mime; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; import java.util.Set; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BirthdayServiceClient { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("mail-mime.xml"); UserSet userSet = (UserSet)context.getBean("userSet"); Set allUsers = userSet.getUsers(); Set users = new HashSet(); for (User user : allUsers){ boolean isCurrentMonth = isCurrentMonth(user); if (isCurrentMonth){ users.add(user); } } BirthdayService birthdayService = (BirthdayService)context.getBean("birthdayService"); birthdayService.setUsers(users); birthdayService.birthdayWish(); } private static boolean isCurrentMonth(User user){ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date dob = null; try{ dob = dateFormat.parse(user.getDateOfBirth()); }catch (Exception e){ e.printStackTrace(); return false; } Date current = new Date(); return current.getMonth() == dob.getMonth(); } }
The client class other than loading the application’s context invokes the method birthdayWish() defined on birthday service object. Note that before calling
this method only the user objects which has the birth month equal to current month is passed to the setUsers() method.
Conclusion
This article demonstrated the capabilities of Spring for sending simple text and rich text email contents. It explained through the various classes and interfaces like MailSender
, MailMessage
, JavaMailSenderImpl
, MimeMessage
, MimeMessageHelper
, MimeMessagePreparator
by illustrating two sample applications. It is expected that after going through the article the readers would have got the knowledge of integrating email sending capability of Spring into their real-time applications.
also read: