Simple Java Mail的使用

劳昊明
2023-12-01

Simple Java Mail是一个非常强大的邮件发送框架,非常值得使用。

本文翻译Simple Java Mail的官方实例文档,可以参考使用。

官方网站:http://www.simplejavamail.org/#/about

原文:http://www.simplejavamail.org/#/features

基本用法

创建Email,填充你的数据,创建Mailer然后发送Email实例,mailer也可以是你自己的Session实例。
Mailer 是单例模式。

Email email = new Email();

email.setFromAddress("Michel Baker", "m.baker@mbakery.com");
email.addNamedToRecipient("mom", "jean.baker@hotmail.com");
email.addNamedToRecipient("dad", "StevenOakly1963@hotmail.com");
email.setSubject("My Bakery is finally open!");
email.setText("Mom, Dad. We did the opening ceremony of our bakery!!!");

new Mailer("server", 25, "username", "password").sendMail(email);

使用建造者模式的流式接口

前一个例子用流式接口可以更简洁。

    Email email = new EmailBuilder()
    .from("Michel Baker", "m.baker@mbakery.com")
    .to("mom", "jean.baker@hotmail.com")
    .to("dad", "StevenOakly1963@hotmail.com")
    .subject("My Bakery is finally open!")
    .text("Mom, Dad. We did the opening ceremony of our bakery!!!")
    .build();

    new Mailer("server", 25, "username", "password").sendMail(email);

一次配置多次使用

    你可以预配置一个Mailer,然后无限次使用

    Mailer inhouseMailer = new Mailer("server", 25, "username", "password");

    inhouseMailer.sendMail(email);
    inhouseMailer.sendMail(anotherEmail);


    或者配置成一个Spring Bean 

    <bean id="inhouseMailer" class="org.simplejavamail.mailer.Mailer">
       <constructor-arg value="server" />
       <constructor-arg value="25" />
       <constructor-arg value="username" />
       <constructor-arg value="password" />
    </bean>


    或者用Spring的默认值

    @Autowired Mailer mailer; // configured completely using default properties

几乎所有都可以替代的API

有几种方法可以在电子邮件中做几乎所有的事情,只是为了适应你已经拥有的东西。

Email:

// You can add your own Recipient instances for example
email.addRecipients(yourRecipient1, yourRecipient2...);

// or add comma / semicolon separated addresses (without names)
String list = "twister@sweets.com,blue.tongue@sweets.com;honey@sweets.com";
emailNormal.addBccRecipients(list);
// or:
emailNormal.addNamedToRecipients("maintenance group", list);

// what about a group with one deviating name?
String list = "bob@sweets.com, gene@sweets.com; Security Group <security@sweets.com>";
emailNormal.addNamedToRecipients("stakeholders", list);
// bob and gene are named "stakeholders", "Security Group" get its own name

EmailBuilder:

.to(yourRecipient1, yourRecipient2...)
.cc("stakeholders", "bob@sweets.com", "gene@sweets.com", "Security Group <security@sweets.com>")
.cc("stakeholders", "bob@sweets.com, gene@sweets.com; Security Group <security@sweets.com>")
.bcc("twister@sweets.com,blue.tongue@sweets.com;honey@sweets.com")
...
.build();

Through properties:

simplejavamail.defaults.bcc.name=
simplejavamail.defaults.bcc.address=twister@sweets.com,blue.tongue@sweets.com;honey@sweets.com

异步并行批量发送

默认是同步的发送方式,闭塞执行直到email被处理且返回成功的结果。
你也可以异步或者批量发送,或者使用fire-and-forget发送方式
如果认证的代理接口正在被使用,这个接口会一直保持到最后一封发送完毕。
依靠SMTP 服务(和代理服务如果可以)这个可以快速发送。

mailer.sendMail(email, true);

用自己的Session实例发送

如果你更喜欢使用预配置的Session实例发送,仍然可以使用。
    Email email = new Email();
    ...

    new Mailer(yourSession).sendMail(email);

在发送的电子邮件中设置自定义邮件ID

