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
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.
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
Plz try to make use of MimeTypes to allow only the specific extensions . And not sure about virus free. You would probably go for it if ur charging excess for it xD
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
dude , Seriously . you just have to take multiple inputs in “toMail” variable by seperating it with a ” ; “
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
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
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
http://stackoverflow.com/questions/13951322/javamail-email-commons-empty-message-gives-strange-error
Can you please tell me how to send email using JavaMailSender to a DistributionList or DL in outlook
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
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
Great post, added my understanding massively, I’m now sending e-mails with attachments. Thanks.
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
Can you anyone know how to send the email In HTML format? If so, kindly reply me.
Check the docs: http://static.springsource.org/spring/docs/2.0.x/reference/mail.html#mail-javamail-mime-attachments-inline
Please reply, how to attache multiple files?
Hi Mkyoung, Thanks for very Nice Tutorial.
could you please tell, how to attach multiple files ?
Thanks in advance,
Bharatkumar
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
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
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)
Hi Yong,
In case of multiple attachment what changes i need to do.
Thanks
Jitendra
Hi Yong,
how to send in HTML Format?
Tks;
Good Article. It really helped me get the clarity on the configuration part.
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
Hi Rudi,
Did you configure the setter method for the simpleMailMessage? It look like the property can not set.
If you did configured it, pls zip your project and send to me.
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