Pages

Tuesday, October 29, 2019

Beginners Guide to Spring Email (Spring Boot)

1. Overview


In this article, We'll learn how to send an email using Spring or Spring Boot through step by step procedure. This is absolutely designed for beginners.

In this tutorial, We will see the following as required to send mail in the spring framework with a step by step.


  • Maven dependencies for spring and spring boot.
  • Understanding the common mailing terminologies in spring.
  • Spring and spring boot mailing properties.
  • Sending simple sample spring email examples.
  • Sending emails with an attachment.
  • Construction and sending an email template.
  • How to handle email sending errors.






2. Maven and Gradle Dependencies


Below shown are the maven dependencies for spring and spring boot.

2.1 Spring


For the spring framework, We should use the corresponding jar file because spring does not bundle "spring-context-support" in the base jars. So we must add email dependency in pom.xml as below. You can check out the latest version from the link given in the references.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.0.1.RELEASE</version>
</dependency>


2.2 Spring Boot


For Spring Boot, We must add &quot;spring-boot-starter-mail&quot; artifactId as part of the dependency section in pom.xml file.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>

Note: If you are not using maven then add the below dependencies to the project classpath.

The JavaMail mail.jar library
The JAF activation.jar library


2.3 Grade dependency management


Spring:
compile('org.springframework:spring-context-support')


Spring Boot: 


compile('org.springframework.boot:spring-boot-starter-mail')


3. Mail Server Properties


In java, the Spring framework has a set of classes and interfaces which supports sending emails. "org.springframework.mail" is the root package for all email classes and interfaces.

If you do not understand this section, do not worry. You can skip for now. You will understand clearly when you go through the examples code on it.

MailSender: This is a top-level interface that provides basic functionality for sending very simple emails.

JavaMailSender: This is also an interface and sub-interface of the above MailSender top interface. It supports MIME messages and is mostly used in conjunction with the MimeMessageHelper class for the creation of a MimeMessage. It is recommended to use the MimeMessagePreparator mechanism with this interface.

JavaMailSenderImpl class: Provides an implementation of the JavaMailSender interface. It supports the MimeMessage and SimpleMailMessage.

SimpleMailMessage class: Used to create a simple mail message including the from, to, cc, subject and text fields.

MimeMessagePreparator interface: Provides a callback interface for the preparation of MIME messages.

MimeMessageHelper class: Helper class for the creation of MIME messages. It offers support for images, typical mail attachments and text content in an HTML layout

3.1. Spring Mail Server Properties


JavaMailSenderImpl class is a part of org.springframework.mail.javamail. Common properties need to be specified in the JavaMailSenderImpl instances. All properties are should be set to JavaMailSenderImpl such as host, port, user name, password and SMTP protocol properties.

@Bean
public JavaMailSender getJavaMailSenderInstance() {
    JavaMailSenderImpl javaMailSenderObject = new JavaMailSenderImpl();
    javaMailSenderObject.setHost("smtp.gmail.com");
    javaMailSenderObject.setPort(587);
     
    javaMailSenderObject.setUsername("this.is.my.gmail@gmail.com");
    javaMailSenderObject.setPassword("password123");
     
    Properties props = javaMailSenderObject.getJavaMailProperties();
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.debug", "true");
     
    return javaMailSenderObject;
}

3.2. Spring Boot Mail Server Properties


Before seeing this section, please make sure you have the dependency jar file is in place.

Add the below properties in the application.properties file using "spring.mail" namespace.

Here the example is based on Gmail mail configurations.

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<login user name to smtp server>
spring.mail.password=<login password to smtp server (Not an ordinary password)>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

Note: The password for your account should not be an ordinary password. This is an application password generated for your google account. Follow this link to see the details and how to generate your Google App Password.

3.3 SES SMTP Properties


How to send an email using Amazon SES service from Spring boot application.
Add the below properties set to application.properties.

The host should be "email-smtp.*.amazonaws.com". '*' means zone or location of your host.

spring.mail.host=email-smtp.us-west-2.amazonaws.com
spring.mail.username=user-name
spring.mail.password=password
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.port=25
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true


Note: Amazon requires you to verify your credentials before using them properly. Follow the steps in this link to verify your username and password from the official guide.


4. Java Spring Email Example (Works for Spring Boot as well)


We are going to send a simple mail about the order placed in amazon. This example is without any attachments.

import org.springframework.mail.SimpleMailMessage;

@Component
public class EmailServiceImpl implements EmailService {
  
    @Autowired
    public JavaMailSender emailSender;
 
    public void sendSimpleMessageForOrder(String toEmail, String orderTitle, String emailBody) {

        SimpleMailMessage message = new SimpleMailMessage(); 
        message.setTo(toEmail); 
        message.setSubject(orderTitle); 
        message.setText(emailBody);
        emailSender.send(message);

    }
}

5. Sending Email to Multiple Recipients