消息ID通常由底层的JavaMail框架生成,但如果需要,您可以提供自己的框架。
只需确保您自己的id符合rfc5322 msg-id格式标准

Email email = new Email()
    email.setId("<123@456>");

Or:
Email email = new EmailBuilder()
    .id("<123@456>")
    .build();

用SSL和TLS发送

激活SSL或TLS是非常简单的。 只需使用适当的TransportStrategy枚举。

Email email = new Email();

mailer.sendMail(email, TransportStrategy.SMTP_PLAIN); // default if omitted
mailer.sendMail(email, TransportStrategy.SMTP_SSL);
mailer.sendMail(email, TransportStrategy.SMTP_TLS);

SSL和TLS与Google邮件

这里有个例子关于用SSL和TLS使用gMail。
如果您启用two-factor(双重认证)登录,则需要从Google帐户生成专用密码。

new Mailer("smtp.gmail.com", 25, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 587, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 465, "your user", "your password", TransportStrategy.SMTP_SSL).sendMail(email);

添加附件

你可以轻松添加附件,但您必须自己提供数据。 简单的Java Mail接受byte []和DataSource对象。

Email email = new Email();

email.addAttachment("dresscode.txt", new ByteArrayDataSource("Black Tie Optional", "text/plain"));
email.addAttachment("location.txt", "On the moon!".getBytes(Charset.defaultCharset()), "text/plain");

// ofcourse it can be anything: a pdf, doc, image, csv or anything else

email.addAttachment("invitation.pdf", new FileDataSource("invitation_v8.3.pdf"));

嵌入图片

嵌入图片比较简单,但是你必须自己在HTML中添加占位符

Email email = new Email();

email.addEmbeddedImage("smiley", new FileDataSource("smiley.jpg"));
// this example is included in the demo package in MailTestApp.java
String base64String = "iVBORw0KGgoAAAANSUhEUgAAA ...snip";
email.addEmbeddedImage("thumbsup", parseBase64Binary(base64String), "image/png");

// the corresponding HTML should contain the placeholders
<p>Let's go!</p><img src='cid:thumbsup'><br/>
<p>Smile!</p><img src='cid:smiley'>

设置自定义标题

有时候你的电子邮件需要额外的标题,因为你的电子邮件服务器,收件人服务器或者你的的电子邮件客户端需要, 
又或者你需要在邮件服务器之间建立代理或监控设置。 无论如何,添加标题很容易。

Email email = new Email();

email.addHeader("X-Priority", 2);
email.addHeader("X-MC-GoogleAnalyticsCampaign", "halloween_sale");
email.addHeader("X-MEETUP-RECIP-ID", "71415272");
email.addHeader("X-my-custom-header", "foo");

在内部会话中设置自定义属性

如果你需要修改内部Session对象,那需要你基础的javax.mail支持来配置,这也非常简单。

Properties props = new Properties();
props.setProperty("mail.smtp.timeout", 30 * 1000);
props.setProperty("mail.smtp.connectiontimeout", 10 * 1000);

Mailer mailer = new Mailer();
mailer.applyProperties(props);

直接访问会话内部

对于紧急情况,你还可以获取内部会话实例本身。虽然你不太可能需要它,如果这样做意味着Simple Java Mail 无法简化你的配置过程。
请让我们知道如何帮助缓解这种需求。

Mailer mailer = new Mailer();

Session session = mailer.getSession();
// do your thing with session

用DKIM签名电子邮件

Simple Java Mail还支持使用DKIM域密钥进行签名。 
它使用java-utils-mail-dkim(依赖性打包)来执行给定域上的DNS DKIM记录检查。

Email signedEmail = new Email();

signedEmail.signWithDomainKey(
   privateKey byte[] / File / InputStream,
   "your_domain.org",
   "your_selector");

new Mailer().sendMail(signedEmail);

配置传送/读取收据

对于支持它的服务器和客户端(主要是Outlook),Simple Java Mail已经内置了“送货收据”和“读取收据”的支持,
这可以通过标题分别返回收货和处理通知。

你可以明确定义电子邮件地址以将收据退回到或其他Simple Java Mail将默认为replyTo地址(如果可用)或其他fromAddress。

