Spring – Sending e-mail with attachment

Here’s an example to use Spring to send e-mail that has attachments via Gmail SMTP server. In order to contains the attachment in your e-mail, you have to use Spring’s JavaMailSender & MimeMessage , instead of MailSender & SimpleMailMessage.

1. Project dependency

Add the JavaMail and Spring’s dependency.

File : pom.xml


<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mkyong.common</groupId>
  <artifactId>SpringExample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SpringExample</name>
  <url>http://maven.apache.org</url>
  
  <repositories>
  	<repository>
  		<id>Java.Net</id>
  		<url>http://download.java.net/maven/2/</url>
  	</repository>
  </repositories>
  
  <dependencies>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    
    <!-- Java Mail API -->
    <dependency>
	    <groupId>javax.mail</groupId>
	    <artifactId>mail</artifactId>
	    <version>1.4.3</version>
    </dependency>
    
    <!-- Spring framework -->
    <dependency>
     	<groupId>org.springframework</groupId>
	    <artifactId>spring</artifactId>
	    <version>2.5.6</version>
    </dependency>
    
  </dependencies>
</project>

2. Spring’s Mail Sender

You have to use JavaMailSender instead of MailSender to send attachments, and attach the resources with MimeMessageHelper. In this example, it will get the “c:\\log.txt” text file from your file system (FileSystemResource) as an e-mail attachment.

Beside file system, you can also get any resources from URL path(UrlResource), Classpath (ClassPathResource), InputStream (InputStreamResource)… please refer to Spring’s AbstractResource implemented classes.

File : MailMail.java


package com.mkyong.common;

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

import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.MailParseException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

public class MailMail
{
	private JavaMailSender mailSender;
	private SimpleMailMessage simpleMailMessage;
	
	public void setSimpleMailMessage(SimpleMailMessage simpleMailMessage) {
		this.simpleMailMessage = simpleMailMessage;
	}

	public void setMailSender(JavaMailSender mailSender) {
		this.mailSender = mailSender;
	}
	
	public void sendMail(String dear, String content) {
	
	   MimeMessage message = mailSender.createMimeMessage();
		
	   try{
		MimeMessageHelper helper = new MimeMessageHelper(message, true);
			
		helper.setFrom(simpleMailMessage.getFrom());
		helper.setTo(simpleMailMessage.getTo());
		helper.setSubject(simpleMailMessage.getSubject());
		helper.setText(String.format(
			simpleMailMessage.getText(), dear, content));
			
		FileSystemResource file = new FileSystemResource("C:\\log.txt");
		helper.addAttachment(file.getFilename(), file);

	     }catch (MessagingException e) {
		throw new MailParseException(e);
	     }
	     mailSender.send(message);
         }
}

3. Bean configuration file

Configure the mailSender bean, email template and specify the email details for the Gmail SMTP server.

File : Spring-Mail.xml


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
	<property name="host" value="smtp.gmail.com" />
	<property name="port" value="587" />
	<property name="username" value="username" />
	<property name="password" value="password" />
		
	<property name="javaMailProperties">
		<props>
           	<prop key="mail.smtp.auth">true</prop>
           	<prop key="mail.smtp.starttls.enable">true</prop>
       	</props>
	</property>
</bean>
	
<bean id="mailMail" class="com.mkyong.common.MailMail">
	<property name="mailSender" ref="mailSender" />
	<property name="simpleMailMessage" ref="customeMailMessage" />
</bean>
	
<bean id="customeMailMessage"
	class="org.springframework.mail.SimpleMailMessage">

	<property name="from" value="[email protected]" />
	<property name="to" value="[email protected]" />
	<property name="subject" value="Testing Subject" />
	<property name="text">
	<value>
		<![CDATA[
			Dear %s,
			Mail Content : %s
		]]>
	</value>
    </property>
</bean>

</beans>

4. Run it


package com.mkyong.common;

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

public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
            new ClassPathXmlApplicationContext("Spring-Mail.xml");
    	 
    	MailMail mm = (MailMail) context.getBean("mailMail");
        mm.sendMail("Yong Mook Kim", "This is text content");
        
    }
}

output


 Dear Yong Mook Kim,
 Mail Content : This is text content
 
 Attachment : log.txt

Download Source Code