We can pass multiple email addresses to the setTo() method. Because it takes Var-Args to type pf String.

    SimpleMailMessage msg = new SimpleMailMessage();
    msg.setTo("to_1@gmail.com", "to_2@gmail.com", "to_3@yahoo.com");


6. Spring Boot Send Email With Attachment Example


Now, We'll see the example on how to send an email with attachments in Spring Boot. In most cases, simple email messages are not enough. See the above case just sending the order information about the product is not good enough for the customer. It would be nice if it has an invoice and order summary attachment.

We need a special class to support the attachments feature. Spring API has a class "MimeMessageHelper" which supports different MIME types and this is part of package "org.springframework.mail.javamail".

By using we can send simple emails and also sends attachments with no issues.

addAttachment() method must be invoked from MimeMessageHelper class.

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

@Component
public class EmailServiceWithAttachments implements EmailService {
  
    @Autowired
    public JavaMailSender emailSend
 

 void sendEmailWithAttachment() throws MessagingException, IOException {
  MimeMessage message = emailSend.createMimeMessage();

  // True flag to indicate you need a multipart message
  MimeMessageHelper helper = new MimeMessageHelper(message, true);
  helper.setTo("jhon@gmail.com");
  helper.setSubject("Order No #1234 Detailed Summary"); 
  helper.setText("Your complete order info, You can find it in the attachement!");

  // let's attach the infamous windows Sample file (this time copied to c:/)
  FileSystemResource file = new FileSystemResource(new File("ftp:/orders/order-1234.pdf"));
  helper.addAttachment("order-1234.pdf", file);

  emailSend.send(message);
 }

}


7. Spring Mail - Sending Email with Inline Attachment Example


In some of the cases, We need to create the HTML content in java class and pass the inline content to email. And another thing is attachment also should be part of the HTML page at the end of the HTML content.

Spring Boot handles these kinds of situations also. MimeMessageHelper has a method addInline() which does the job for us. Let us take a look at the below example.

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

@Component
public class EmailServiceWithAttachments implements EmailService {
  
    @Autowired
    public JavaMailSender emailSend
 

 void sendEmailWithAttachment() throws MessagingException, IOException {
  MimeMessage message = emailSend.createMimeMessage();

  // True flag to indicate you need a multipart message
  MimeMessageHelper helper = new MimeMessageHelper(message, true);
  helper.setTo("jhon@gmail.com");
  helper.setSubject("Order No #1234 Detailed Summary"); 
  helper.setText("<html><body> some image..</body></html>");

  // let's attach the infamous windows Sample file (this time copied to c:/)
  FileSystemResource file = new FileSystemResource(new File("ftp:/orders/order-1234.pdf"));
  helper.addInline("order-1234.pdf", file);

  emailSend.send(message);
 }

}

8. Simple Email Template for Email Body


As we have seen in the previous examples that the SimpleMailMessage class supports text formatting. We can extend and create a template for emails by defining a template bean in our configuration as below.

Note that this for formating only emails body content.

@Bean
public SimpleMailMessage addSimpleEmailTemplateForEmail() {
    SimpleMailMessage message = new SimpleMailMessage();
    message.setText("This is the email for your order no :\n%s\n");
    return message;
}

Now we can use the above-created bean as a template for email and only need to provide the necessary parameters to the template.


@Autowired
public SimpleMailMessage template;

public void sendEmail(){

 String templateArgument = "12345":
 String text = String.format(template.getText(), templateArgument);  
 SimpleMailMessage message = new SimpleMailMessage(); 
 message.setTo(toEmail); 
 message.setSubject(orderTitle); 
 message.setText(emailBody);
 emailSender.send(message);
}

9. Handling Email Send Errors


When sending an email we do not face any problems or errors if the recipient's emails are correct. If the recipient's email is wrong then we will get errors.

The protocol specs for SMTP in RFC 821 specifies the return code as 550. That SMTP server should return when attempt sending an email to the incorrect address. But most of the public SMTP servers don't do this. Instead, they send a “Delivery Failed” email to your inbox or give no feedback at all.

Here are a few options you can go through to handle this case:


  • Catch the SendFailedException, which can never be thrown.
  • Check your sender mailbox on the “delivery failed” message for some period of time. This is not straightforward and the time period is not determined.
  • If your mail server gives no feedback at all, you can do nothing.


10. Conclusion


In this article, We've seen how to send an mail using Spring and Spring Boot. Covered the below topics.

Setting up email properties
Sending an email using a very simple approach
Sending emails to multiple users
Sending with attachment
Sending attachment as inline
Creating an email template and using it
How to handle the errors.

11. References

Here are the references that this article is crafted and useful for further learning.

Spring Email Dependency
Spring Boot Email Dependency
Spring email doc
JavaMail
JAF
Gmail SMTP Settings
Java Var-Args

No comments:

Post a Comment

Please do not add any spam links in the comments section.