The JavaMail API library provides necessary support to develop an e-mail application. Spring revamped the idea and provides an excellent support for the same. It simplified the technique by removing many of the redundant properties of setting up e-mail support in a Java application. This article delves into the API, JavaMail, and Spring and with a simple e-mail application that illustrates their distinctiveness.
Editor’s Note: This site standardly uses the term “e-mail” in the text, but the code that follows uses the term “email.” This shouldn’t cause any confusion. |
An Overview
E-mail has many uses, especially in this era of day-to-day communication and global networks. For example, by subscribing to a specific feature of a Web site, we can start receiving e-mails regarding updates of the subscribed topic. E-mails allow us to send notifications, business orders, periodic reports, and last but not least, annoying junk mail. They are useful, no doubt, but also have numerous instances of misuses as well. In a typical e-mail application, an e-mail is composed by a client, sent to a server, delivered to the destination, and then sends back a response to the client. The Java messaging system makes this communication asynchronous.
The JavaMail API is the e-mail support library from the Oracle arsenal. It is quite powerful, and yet is simple to use. The set of classes and interfaces enable us to send and receive e-mails that can be scaled up to work with different protocols associated with the mailing system.
Spring has simplified the API for full stack e-mail support and minimized the effect of underlying mailing system specifications. Perhaps the most notable distinction between JavaMail API and Spring e-mail support is later simplification of ideas and nothing else. In fact, there is nothing wrong with JavaMail API. If the former is simple, Spring made it simpler. That’s all.
E-mail Through the JavaMail API
JavaMail is not only platform independent but also is a protocol independent API. This means, no matter what be the underlying protocol used by the mailing system, it can be set up accordingly to work with the system. Typically, the set of steps to be followed while writing an e-mail application is more or less the same:
- Supply username and password to connect to the e-mail server.
- Create message, supply recipient addresses.
- Add attachments, if any.
- Send the message to the e-mail server.
The required classes and interfaces are found in the javax.mail and javax.mail.internet packages. Some of the key classes are as follows:
- Authenticator: This is an abstract class found in thejavax.mail package. An object of this class is responsible for authentication for the e-mail provider. An instance of this class is created by invoking the getPasswordAuthentication() method.
- PasswordAuthentication: Found in the javax.mail package. It is the username and password holder class for the Authenticator.
- InternetAddress: Found in the javax.mail.internet package. An instance of this class represents the Internet e-mail address according to the syntax specification of RFC822.
- Message: Found in the javax.mail package. This is a model abstract class for an e-mail message. Implementations are provided by subclassing it.
- MimeMessage: Found in javax.mail.internet. An instance of this class represents MIME-style e-mail messages.
- Session: This is a final class found in the javax.mail package. This class cannot be subclassed and represents a mail session.
- Transport: This is an abstract class found in the javax.mail package which models a message transport.
A Quick Example
The protocol responsible for sending e-mails is called SMTP (Simple Mail Transfer Protocol). The specific properties of the host e-mail provider are set by using an instance of the utility class called Properties. These properties enable us to connect to the host SMTP server, which in our example case is Gmail. A session object is created by using the username and password credentials. The sender’s e-mail address, recipient’s e-mail address, subject of the message, and the content of the message are set by using the MimeMessage object. And finally, the message is send using the static method called send() provided by the Transport class.
package org.mailerapp.demo; import java.util.Properties; import javax.mail.*; import javax.mail.internet.*; public class SimpleMailer { public static void sendMailUsingTLS(String host, String username, String password, String from, String to, String subject, String text) { Properties properties = new Properties(); properties.put("mail.smtp.host", host); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.starttls.enable", "true"); properties.put("mail.smtp.port", "587"); sendMail(properties, username, password, from, to, subject, text); } public static void sendMailUsingSSL(String host, String username, String password, String from, String to, String subject, String text) { Properties properties = new Properties(); properties.put("mail.smtp.host", "smtp.gmail.com"); properties.put("mail.smtp.socketFactory.port", "465"); properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.port", "465"); sendMail(properties, username, password, from, to, subject, text); } public static void sendMail(Properties properties, String username, String password, String fromEmailAddress, String toEmailAddress,, String subject String messageText) { Session session = Session.getInstance(properties, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress(fromEmailAddress)); msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmailAddress)); msg.setSubject(subject); msg.setText(messageText); Transport.send(msg); } catch (Exception ex) { ex.printStackTrace(); } } public static void main(String[] args) { String host = "smtp.gmail.com"; String username = "from-myemail1@gmail.com"; String password = "******"; String fromAddress = "from-myemail1@gmail.com"; String toAddress = "to-myemail2@gmail.com"; String subject = "Test mail"; String text = "This is a sample message. Thank you."; SimpleMailer.sendMailUsingTLS(host, username, password, fromAddress, toAddress, subject, text); SimpleMailer.sendMailUsingSSL(host, username, password, fromAddress, toAddress, subject, text); } }
Listing 1: E-mail support using JavaMail API
E-mail Through the Spring API for JavaMail
Spring classes for e-mail support are grouped under two packages: org.springframework.mail and org.springframework.mail.javamail. The APIs provide support for cleanup operations, initializations, and exceptions.
The org.springframework.mailis the root level package for e-mail support in Spring and the most important interface for sending e-mail is the MailSender. The package contains the hierarchy of classes for checked exceptions.
The org.springframework.mail.javamail package contains the JavaMailSender interface that features MIME message support.
Some key classes and interfaces of these packages are as follows:
- MailSender: This is an interface that defines methods for sending simple e-mails, such as simple text e-mails. To incorporate a MIME message, there is an another interface, called JavaMailSender, which is an extension of this interface.
- MailMessage: This is a common interface for all e-mail messages and designates irrespective of the types of message such as a simple test message or a more complex MIME message.
- MailException: Base exception class for all exception thrown by mail.
- SimpleMailMessage: This refers to a class that represents a simple message and includes data such as from, to, cc, subject, and text message contents.
- JavaMailSenderImpl: This is the core class to send simple mail as well as MIME messages. It is an implementation of the MailSender interface.
- MimeMailMessage: This is an implementation of the MailMessage interface for JavaMail MIME messages.
- MimeMessageHelper: This is a helper class for populating MIME messages. For example, it supports HTML text content, inline content such as images, typical mail attachments, and so forth.
A Quick Example
This is almost the same program as the previous one, except that we are using the Spring mail API to illustrate the idea. Here, the properties for the e-mail host are supplied in the application.properties file. This can be supplied in an XML file or even a database instead with a little modification. Refer to the Spring API javadoc for more details on the API description.
<dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-mail </artifactId> </dependency>
Listing 2: Spring Boot dependency in pom.xml
package org.mailerapp.demo; public class Email { private String from; private String to; private String subject; private String messageText; public Email() { } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getMessageText() { return messageText; } public void setMessageText(String messageText) { this.messageText = messageText; } }
Listing 3: A simple POJO to host e-mail content and properties
package org.mailerapp.demo; import org.springframework.core.io.FileSystemResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import javax.mail.internet.MimeMessage; import java.io.File; @Service public class EmailService { private JavaMailSender javaMailSender; public void sendMail(final Email email){ SimpleMailMessage simpleMailMessage=new SimpleMailMessage(); simpleMailMessage.setSubject(email.getSubject()); simpleMailMessage.setFrom(email.getFrom()); simpleMailMessage.setTo(email.getTo()); simpleMailMessage.setText(email.getMessageText()); javaMailSender.send(simpleMailMessage); } public void sendMailWithAttachment(final Email email, String filePath) throws Exception{ MimeMessage mimeMessage=javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper=new MimeMessageHelper(mimeMessage,true); mimeMessageHelper.setSubject(email.getSubject()); mimeMessageHelper.setFrom(email.getFrom()); mimeMessageHelper.setTo(email.getTo()); mimeMessageHelper.setText(email.getMessageText()); FileSystemResource file=new FileSystemResource(new File(filePath)); mimeMessageHelper.addAttachment("Sample File",file); javaMailSender.send(mimeMessage); } }
Listing 4: Service class to provide e-mail service
package org.mailerapp.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure .SpringBootApplication; @SpringBootApplication public class SimpleMailerWithSpring { @Autowired private static EmailService emailService; public static void main(String[] args) throws Exception { SpringApplication.run(SimpleMailerWithSpring.class, args); Email email = new Email(); email.setFrom("from-mail1@gmail.com"); email.setTo("to-mail2@mgmail.com"); email.setSubject("This is a test mail"); email.setMessageText("This is a sample text message."); emailService.sendMailWithAttachment(email, "./samplepic.jpg"); } }
Listing 5: Initiating Spring boot application
spring.mail.host=smtp.gmail.com spring.mail.username=username@gmail.com spring.mail.password=****** spring.mail.port=587 spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true
Listing 6: application.properties
Conclusion
The Spring framework provides a mailing support utility that can be incorporated into any Java application. It handles the low-level resources quite efficiently on behalf of the programmer and shields from many intricacies of specifying about the type of mailing system being used in the background. There is lot that can be done with both the Spring and JavaMail APIs. Here, we have provided only the barest hint of it.