Send Email With Attachment – Spring Boot

In this post, we will learn how to send the email from the spring boot application with an attachment. We will also learn how to add an image in the email body and attach a PDF file to it.

We will also use the FreeMarker template as the mail body. The freemarker is a template engine that generates dynamic HTML files by processing values passed from the application layer.

Version details:

  • Spring Boot version : 2.2.4.RELEASE
  • Java version : 1.8
  • Spring boot Web, FreeMarker, lombok and mail dependencies.
  • Postman to test the application.

Create the Spring boot application

Create a Spring boot application with required dependencies.

Add spring boot web, spring boot freemarker, spring boot mail starter dependencies, and the lombok dependency.

The complete pom.xml file is given below.

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.asb.example</groupId>
	<artifactId>spring-boot-mailing-example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-mailing-example</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
		<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-freemarker</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mail</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Add the mail related configurations

Add the below spring configuration properties to the application.properties configuration file.

spring.mail.default-encoding=UTF-8
spring.mail.host=smtp.gmail.com
spring.mail.protocol=smtp
spring.mail.username=your mailid
spring.mail.password=your password
spring.mail.port=587
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

A few of the configuration properties are:

  • spring.mail.protocol: The protocol used for sending the mail.
  • spring.mail.host: We are using Gmail as SMTP host in this example.
  • spring.mail.username: SMTP server login username. Replace with your Gmail Id.
  • spring.mail.password: SMTP server password. Enter your Gmail password here.
  • spring.mail.properties.*: Other Java mail properties.

Create an EmailConfig configuration file and define a FreeMarker template configuration bean. Here, we are setting the template file path. We use this template file as the email body.

package com.asb.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean;
@Configuration
public class EmailConfig {
	@Primary
	@Bean
	public FreeMarkerConfigurationFactoryBean fmfbean() {
		FreeMarkerConfigurationFactoryBean bean = new FreeMarkerConfigurationFactoryBean();
		bean.setTemplateLoaderPath("classpath:/templates");
		return bean;
	}
}

Creating a email request DTO

Create an EmailRequestDto DTO class.

We are using this class as the request object to send the email.

package com.asb.example.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class EmailRequestDto {
	private String from;
	private String to;
	private String subject;
	private String name;
}

Creating the email service

Create a spring service class with the name MailService. This class will process the FreeMarker template file and create an email body.

The method also sends the request to the SMTP server.

package com.asb.example.service;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import com.asb.example.dto.EmailRequestDto;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
@Service
public class MailService {
	@Autowired
	private JavaMailSender mailSender;
	@Autowired
	private Configuration configuration;
	public String sendMail(EmailRequestDto request, Map<String, String> model) {
		String response;
		MimeMessage message = mailSender.createMimeMessage();
		try {
			MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
					StandardCharsets.UTF_8.name());
			ClassPathResource pdf = new ClassPathResource("static/attachment.pdf");
			ClassPathResource image = new ClassPathResource("static/asbnotebook.png");
			Template template = configuration.getTemplate("email.ftl");
			String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
			helper.setTo(request.getTo());
			helper.setFrom(request.getFrom());
			helper.setSubject(request.getSubject());
			helper.setText(html, true);
			helper.addInline("asbnotebook", image);
			helper.addAttachment("attachment.pdf", pdf);
			mailSender.send(message);
			response = "Email has been sent to :" + request.getTo();
		} catch (MessagingException | IOException | TemplateException e) {
			response = "Email send failure to :" + request.getTo();
		}
		return response;
	}
}

We have the method sendMail that accepts email requests and a map as the input parameter.

Spring provides a JavaMailSender class that we can use to send the email. Also, we can auto wire this bean into our service, as shown in the above service class.

We have created a MimeMessage instance and created a MimeMessageHelper instance. This helper class can be used to set different email properties such as to, from, email text, attachments, etc.

Also, we have used the addInline method to embed the image to the email body. We have attached a PDF file with the help of the addAttachment method of the class MimeMessageHelper.

The FreeMarker template is processed and converted into HTML text using the Configuration instance. The FreeMarkerTemplateUtils utility class helps dynamically processing the FreeMarker template and generates the final HTML format.

These two classes are available in the spring boot freemarker starter dependency.

Expose a REST endpoint to send the email

Create a MailSenderController class. This is a RESTful controller with one POST method.

The REST endpoint sends the email to the given email id with the subject.

package com.asb.example.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.asb.example.dto.EmailRequestDto;
import com.asb.example.service.MailService;
@RestController
public class MailSenderController {
	@Autowired
	private MailService mailService;
	@PostMapping("send-mail")
	public ResponseEntity<String> sendMail(@RequestBody EmailRequestDto emailRequest) {
		Map<String, String> model = new HashMap<>();
		model.put("name", emailRequest.getName());
		model.put("value", "Welcome to ASB Notebook!!");
		String response = mailService.sendMail(emailRequest, model);
		return new ResponseEntity<>(response, HttpStatus.OK);
	}
}

Here, we are adding the name and value to a map. These values are used by the FreeMarker template file.

Add the email template file

Create a FreeMarker template file called email.ftl under resources/template/ folder.

This template file contains a Header, a greeting with the name of the mail recipient, a greeting message, and an image within the email body.

<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Spring boot send mail example</title>
  </head>
  <body>
    <h2>Sending mail from Spring boot!!</h2>
    <h3>Hi ${name}!!</h3>
	<p>${value}</p>
	<div>
		<a href="https://asbnotebook.com">
			<img src='cid:asbnotebook' alt="ASBNotebook" style="width:10%"/>
			<p>ASB Notebook</p>
		</a>
	</div>
  </body>
</html>

Also, make sure to add the image and PDF file under resources/static/ folder, as shown below.

spring boot email with image and attachment

Testing the application

Start the Spring boot application and send an email request, as shown below.

We are passing the email recipient, email subject, email from, and also the email recipient’s name in this request.

Spring boot email with freemarker

We will get a confirmation message if the email is sent successfully.

If you face issues related to authentication, make sure that the below setting is enabled for your Gmail account.

Spring boot email example.

The below image displays the email received by the recipient.

We can also observe the dynamically generated HTML content, embedded image, and the PDF file attachment.

Spring boot email example

Conclusion

In this post, we learned how to send an email by using the Spring boot application with an attachment. We have also learned how to use the FreeMarker template as the mail body and embedding the image inside the email.

We also added a PDF file as an email attachment.

Example code is available on GitHub.