27 comments on “Spring – Sending e-mail with attachment

  1. How do you scan an attachment before uploading? my requirement is to allow only speci extension types and also to amke sure its virus free

  2. this says: org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
    nested exception is:
    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

  3. Hi Mkyoung,
    Thanks for the nice POST .This is very useful to me.
    I need one more thing in the above code.
    i.e. how to send mail to multiple users using the same code?.can u share this as well.

    regards,
    Hemant Singh

  4. hi,

    can you please provide me a example to send a mail along with a link to access the same application using spring mvc?

    Thanks,

    Gowtham. A

  5. Thank You mkyong. Can you please specify how to not hard code the file path and keep it relative and place the file within the web application path

  6. Pls help me on this issue when take this article and execute. It is behaving so differently some time protocal issues some time data type issues. Here am getting exception recently below snippet. Thanks in advance..ASAP help me

    org.springframework.mail.MailSendException: Failed messages: javax.mail.MessagingException: IOException while sending message;
    nested exception is:
    javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
    boundary=”—-=_Part_0_1221956599.1384766127208″; message exception details (1) are:
    Failed message 1:
    javax.mail.MessagingException: IOException while sending message;
    nested exception is:
    javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
    boundary=”—-=_Part_0_1221956599.1384766127208″
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1177)
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:416)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:336)
    at com.brzee.controller.MailUtil.sendEmailNotify(MailUtil.java:64)
    at com.brzee.controller.HelloWorldController.helloWorld(HelloWorldController.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
    boundary=”—-=_Part_0_1221956599.1384766127208″
    at javax.activation.ObjectDataContentHandler.writeTo(Unknown Source)
    at javax.activation.DataHandler.writeTo(Unknown Source)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1485)
    at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1773)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1121)
    … 35 more

  7. Hi mkyong,

    Thanks for the article. its very helpful.

    I am having problem running this example, getting below error. Appreciate if you could help on this.

    Thanks in Advance.

    Exception in thread “main” java.lang.NullPointerException
    at com.pp.api.email.MailMail.sendMail(MailMail.java:26)
    at com.pp.api.email.MailMail.main(MailMail.java:49)

    Thanks,
    Narasim

  8. Hi Mkyoung, thank you for your tutorial. But need your help!

    I have a problem: I am using Spring MVC but without Maven.
    I added sing-2.5.6.jar to project’s Java Build Path
    I added to dispatcher-servlet.xml exactly code from your Spring-Mail.xml
    and getting error:
    SEVERE: Allocate exception for servlet dispatcher
    java.lang.ClassNotFoundException: org.springframework.mail.javamail.JavaMailSenderImpl

    Thank you,
    Rimma

  9. 12/08/13 17:41:23 INFO support.ClassPathXmlApplicationContext: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1a0c10f: display name [org.springframework.context.support.ClassPathXmlApplicationContext@1a0c10f]; startup date [Mon Aug 13 17:41:23 IST 2012]; root of context hierarchy
    12/08/13 17:41:23 INFO xml.XmlBeanDefinitionReader: Loading XML bean definitions from class path resource [Spring-Mail.xml]
    12/08/13 17:41:23 INFO support.ClassPathXmlApplicationContext: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@1a0c10f]: org.springframework.beans.factory.support.DefaultListableBeanFactory@86fe26
    12/08/13 17:41:24 INFO support.DefaultListableBeanFactory: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@86fe26: defining beans [mailSender,mailMail,customeMailMessage]; root of factory hierarchy
    Exception in thread “main” org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 25;
    nested exception is:
    java.net.ConnectException: Connection timed out: connect
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:419)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:342)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:338)
    at com.mkyong.common.MailMail.sendMail(MailMail.java:43)
    at com.mkyong.common.App.main(App.java:13)
    Caused by: javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 25;
    nested exception is:
    java.net.ConnectException: Connection timed out: connect
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1282)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:370)
    at javax.mail.Service.connect(Service.java:275)
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:389)
    … 4 more
    Caused by: java.net.ConnectException: Connection timed out: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:529)
    at java.net.Socket.connect(Socket.java:478)
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:232)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:189)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1250)
    … 7 more

  10. Hi Mkyoung, Thanks for very Nice Tutorial.
    could you please tell, how to attach multiple files ?

    Thanks in advance,

    Bharatkumar

  11. Hii Yong,

    I have sent email with attachment.
    Now i want to attach multiple files.
    so what changes i should do in previous code ?

    Thanks and Regards
    Kinjan Ajudiya

  12. Hello,
    My name is Kinjan Ajudiya.
    I am software Engineer.
    I tried hard to find code for attachment with email.But at last i found from this post .Thank you very much..

    Thanks and Regards
    Kinjan Ajudiya

  13. Hi , I get this error

    EVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    java.lang.NoClassDefFoundError: javax/mail/MessagingException
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
    at java.lang.Class.getDeclaredConstructors(Class.java:1836)

  14. Hi,

    Thanks for the article. Very informative.

    I’m having a problem running the example here in
    https://mkyong.com/spring/spring-sending-e-mail-with-attachment/

    The problem is org.springframework.beans.factory.BeanCreationException: error creating bean with name mailMail defined in class path Spring-Mail.xml. Initialization of bean failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property ‘simpleMailMessage’ of class MailMail. No property found.

    However, simpleMailMessage is there just as the code shows.

    Any help is appreciated. Thanks in advance.

    Have a great day.

    Best regards,

    Rudi

    1. Hi Rudi,

      Did you configure the setter method for the simpleMailMessage? It look like the property can not set.

      public void setSimpleMailMessage(SimpleMailMessage simpleMailMessage) {
      		this.simpleMailMessage = simpleMailMessage;
      	}
      

      If you did configured it, pls zip your project and send to me.

      1. Hi Yong,

        Thank you for the reply.

        I got the example to work. The problem was with the setter name that I had typed starting with uppercase. Sorry about that.

        I made that setter name lowercase. Then I created the log file and added some jars that the project needed.

        Have a great day. Thanks again for the help and the articles
        that you post. This is a great site. 🙂

        Best regards,

        Rudi

Leave a Comment

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