Send email with multiple attachments via Spring

This tutorial will show you how to send a basic mail via Spring framework’s email support. The Spring Framework provides a helpful utility library for sending email that shields the user from the specifics of the underlying mailing system and is responsible for low level resource handling on behalf of the client. I will show you both annotation based Spring Boot application and XML based Spring application using gradle and maven to send email with multiple attachments.

A 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.
The following example shows you how to use the MimeMessageHelper to send an email along with multiple attachments.

Prerequisites

At least Java 8, Eclipse 4.12, Gradle 5.6, Maven 3.6.1, Spring Boot 2.2.1, Spring 5.2.2

Create Project

You may create either maven or gradle based project in Eclipse.

If you are creating maven based project then you need to follow the below settings:

  • Create a standalone project – maven-arctype-quickstart.
  • Group Id : com.roytuts
  • Artifact Id : spring-email-multiple-attachments

Modify the pom.xml file with the below content:

<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-multiple-attachments</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
	
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.version>at least 1.8</jdk.version>
        <java.mail.version>1.6.2</java.mail.version>
        <spring.version>5.2.2.RELEASE</spring.version>
    </properties>
	
    <dependencies>
        <!-- Spring framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
		
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
		
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
		
        <!-- Java Mail API -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>${java.mail.version}</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

If you are creating gradle based project then make sure the project name is spring-email-multiple-attachments.

Now modify the build.gradle script to have the required dependencies. For annotation based application we are creating Spring Boot application.

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

plugins {
    id 'java-library'
    id 'org.springframework.boot' version '2.2.2.RELEASE'
}

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'
}

Create Email Configuration

Create an XML file spring-email-config.xml under classpath directory src/main/resources. It is obvious that this XMl file is created for maven based standalone project.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com" />
        <property name="port" value="587" />
        <property name="username" value="gmail@gmail.com" />
        <property name="password" value="******" />
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.smtp.auth">true</prop>
            </props>
        </property>
    </bean>
	
    <bean id="emailSender" class="com.roytuts.spring.email.multiple.attachments.sender.EmailSender">
        <property name="mailSender" ref="javaMailSender" />
    </bean>
</beans>

Now we will create the similar email configuration for Spring Boot application.

package com.roytuts.spring.email.multiple.attachments.config;

import java.util.Properties;

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

@Configuration
public class EmailConfig {

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

		mailSender.setHost("smtp.gmail.com");
		mailSender.setPort(587);
		mailSender.setUsername("gmail@gmail.com");
		mailSender.setPassword("gmail pass");

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

		mailSender.setJavaMailProperties(javaMailProperties);

		return mailSender;
	}

}

Email Sender

Create below EmailSender class that will send email with attachments. This class is used with maven based project.

package com.roytuts.spring.email.multiple.attachments.sender;

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;

public class EmailSender {

	@Autowired
	private JavaMailSender mailSender;

	public void sendEmailMultiAttachment(final String subject, final String message, final String fromEmailAddress,
			final String toEmailAddress, final File[] attachments, final boolean isHtmlMail) {

		try {
			MimeMessage mimeMessage = mailSender.createMimeMessage();

			// use the true flag to indicate you need a multipart message
			MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

			helper.setFrom(fromEmailAddress);
			helper.setTo(toEmailAddress);
			helper.setSubject(subject);

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

			// add the file attachment
			for (File file : attachments) {
				FileSystemResource fr = new FileSystemResource(file);
				helper.addAttachment(file.getName(), fr);
			}

			mailSender.send(mimeMessage);

			System.out.println("Email sending with multiple attachments complete.");

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

        public void setMailSender(JavaMailSender mailSender) {
             this.mailSender = mailSender;
        }

}

The below class is used with Spring Boot application. This class has annotation @Component and does not have setter method for the property mailSender.

package com.roytuts.spring.email.multiple.attachments.sender;

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 sendEmailMultiAttachment(final String subject, final String message, final String fromEmailAddress,
			final String toEmailAddress, final File[] attachments, final boolean isHtmlMail) {

		try {
			MimeMessage mimeMessage = mailSender.createMimeMessage();

			// use the true flag to indicate you need a multipart message
			MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

			helper.setFrom(fromEmailAddress);
			helper.setTo(toEmailAddress);
			helper.setSubject(subject);

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

			// add the file attachment
			for (File file : attachments) {
				FileSystemResource fr = new FileSystemResource(file);
				helper.addAttachment(file.getName(), fr);
			}

			mailSender.send(mimeMessage);

			System.out.println("Email sending with multiple attachments complete.");

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Send Email with Attachments

We will create a class with main method to send email with multiple attachments.

The files are kept into the project’s root directory.

For standalone maven based application use below class.

import java.io.File;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.roytuts.spring.email.multiple.attachments.sender.EmailSender;

public class EmailSenderTest {
    private EmailSender emailSender;
	
    @Before
    public void setUp() throws Exception {
        @SuppressWarnings("resource")
        
    }
	
    public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-email-config.xml");
        EmailSender emailSender = applicationContext.getBean("emailSender", EmailSender.class);
		
        File attachment1 = new File("employee_report.csv");
		File attachment2 = new File("sample.pdf");

		File[] attachments = new File[] { attachment1, attachment2 };

		emailSender.sendEmailMultiAttachment("How are you ?",
				"Hello, <i>How are you ?</i> <br/> Please open attachments to view the files.", "gmail@gmail.com",
				"gmail@gmail.com", attachments, true);
    }
}

For Spring Boot application use below class.

package com.roytuts.spring.email.multiple.attachments;

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;

import com.roytuts.spring.email.multiple.attachments.sender.EmailSender;

@SpringBootApplication(scanBasePackages = "com.roytuts.spring.email.multiple.attachments")
public class SpringEmailMultipleAttachmentsApp implements CommandLineRunner {

	@Autowired
	private EmailSender emailSender;

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

	@Override
	public void run(String... args) throws Exception {

		File attachment1 = new File("employee_report.csv");
		File attachment2 = new File("sample.pdf");

		File[] attachments = new File[] { attachment1, attachment2 };

		emailSender.sendEmailMultiAttachment("How are you ?",
				"Hello, <i>How are you ?</i> <br/> Please open attachments to view the files.", "gmail@gmail.com",
				"gmail@gmail.com", attachments, true);

	}

}

Testing the Application

Now run the above main class, you will see the below output in console:

Email sending with multiple attachments complete.

Verify Gmail Inbox

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

As I have sent from my gmail address to my gmail address, so the from email address you see as me in the above image.

email spring multiple attachments

When you open the message you will see below output as shown in the image:

email spring multiple attachments

If you get the below error while sending email using Gmail SMTP server

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')

Then you need to lower your Gmail’s security settings to send email from your gmail address.

Source Code

Download

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *