You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
8.8 KiB
234 lines
8.8 KiB
[[mail]] |
|
= Email |
|
|
|
This section describes how to send email with the Spring Framework. |
|
|
|
.Library dependencies |
|
**** |
|
The following JAR needs to be on the classpath of your application in order to use the |
|
Spring Framework's email support: |
|
|
|
* The https://jakartaee.github.io/mail-api/[Jakarta Mail] library |
|
|
|
This library is freely available on the web -- for example, in Maven Central as |
|
`org.eclipse.angus:angus-mail`. |
|
**** |
|
|
|
The Spring Framework provides a helpful utility library for sending email that shields |
|
you from the specifics of the underlying mailing system and is responsible for |
|
low-level resource handling on behalf of the client. |
|
|
|
The `org.springframework.mail` package is the root level package for the Spring |
|
Framework's email support. The central interface for sending emails is the `MailSender` |
|
interface. A simple value object that encapsulates the properties of a simple mail such |
|
as `from` and `to` (plus many others) is the `SimpleMailMessage` class. This package |
|
also contains a hierarchy of checked exceptions that provide a higher level of |
|
abstraction over the lower level mail system exceptions, with the root exception being |
|
`MailException`. See the {spring-framework-api}/mail/MailException.html[javadoc] |
|
for more information on the rich mail exception hierarchy. |
|
|
|
The `org.springframework.mail.javamail.JavaMailSender` interface adds specialized |
|
JavaMail features, such as MIME message support to the `MailSender` interface |
|
(from which it inherits). `JavaMailSender` also provides a callback interface called |
|
`org.springframework.mail.javamail.MimeMessagePreparator` for preparing a `MimeMessage`. |
|
|
|
|
|
|
|
[[mail-usage]] |
|
== Usage |
|
|
|
Assume that we have a business interface called `OrderManager`, as the following example shows: |
|
|
|
include-code::./OrderManager[tag=snippet,indent=0] |
|
|
|
Further assume that we have a requirement stating that an email message with an |
|
order number needs to be generated and sent to a customer who placed the relevant order. |
|
|
|
|
|
[[mail-usage-simple]] |
|
=== Basic `MailSender` and `SimpleMailMessage` Usage |
|
|
|
The following example shows how to use `MailSender` and `SimpleMailMessage` to send an |
|
email when someone places an order: |
|
|
|
include-code::./SimpleOrderManager[tag=snippet,indent=0] |
|
|
|
The following example shows the bean definitions for the preceding code: |
|
|
|
include-code::./MailConfiguration[tag=snippet,indent=0] |
|
|
|
|
|
[[mail-usage-mime]] |
|
=== Using `JavaMailSender` and `MimeMessagePreparator` |
|
|
|
This section describes another implementation of `OrderManager` that uses the `MimeMessagePreparator` |
|
callback interface. In the following example, the `mailSender` property is of type |
|
`JavaMailSender` so that we are able to use the JavaMail `MimeMessage` class: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes"] |
|
---- |
|
import jakarta.mail.Message; |
|
import jakarta.mail.MessagingException; |
|
import jakarta.mail.internet.InternetAddress; |
|
import jakarta.mail.internet.MimeMessage; |
|
|
|
import jakarta.mail.internet.MimeMessage; |
|
import org.springframework.mail.MailException; |
|
import org.springframework.mail.javamail.JavaMailSender; |
|
import org.springframework.mail.javamail.MimeMessagePreparator; |
|
|
|
public class SimpleOrderManager implements OrderManager { |
|
|
|
private JavaMailSender mailSender; |
|
|
|
public void setMailSender(JavaMailSender mailSender) { |
|
this.mailSender = mailSender; |
|
} |
|
|
|
public void placeOrder(final Order order) { |
|
// Do the business calculations... |
|
// Call the collaborators to persist the order... |
|
|
|
MimeMessagePreparator preparator = new MimeMessagePreparator() { |
|
public void prepare(MimeMessage mimeMessage) throws Exception { |
|
mimeMessage.setRecipient(Message.RecipientType.TO, |
|
new InternetAddress(order.getCustomer().getEmailAddress())); |
|
mimeMessage.setFrom(new InternetAddress("mail@mycompany.example")); |
|
mimeMessage.setText("Dear " + order.getCustomer().getFirstName() + " " + |
|
order.getCustomer().getLastName() + ", thanks for your order. " + |
|
"Your order number is " + order.getOrderNumber() + "."); |
|
} |
|
}; |
|
|
|
try { |
|
this.mailSender.send(preparator); |
|
} |
|
catch (MailException ex) { |
|
// simply log it and go on... |
|
System.err.println(ex.getMessage()); |
|
} |
|
} |
|
|
|
} |
|
---- |
|
|
|
NOTE: The mail code is a crosscutting concern and could well be a candidate for |
|
refactoring into a xref:core/aop.adoc[custom Spring AOP aspect], which could then |
|
be run at appropriate joinpoints on the `OrderManager` target. |
|
|
|
The Spring Framework's mail support ships with the standard JavaMail implementation. |
|
See the relevant javadoc for more information. |
|
|
|
|
|
|
|
[[mail-javamail-mime]] |
|
== Using the JavaMail `MimeMessageHelper` |
|
|
|
A class that comes in pretty handy when dealing with JavaMail messages is |
|
`org.springframework.mail.javamail.MimeMessageHelper`, which shields you from |
|
having to use the verbose JavaMail API. Using the `MimeMessageHelper`, it is |
|
pretty easy to create a `MimeMessage`, as the following example shows: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes"] |
|
---- |
|
// of course you would use DI in any real-world cases |
|
JavaMailSenderImpl sender = new JavaMailSenderImpl(); |
|
sender.setHost("mail.host.com"); |
|
|
|
MimeMessage message = sender.createMimeMessage(); |
|
MimeMessageHelper helper = new MimeMessageHelper(message); |
|
helper.setTo("test@host.com"); |
|
helper.setText("Thank you for ordering!"); |
|
|
|
sender.send(message); |
|
---- |
|
|
|
|
|
[[mail-javamail-mime-attachments]] |
|
=== Sending Attachments and Inline Resources |
|
|
|
Multipart email messages allow for both attachments and inline resources. Examples of |
|
inline resources include an image or a stylesheet that you want to use in your message but |
|
that you do not want displayed as an attachment. |
|
|
|
[[mail-javamail-mime-attachments-attachment]] |
|
==== Attachments |
|
|
|
The following example shows you how to use the `MimeMessageHelper` to send an email |
|
with a single JPEG image attachment: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes"] |
|
---- |
|
JavaMailSenderImpl sender = new JavaMailSenderImpl(); |
|
sender.setHost("mail.host.com"); |
|
|
|
MimeMessage message = sender.createMimeMessage(); |
|
|
|
// use the true flag to indicate you need a multipart message |
|
MimeMessageHelper helper = new MimeMessageHelper(message, true); |
|
helper.setTo("test@host.com"); |
|
|
|
helper.setText("Check out this image!"); |
|
|
|
// let's attach the infamous windows Sample file (this time copied to c:/) |
|
FileSystemResource file = new FileSystemResource(new File("c:/Sample.jpg")); |
|
helper.addAttachment("CoolImage.jpg", file); |
|
|
|
sender.send(message); |
|
---- |
|
|
|
[[mail-javamail-mime-attachments-inline]] |
|
==== Inline Resources |
|
|
|
The following example shows you how to use the `MimeMessageHelper` to send an email |
|
with an inline image: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes"] |
|
---- |
|
JavaMailSenderImpl sender = new JavaMailSenderImpl(); |
|
sender.setHost("mail.host.com"); |
|
|
|
MimeMessage message = sender.createMimeMessage(); |
|
|
|
// use the true flag to indicate you need a multipart message |
|
MimeMessageHelper helper = new MimeMessageHelper(message, true); |
|
helper.setTo("test@host.com"); |
|
|
|
// use the true flag to indicate the text included is HTML |
|
helper.setText("<html><body><img src='cid:identifier1234'></body></html>", true); |
|
|
|
// let's include the infamous windows Sample file (this time copied to c:/) |
|
FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg")); |
|
helper.addInline("identifier1234", res); |
|
|
|
sender.send(message); |
|
---- |
|
|
|
WARNING: Inline resources are added to the `MimeMessage` by using the specified `Content-ID` |
|
(`identifier1234` in the above example). The order in which you add the text |
|
and the resource are very important. Be sure to first add the text and then |
|
the resources. If you are doing it the other way around, it does not work. |
|
|
|
|
|
[[mail-templates]] |
|
=== Creating Email Content by Using a Templating Library |
|
|
|
The code in the examples shown in the previous sections explicitly created the content of the email message, |
|
by using methods calls such as `message.setText(..)`. This is fine for simple cases, and it |
|
is okay in the context of the aforementioned examples, where the intent was to show you |
|
the very basics of the API. |
|
|
|
In your typical enterprise application, though, developers often do not create the content |
|
of email messages by using the previously shown approach for a number of reasons: |
|
|
|
* Creating HTML-based email content in Java code is tedious and error prone. |
|
* There is no clear separation between display logic and business logic. |
|
* Changing the display structure of the email content requires writing Java code, |
|
recompiling, redeploying, and so on. |
|
|
|
Typically, the approach taken to address these issues is to use a template library (such |
|
as FreeMarker) to define the display structure of email content. This leaves your code |
|
tasked only with creating the data that is to be rendered in the email template and |
|
sending the email. It is definitely a best practice when the content of your email messages |
|
becomes even moderately complex, and, with the Spring Framework's support classes for |
|
FreeMarker, it becomes quite easy to do.
|
|
|