Send email with inline attachment or resource via Spring

This tutorial will show you how to send a basic mail via Spring framework’s email support. We will attach a resource (an image) as an inline attachment in the email body.

The Spring Framework provides a helpful utility library class that comes in pretty handy when dealing with JavaMail messages is the org.springframework.mail.javamail.MimeMessageHelper class, which shields you from having to use the verbose JavaMail API.

Using the MimeMessageHelper it is pretty easy to create a MimeMessage. Multipart email messages allow for both attachments and inline resources.

Examples of inline resources would be images or a stylesheet you want to use in your message, but that you don’t want displayed as an attachment. Inline resources are added to the mime message using the specified Content-ID (file.getName() in the below example).

The order in which you are adding the text and the resource are very important. Be sure to first add the text and after that the resources. If you are doing it the other way around, it won’t work!

The following example shows you how to use the MimeMessageHelper to send an email along with an inline image.

Prerequisites

Eclipse 2019-12, Java at least 1.8, Gradle 6.4.1, Maven 3.6.3, Spring Boot Mail Starter 2.3.1, Java mail API 1.6.2

Project Setup

Create either gradle or maven based project in Eclipse. The name of the project is spring-email-inline-attachment.

If you are creating gradle based project then you can use below build.gradle script:

buildscript {
	ext {
		springBootVersion = '2.3.1.RELEASE'
	}
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

plugins {
    id 'java-library'
    id 'org.springframework.boot' version "${springBootVersion}"
}

sourceCompatibility = 12
targetCompatibility = 12

repositories {
    mavenCentral()
}

dependencies {
	implementation("org.springframework.boot:spring-boot-starter-mail:${springBootVersion}")
	implementation('javax.mail:javax.mail-api:1.6.2')
}

If you are creating maven based project then you can use below pom.xml file:

<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.roytuts</groupId>
	<artifactId>spring-email-inline-attachment</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.1.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mail</artifactId>
		</dependency>
		
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>javax.mail-api</artifactId>
			<version>1.6.2</version>
		</dependency>
	</dependencies>

    <build>
        <plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>at least 8</source>
					<target>at least 8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Email Configuration

We will create an email configuration class where we will configure SMTP (Simple Mail Transfer Protocol) server details, from email address.

package com.roytuts.spring.email.inline.attachment;

import java.util.Properties;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

@Configuration
public class EmailConfig {

	@Bean
	public JavaMailSender mailSender() {
		JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

		mailSender.setHost("smtp.gmail.com");
		mailSender.setPort(587);
		mailSender.setUsername("[email protected]");
		mailSender.setPassword("gmail password");

		Properties javaMailProperties = new Properties();
		javaMailProperties.put("mail.smtp.auth", true);
		javaMailProperties.put("mail.smtp.starttls.enable", true);

		mailSender.setJavaMailProperties(javaMailProperties);

		return mailSender;
	}

}

We need to issue STARTTLS command otherwise you will get the error message similar to the following:

#smtplib.SMTPSenderRefused: (530, b'5.7.0 Must issue a STARTTLS command first. p7sm24605501pfn.14 - gsmtp', '[email protected]')

You will get below error if your security level is high:

#smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8  https://support.google.com/mail/?p=BadCredentials x10sm26098036pfn.36 - gsmtp')

Therefore you need to lower your Gmail’s security settings.

Email Sender

Email sender class just does the right job for sending the email to the intended recipient.

We have checked whether users want to send HTML message or text message in the email.

We have specified second parameter of MimeMessageHelper class’s constructor’s with true value to indicate that we want to send multipart form data.

We are adding the inline attachment using addInline() method.

package com.roytuts.spring.email.inline.attachment;

import java.io.File;

import javax.mail.internet.MimeMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

@Component
public class EmailSender {

	@Autowired
	private JavaMailSender mailSender;

	public void sendEmailAttachment(final String subject, final String message, final String fromEmailAddress,
			final String toEmailAddresses, final boolean isHtmlMail, final File attachment) {
		try {
			MimeMessage mimeMessage = mailSender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
			helper.setFrom(fromEmailAddress);
			helper.setTo(toEmailAddresses);
			helper.setSubject(subject);

			if (isHtmlMail) {
				helper.setText("<html><body>" + message + "</html></body>", true);
			} else {
				helper.setText(message);
			}

			// attach the file into email body
			FileSystemResource file = new FileSystemResource(attachment);
			helper.addInline(attachment.getName(), file);

			mailSender.send(mimeMessage);

			System.out.println("Email sending complete.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Main Class

A class is having main method with @SpringBootApplication annotation is enough to start up the Spring Boot application.

In this class we specify the subject, message, true flag for an HTML email and the recipient to send the email.

We have also attached an image file sample.jpg to attach as an inline resource in the email body.

package com.roytuts.spring.email.inline.attachment;

import java.io.File;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EmailInlineAttachmentApp implements CommandLineRunner {

	@Autowired
	private EmailSender emailSender;

	public static void main(String[] args) {
		SpringApplication.run(EmailInlineAttachmentApp.class, args);
	}

	@Override
	public void run(String... args) throws Exception {
		emailSender.sendEmailAttachment("Email Inline Attachment", "Email Inline Attachment using MimeMessageHelper",
				"[email protected]", "[email protected]", true, new File("C:/jee_workspace/sample.jpg"));
	}

}

Testing the Application

Now executing the main class will send the email to the intended recipient and you will see the below output in console:

Email sending complete.

Check the inbox you will get a message. If you do not find the message in inbox then check the Spam folder.

I have sent email to myself, so I am seeing me as a from email address.

Email in inbox:

email with inline attachment using spring

Email details:

email with inline attachment using spring

Source Code

Download

Thanks for reading.

Related posts

Leave a Comment