对于最新的稳定版本,请使用 Spring Framework 6.2.4spring-doc.cadn.net.cn

电子邮件

本节介绍如何使用 Spring Framework 发送电子邮件。spring-doc.cadn.net.cn

库依赖项

以下 JAR 需要位于应用程序的类路径上,以便使用 Spring Framework 的电子邮件支持:spring-doc.cadn.net.cn

此库在 Web 上免费提供 — 例如,在 Maven Central 中为com.sun.mail:jakarta.mail.请确保使用最新的 2.x 版本(使用 这jakarta.mailpackage 命名空间)而不是 Jakarta Mail 1.6.x(使用javax.mailpackage 命名空间)。spring-doc.cadn.net.cn

Spring Framework 提供了一个有用的实用程序库,用于发送电子邮件,该库屏蔽了 您从底层邮件系统的具体情况中了解,并负责 代表客户端进行低级资源处理。spring-doc.cadn.net.cn

org.springframework.mailpackage 是 Spring 的根级包 Framework 的电子邮件支持。发送电子邮件的中央界面是MailSender接口。一个简单值对象,它封装了简单邮件的属性,例如 如fromto(以及许多其他 URL)是SimpleMailMessage类。此软件包 还包含已检查异常的层次结构,这些异常提供更高级别的 抽象对较低级别的邮件系统例外,根例外是MailException.请参阅 javadoc 以了解有关富邮件异常层次结构的更多信息。spring-doc.cadn.net.cn

org.springframework.mail.javamail.JavaMailSenderinterface 添加专用 JavaMail 功能,例如对MailSender接口 (它从中继承)。JavaMailSender还提供了一个名为org.springframework.mail.javamail.MimeMessagePreparator用于准备MimeMessage.spring-doc.cadn.net.cn

用法

假设我们有一个名为OrderManager,如下例所示:spring-doc.cadn.net.cn

public interface OrderManager {

	void placeOrder(Order order);

}

进一步假设我们有一个要求,声明带有 需要生成订单号并将其发送给下达相关订单的客户。spring-doc.cadn.net.cn

基本MailSenderSimpleMailMessage用法

以下示例演示如何使用MailSenderSimpleMailMessage要发送 电子邮件(当有人下订单时):spring-doc.cadn.net.cn

import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

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;
	}

	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());
		}
	}

}

The following example shows the bean definitions for the preceding code:spring-doc.cadn.net.cn

<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>

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:spring-doc.cadn.net.cn

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());
		}
	}

}
The mail code is a crosscutting concern and could well be a candidate for refactoring into a 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.spring-doc.cadn.net.cn

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:spring-doc.cadn.net.cn

// 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);

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.spring-doc.cadn.net.cn

Attachments

The following example shows you how to use the MimeMessageHelper to send an email with a single JPEG image attachment:spring-doc.cadn.net.cn

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);

Inline Resources

The following example shows you how to use the MimeMessageHelper to send an email with an inline image:spring-doc.cadn.net.cn

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);
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.

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.spring-doc.cadn.net.cn

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:spring-doc.cadn.net.cn

  • Creating HTML-based email content in Java code is tedious and error prone.spring-doc.cadn.net.cn

  • There is no clear separation between display logic and business logic.spring-doc.cadn.net.cn

  • Changing the display structure of the email content requires writing Java code, recompiling, redeploying, and so on.spring-doc.cadn.net.cn

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.spring-doc.cadn.net.cn