Files
rikako-note/spring/spring email/spring email.md
2023-07-28 15:25:42 +08:00

6.3 KiB
Raw Permalink Blame History

Email

spring framework提供了工具库用于发送邮件并且并不依赖具体的底层邮件系统。

org.springframework.mail包是spring邮件系统的root package用于发送邮件的接口为MailSender。封装邮件属性的对象为SimpleMailMessage其封装了邮件主要的属性例如from和to

root package也包含了一套checked exception结构root exception类型为MailException.

org.springframework.mail.javamail.JavaMailSender接口则是添加了专门的JavaMail特性例如对MIME消息的支持从MailSender接口继承JavaMailSender也提供了一个回调接口org.springframework.mail.javamail.MimeMessagePreparator用于准备Mime信息。

使用示例

MailSender使用和SimpleMailMessage使用

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

}

使用JavaMailSender和MimeMessagePreparator

如下示例通过MimeMessagePreparator来发送MimeMessage

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

}

使用MimeMessageHelper

通过使用org.springframework.mail.javamail.MimeMessageHelper可以避免复杂的JavaMail API通过其创建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("test@host.com");
helper.setText("Thank you for ordering!");

sender.send(message);

发送附件和内联资源

多数邮件消息都允许使用附件和inline resource。inline resource包含图片、样式表等但是不希望以附件的形式来显示inline resource。

附件

如下实例显示了如何通过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("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);

inline resource

如下示例显示了如何通过MimeMessageHelper来发送带有inline resource的邮件

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

Spring Boot集成

如果java.mail.host和相应的库(spring-boot-starter-mail)存在一个默认的JavaMailSender将会被自动创建如果JavaMailSender不存在自己创建的bean对象

某些timeout值默认情况下是无限的应该手动为其指定值避免在邮件服务器未响应时线程被阻塞

spring.mail.properties[mail.smtp.connectiontimeout]=5000
spring.mail.properties[mail.smtp.timeout]=3000
spring.mail.properties[mail.smtp.writetimeout]=5000