Email email = new Email();
email.setUseDispositionNotificationTo();
email.setUseReturnReceiptTo();
// or:
email.setDispositionNotificationTo(new Recipient("name", "address@domain.com"));
email.setReturnReceiptTo(new Recipient("name", "address@domain.com"));

// or:
Email email = new EmailBuilder()
  (..)
  .withDispositionNotificationTo()
  .withReturnReceiptTo()
  // or:
  .withDispositionNotificationTo("on-read@domain.com")
  .withReturnReceiptTo("name", "on-delivery@domain.com")
  .build();

验证邮箱地址

Simple Java Mail可以验证你的邮箱地址。不是简单的正则匹配,而是针对RFC-2822的完整和强大的完整验证。 
它通过在库中包含电子邮件-rfc2822验证器来实现。


EmailAddressValidator.isValid("your_address@domain.com",
   EmailAddressCriteria.RFC_COMPLIANT);

// or, fine-tuned to be less strict:
EmailAddressValidator.isValid("your_address@domain.com",
   of(ALLOW_QUOTED_IDENTIFIERS, ALLOW_PARENS_IN_LOCALPART));

Email, MimeMessage, EML and Outlook .msg之间的转换

使用Simple Java Mail你可以轻松装换其他类型。
比如,如果你需要MimeMessage,你可以转换Email,EML数据甚至Outlook .msg文件。

如果你已经有MimeMessage,您可以将它变成一个Email实例,其中包含嵌入图像和附件,标题不变。

如果你喜欢,你甚至可以构建一个大量的Outlook .msg到EML转换器!

// from Email
String eml =              EmailConverter.emailToEML(yourEmail);
MimeMessage mimeMessage = EmailConverter.emailToMimeMessage(yourEmail);
MimeMessage mimeMessage = EmailConverter.emailToMimeMessage(yourEmail, yourSession);

// from MimeMessage
Email email =             EmailConverter.mimeMessageToEmail(yourMimeMessage);
String eml =              EmailConverter.mimeMessageToEML(yourMimeMessage);

// from EML
Email email =             EmailConverter.emlToEmail(emlDataString);
MimeMessage mimeMessage = EmailConverter.emlToMimeMessage(emlDataString);
MimeMessage mimeMessage = EmailConverter.emlToMimeMessage(emlDataString, yourSession);

// from Outlook .msg
Email email =             EmailConverter.outlookMsgToEmail(readToString("yourMessage.msg"));
Email email =             EmailConverter.outlookMsgToEmail(new File("yourMessage.msg"));
Email email =             EmailConverter.outlookMsgToEmail(getInputStream("yourMessage.msg"));
String eml =              EmailConverter.outlookMsgToEML(readToString("yourMessage.msg"));
String eml =              EmailConverter.outlookMsgToEML(new File("yourMessage.msg"));
String eml =              EmailConverter.outlookMsgToEML(getInputStream("yourMessage.msg"));
MimeMessage mimeMessage = EmailConverter.outlookMsgToMimeMessage(readToString("yourMessage.msg"));
MimeMessage mimeMessage = EmailConverter.outlookMsgToMimeMessage(new File("yourMessage.msg"));
MimeMessage mimeMessage = EmailConverter.outlookMsgToMimeMessage(getInputStream("yourMessage.msg"));

使用代理发送

Simple Java Mail支持通过代理发送电子邮件。 它也是世界上唯一支持通过身份验证的代理发送电子邮件的Java邮件框架。

原因是底层本机Javax Mail框架支持匿名SOCKS5代理,但不支持身份验证代理。

为了使此工作通过身份验证,Simple Java Mail使用一个技巧:它设置一个临时匿名代理服务器为Javax Mail连接到,
然后中继连接到目标代理执行Javax Mail之外的身份验证。

该临时服务器称为代理桥接服务器。

// anonymous proxy
new Mailer(serverConfig, new ProxyConfig("proxy.host.com", 1080));

// authenticated proxy
new Mailer(serverConfig, new ProxyConfig("proxy.host.com", 1080, "proxy username", "proxy password"));
 类似资料: