此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
电子邮件
本节介绍如何使用 Spring Framework 发送电子邮件。
Spring Framework 提供了一个有用的实用程序库,用于发送屏蔽的电子邮件 您从底层邮件系统的具体情况中了解并负责 代表客户端进行低级资源处理。
这org.springframework.mail
package 是 Spring 的根级包
Framework 的电子邮件支持。发送电子邮件的中央界面是MailSender
接口。一个简单的值对象,用于封装简单邮件的属性,例如
如from
和to
(以及许多其他)是SimpleMailMessage
类。这个包
还包含已检查异常的层次结构,这些异常提供更高级别的
对较低级别邮件系统异常的抽象,根异常是MailException
.有关富邮件异常层次结构的更多信息,请参阅 javadoc。
这org.springframework.mail.javamail.JavaMailSender
界面添加专用
JavaMail 功能,例如 MIME 消息支持MailSender
接口
(它继承自它)。JavaMailSender
还提供了一个名为org.springframework.mail.javamail.MimeMessagePreparator
用于准备MimeMessage
.
用法
假设我们有一个名为OrderManager
,如以下示例所示:
-
Java
-
Kotlin
public interface OrderManager {
void placeOrder(Order order);
}
interface OrderManager {
fun placeOrder(order: Order)
}
进一步假设我们有一个要求,规定带有 需要生成订单号并将其发送给下相关订单的客户。
基本MailSender
和SimpleMailMessage
用法
以下示例演示如何使用MailSender
和SimpleMailMessage
发送
当有人下订单时发送电子邮件:
-
Java
-
Kotlin
public class SimpleOrderManager implements OrderManager {
private MailSender mailSender;
private SimpleMailMessage templateMessage;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
@Override
public void placeOrder(Order order) {
// Do the business calculations...
// Call the collaborators to persist the order...
// Create a thread-safe "copy" of the template message and customize it
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
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 {
this.mailSender.send(msg);
}
catch (MailException ex) {
// simply log it and go on...
System.err.println(ex.getMessage());
}
}
}
class SimpleOrderManager : OrderManager {
lateinit var mailSender: MailSender
lateinit var templateMessage: SimpleMailMessage
override fun placeOrder(order: Order) {
// Do the business calculations...
// Call the collaborators to persist the order...
// Create a thread-safe "copy" of the template message and customize it
val msg = SimpleMailMessage(this.templateMessage)
msg.setTo(order.customer.emailAddress)
msg.text = ("Dear " + order.customer.firstName
+ order.customer.lastName
+ ", thank you for placing order. Your order number is "
+ order.orderNumber)
try {
mailSender.send(msg)
} catch (ex: MailException) {
// simply log it and go on...
System.err.println(ex.message)
}
}
}
以下示例显示了上述代码的 Bean 定义:
-
Java
-
Kotlin
-
Xml
@Bean
JavaMailSender mailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("mail.mycompany.example");
return mailSender;
}
@Bean // this is a template message that we can pre-load with default state
SimpleMailMessage templateMessage() {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("[email protected]");
message.setSubject("Your order");
return message;
}
@Bean
SimpleOrderManager orderManager(JavaMailSender mailSender, SimpleMailMessage templateMessage) {
SimpleOrderManager orderManager = new SimpleOrderManager();
orderManager.setMailSender(mailSender);
orderManager.setTemplateMessage(templateMessage);
return orderManager;
}
@Bean
fun mailSender(): JavaMailSender {
return JavaMailSenderImpl().apply {
host = "mail.mycompany.example"
}
}
@Bean // this is a template message that we can pre-load with default state
fun templateMessage() = SimpleMailMessage().apply {
from = "[email protected]"
subject = "Your order"
}
@Bean
fun orderManager(javaMailSender: JavaMailSender, simpleTemplateMessage: SimpleMailMessage) = SimpleOrderManager().apply {
mailSender = javaMailSender
templateMessage = simpleTemplateMessage
}
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.mycompany.example"/>
</bean>
<!-- this is a template message that we can pre-load with default state -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="[email protected]"/>
<property name="subject" value="Your order"/>
</bean>
<bean id="orderManager" class="com.mycompany.businessapp.support.SimpleOrderManager">
<property name="mailSender" ref="mailSender"/>
<property name="templateMessage" ref="templateMessage"/>
</bean>
用JavaMailSender
和MimeMessagePreparator
本节介绍OrderManager
使用MimeMessagePreparator
回调接口。在以下示例中,mailSender
属性的类型为JavaMailSender
以便我们能够使用 JavaMailMimeMessage
类:
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("[email protected]"));
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());
}
}
}
邮件代码是一个跨领域问题,很可能成为
重构为自定义的 Spring AOP 方面,然后可以
在OrderManager 目标。 |
Spring Framework 的邮件支持随标准 JavaMail 实现一起提供。 有关更多信息,请参阅相关的 javadoc。
使用 JavaMailMimeMessageHelper
在处理 JavaMail 消息时非常方便的类是org.springframework.mail.javamail.MimeMessageHelper
,这可以保护您免受
必须使用详细的 JavaMail API。使用MimeMessageHelper
是的
创建MimeMessage
,如以下示例所示:
// 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("[email protected]");
helper.setText("Thank you for ordering!");
sender.send(message);
发送附件和内联资源
多部分电子邮件允许附件和内联资源。示例 内联资源包括要在邮件中使用的图像或样式表,但 您不希望显示为附件。
附件
以下示例向您展示如何使用MimeMessageHelper
发送电子邮件
使用单个 JPEG 图像附件:
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("[email protected]");
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);
内联资源
以下示例向您展示如何使用MimeMessageHelper
发送电子邮件
使用内联图像:
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("[email protected]");
// 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);
内联资源将添加到MimeMessage 通过使用指定的Content-ID
(identifier1234 在上面的例子中)。添加文本的顺序
资源非常重要。请务必先添加文本,然后再添加
资源。如果你反过来做,它就行不通了。 |
使用模板库创建电子邮件内容
前面部分中所示的示例中的代码显式创建了电子邮件的内容
通过使用诸如message.setText(..)
.这对于简单的情况来说很好,而且它
在上述示例的上下文中是可以的,其目的是向您展示
API 的基础知识。
但是,在典型的企业应用程序中,开发人员通常不会创建内容 出于多种原因,使用前面显示的方法的电子邮件:
-
在 Java 代码中创建基于 HTML 的电子邮件内容既乏味又容易出错。
-
显示逻辑和业务逻辑之间没有明确的分离。
-
更改电子邮件内容的显示结构需要编写 Java 代码, 重新编译、重新部署等。
通常,解决这些问题所采取的方法是使用模板库(例如 作为 FreeMarker)来定义电子邮件内容的显示结构。这将留下您的代码 仅负责创建要在电子邮件模板中呈现的数据,并且 发送电子邮件。当您的电子邮件内容 甚至变得中等复杂,并且,使用 Spring Framework 的支持类 FreeMarker,它变得很容易做到。