Spring邮件抽象层的主要包为org.springframework.mail。它包括了发送电子邮件的主要接口MailSender和 封装了简单邮件的属性如from, to,cc, subject, text的值对象叫做SimpleMailMessage。 一个以MailException为root的checked Exception继承树,它们提供了对底层邮件系统异常的高级别抽象。 请参考JavaDocs来得到关于邮件异常层次的更多的信息。
为了使用JavaMail中的一些特色如MIME类型的消息,Spring也提供了一个MailSender的子接口, 名为org.springframework.mail.javamail.JavaMailSender,同时也提供了一个对JavaMail的MIME类型的消息分块的回调interface, 名为org.springframework.mail.javamail.MimeMessagePreparator
MailSender:
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:
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:
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;
}让我们来假设有一个业务接口名为OrderManager
public interface OrderManager {
void placeOrder(Order order);
}同时有一个use case为:需要生成带有订单号的email信息,并向客户发送该订单。 为了这个目的我们会使用MailSender和SimpleMailMessage。
请注意,通常情况下,我们在业务代码中使用接口而让Spring ioc容器负责组装我们需要的合作者。
这里为OrderManager的一个实现
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 businness calculations....
//... * Call the collaborators to persist the order
//Create a threadsafe "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());
}
}
}上面的代码的bean的定义应该是这样的:
<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>[email protected]</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>下面是OrderManager的实现,使用了MimeMessagePreparator回调接口。 请注意这里的mailSender属性类型为JavaMailSender,这样做是为了能够使用JavaMail的MimeMessage:
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 businness 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("[email protected]"));
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());
}
}
}如果你想使用JavaMail MimeMessage以获得全部的能力,只需要你指尖轻触键盘即可使用MimeMessagePreparator。
请注意这部分邮件代码是一个横切关注点,是一个可以重构至一个定制的SpringAOP advice的完美候选者, 这样就可以不费力的应用到目标对象OrderManager上来。关于这一点请看AOP章节。
Spring提供两种MailSender的实现:标准的JavaMail实现和在http://servlets.com/cos (com.oreilly.servlet)里的Jason Hunter's MailMessage类之上的实现。请参考JavaDocs以得到进一步的信息。