| | + title | Ref. /chapter[1]/title[1] |
| Original | Traduction | Sending Email with Spring mail abstraction layer |
| sect1
| | + title | Ref. /chapter[1]/sect1[1]/title[1] |
| Original | Traduction | Introduction |
|
| + para | Ref. /chapter[1]/sect1[1]/para[1] |
| Original | Traduction | Spring provides a higher level of abstraction for sending electronic
mail which shields the user from the specifics of underlying mailing
system and is responsible for a low level resource handling on behalf of
the client. |
|
| | sect1
| | + title | Ref. /chapter[1]/sect1[2]/title[1] |
| Original | Traduction | Spring mail abstraction structure |
|
| + para | Ref. /chapter[1]/sect1[2]/para[1] |
| Original | Traduction | The main package of Spring mail abstraction layer is
org.springframework.mail package. It contains central
interface for sending emails called MailSender and the
value object which encapsulates properties of a
simple mail such as from, to,
cc, subject,
text called SimpleMailMessage.
This package also contains a hierarchy of checked exceptions which provide
a higher level of abstraction over the lower level mail system exceptions
with the root exception being MailException.Please
refer to JavaDocs for more information on mail exception hierarchy. |
|
| + para | Ref. /chapter[1]/sect1[2]/para[2] |
| Original | Traduction | Spring also provides a sub-interface of MailSender
for specialized JavaMail features such as MIME
messages, namely
org.springframework.mail.javamail.JavaMailSender It
also provides a callback interface for preparation of JavaMail MIME
messages, namely
org.springframework.mail.javamail.MimeMessagePreparator |
|
| + para | Ref. /chapter[1]/sect1[2]/para[3] |
| Original | Traduction | MailSender: | + programlisting | Ref. /chapter[1]/sect1[2]/para[3]/programlisting[1] |
| Original | Traduction | public interface MailSender {
/**
* Send the given simple mail message.
* @param simpleMessage message to send
* @throws MailException in case of message, authentication, or send errors
*/
public void send(SimpleMailMessage simpleMessage) throws MailException;
/**
* Send the given array of simple mail messages in batch.
* @param simpleMessages messages to send
* @throws MailException in case of message, authentication, or send errors
*/
public void send(SimpleMailMessage[] simpleMessages) throws MailException;
} |
| JavaMailSender: | + programlisting | Ref. /chapter[1]/sect1[2]/para[3]/programlisting[2] |
| Original | Traduction | public interface JavaMailSender extends MailSender {
/**
* Create a new JavaMail MimeMessage for the underlying JavaMail Session
* of this sender. Needs to be called to create MimeMessage instances
* that can be prepared by the client and passed to send(MimeMessage).
* @return the new MimeMessage instance
* @see #send(MimeMessage)
* @see #send(MimeMessage[])
*/
public MimeMessage createMimeMessage();
/**
* Send the given JavaMail MIME message.
* The message needs to have been created with createMimeMessage.
* @param mimeMessage message to send
* @throws MailException in case of message, authentication, or send errors
* @see #createMimeMessage
*/
public void send(MimeMessage mimeMessage) throws MailException;
/**
* Send the given array of JavaMail MIME messages in batch.
* The messages need to have been created with createMimeMessage.
* @param mimeMessages messages to send
* @throws MailException in case of message, authentication, or send errors
* @see #createMimeMessage
*/
public void send(MimeMessage[] mimeMessages) throws MailException;
/**
* Send the JavaMail MIME message prepared by the given MimeMessagePreparator.
* Alternative way to prepare MimeMessage instances, instead of createMimeMessage
* and send(MimeMessage) calls. Takes care of proper exception conversion.
* @param mimeMessagePreparator the preparator to use
* @throws MailException in case of message, authentication, or send errors
*/
public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException;
/**
* Send the JavaMail MIME messages prepared by the given MimeMessagePreparators.
* Alternative way to prepare MimeMessage instances, instead of createMimeMessage
* and send(MimeMessage[]) calls. Takes care of proper exception conversion.
* @param mimeMessagePreparators the preparator to use
* @throws MailException in case of message, authentication, or send errors
*/
public void send(MimeMessagePreparator[] mimeMessagePreparators) throws MailException;
} |
| MimeMessagePreparator: | + programlisting | Ref. /chapter[1]/sect1[2]/para[3]/programlisting[3] |
| Original | Traduction | public interface MimeMessagePreparator {
/**
* Prepare the given new MimeMessage instance.
* @param mimeMessage the message to prepare
* @throws MessagingException passing any exceptions thrown by MimeMessage
* methods through for automatic conversion to the MailException hierarchy
*/
void prepare(MimeMessage mimeMessage) throws MessagingException;
} |
|
|
|
| | sect1
| | + title | Ref. /chapter[1]/sect1[3]/title[1] |
| Original | Traduction | Using Spring mail abstraction |
|
| + para | Ref. /chapter[1]/sect1[3]/para[1] |
| Original | Traduction | Let's assume there is a business interface called
OrderManager | + programlisting | Ref. /chapter[1]/sect1[3]/para[1]/programlisting[1] |
| Original | Traduction | public interface OrderManager {
void placeOrder(Order order);
} |
| and there is a use case that says that an email message
with order number would need to be generated and sent to a customer
placing that order. So for this purpose we want to use
MailSender and
SimpleMailMessage |
| Please note that as usual, we work with interfaces in the
business code and let Spring IoC container take care of wiring of all the
collaborators for us. | + para | Ref. /chapter[1]/sect1[3]/para[3] |
| Original | Traduction | Here is the implementation of OrderManager
| + programlisting | Ref. /chapter[1]/sect1[3]/para[3]/programlisting[1] |
| Original | Traduction | import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
public class OrderManagerImpl implements OrderManager {
private MailSender mailSender;
private SimpleMailMessage message;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setMessage(SimpleMailMessage message) {
this.message = message;
}
public void placeOrder(Order order) {
//... * Do the business calculations....
//... * Call the collaborators to persist the order
//Create a thread safe "sandbox" of the message
SimpleMailMessage msg = new SimpleMailMessage(this.message);
msg.setTo(order.getCustomer().getEmailAddress());
msg.setText(
"Dear "
+ order.getCustomer().getFirstName()
+ order.getCustomer().getLastName()
+ ", thank you for placing order. Your order number is "
+ order.getOrderNumber());
try{
mailSender.send(msg);
}
catch(MailException ex) {
//log it and go on
System.err.println(ex.getMessage());
}
}
} |
| Here is what the bean definitions for the code above would
look like: |
|
| + programlisting | Ref. /chapter[1]/sect1[3]/programlisting[1] |
| Original | Traduction | <bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host"><value>mail.mycompany.com</value></property>
</bean>
<bean id="mailMessage"
class="org.springframework.mail.SimpleMailMessage">
<property name="from"><value>customerservice@mycompany.com</value></property>
<property name="subject"><value>Your order</value></property>
</bean>
<bean id="orderManager"
class="com.mycompany.businessapp.support.OrderManagerImpl">
<property name="mailSender"><ref bean="mailSender"/></property>
<property name="message"><ref bean="mailMessage"/></property>
</bean> |
|
| + para | Ref. /chapter[1]/sect1[3]/para[4] |
| Original | Traduction | Here is the implementation of OrderManager using
MimeMessagePreparator callback interface. Please note
that the mailSender property is of type JavaMailSender
in this case in order to be able to use JavaMail MimeMessage:
| + programlisting | Ref. /chapter[1]/sect1[3]/para[4]/programlisting[1] |
| Original | Traduction | import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;
public class OrderManagerImpl 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 MessagingException {
mimeMessage.setRecipient(Message.RecipientType.TO,
new InternetAddress(order.getCustomer().getEmailAddress()));
mimeMessage.setFrom(new InternetAddress("mail@mycompany.com"));
mimeMessage.setText(
"Dear "
+ order.getCustomer().getFirstName()
+ order.getCustomer().getLastName()
+ ", thank you for placing order. Your order number is "
+ order.getOrderNumber());
}
};
try{
mailSender.send(preparator);
}
catch(MailException ex) {
//log it and go on
System.err.println(ex.getMessage());
}
}
} |
|
|
|
| + para | Ref. /chapter[1]/sect1[3]/para[5] |
| Original | Traduction | If you want to use JavaMail MimeMessage to the full power, the
MimeMessagePreparator is available at your
fingertips. |
| Please note that the mail code is a crosscutting concern
and is a perfect candidate for refactoring into a custom Spring AOP advice,
which then could easily be applied to OrderManager target. Please see the
AOP chapter.sect2
| | + title | Ref. /chapter[1]/sect1[3]/sect2[1]/title[1] |
| Original | Traduction | Pluggable MailSender implementations |
|
| + para | Ref. /chapter[1]/sect1[3]/sect2[1]/para[1] |
| Original | Traduction | Spring comes with two MailSender implementations out of the box -
the JavaMail implementation and the implementation on top of Jason
Hunter's MailMessage class that's included in
http://servlets.com/cos
(com.oreilly.servlet). Please refer to JavaDocs for more
information. |
|
| |
| | sect1
| | + title | Ref. /chapter[1]/sect1[4]/title[1] |
| Original | Traduction | Using the JavaMail MimeMessageHelper |
|
| + para | Ref. /chapter[1]/sect1[4]/para[1] |
| Original | Traduction |
One of the components that comes in pretty handy when dealing with
JavaMail messages is the org.springframework.mail.javamail.MimeMessageHelper.
It prevents you from having to use the nasty APIs the the javax.mail.internet classes.
A couple of possible scenarios:
|
| sect2
| | + title | Ref. /chapter[1]/sect1[4]/sect2[1]/title[1] |
| Original | Traduction | Creating a simple MimeMessage and sending it |
|
| + para | Ref. /chapter[1]/sect1[4]/sect2[1]/para[1] |
| Original | Traduction |
Using the MimeMessageHelper it's pretty easy to setup and send a MimeMessage:
| + programlisting | Ref. /chapter[1]/sect1[4]/sect2[1]/para[1]/programlisting[1] |
| Original | Traduction |
// of course you would setup the mail sender using
// DI in any real-world cases
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");
MimeMessage message = sender.createMimeMesage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo("test@host.com");
helper.setText("Thank you for ordering!");
sender.send(message);
|
|
|
|
| | sect2
| | + title | Ref. /chapter[1]/sect1[4]/sect2[2]/title[1] |
| Original | Traduction | Sending attachments and inline resources |
|
| + para | Ref. /chapter[1]/sect1[4]/sect2[2]/para[1] |
| Original | Traduction |
Email allow for attachments, but also for inline resources in multipart
messages. Inline resources could for example be images or stylesheet you
want to use in your message, but don't want displayed as attachment.
The following shows you how to use the MimeMessageHelper to send an
email along with an inline image.
| + programlisting | Ref. /chapter[1]/sect1[4]/sect2[2]/para[1]/programlisting[1] |
| Original | Traduction |
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");
MimeMessage message = sender.createMimeMesage();
// 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);
// if you would need to include the file as an attachment, use
// addAttachment() methods on the MimeMessageHelper
sender.send(message);
|
|
Inline resources are added to the mime message using the Content-ID specified
as you've seen just now (identifier1234 in this case). The order in
which you're adding the text and the resource are VERY important. First add the text
and after that the resources. If you're doing it the other way around, it won't work!
|
|
| |
| |
|