Scala通过office365的SMTP服务发送邮件

问题描述

最近项目中需要用到office365发送mirror邮件,并且必须要用scala代码解决
以下是scala发送邮件的代码

所用到jar的pom是

  <dependency>
      <groupId>com.typesafe.play</groupId>
      <artifactId>play-mailer_2.11</artifactId>
      <version>7.0.0</version>
  </dependency>

这是发送邮件的code

    val subject = "This is a Mail" //邮件主题
    val file = new File("file path") //附件文件
    val attachment: Attachment = AttachmentFile(name, file) //附件
    val from = "xxxx@xxx.com" //邮件发送地址
    val to = Seq("xxxx@xxx.com", "xxxx@xxx.com",...)  //邮件送达地址
    val bodyHtml = Option(
      s"""
        |<html>
        |<body>
        |<h1 align="center">your html text body</h1>
        |</body>
        |</html>
      """.stripMargin)
    val charset = Option("utf-8") // 字符编码 默认utf-8
    val attachments: Seq[Attachment] = Seq(attachment) // 生成一个seq序列
    val email = Email(subject, from, to, None, bodyHtml, charset, attachments = attachments) // 生成邮件
    
    // STMP服务参数
    val host = "" // STMP服务地址
    val port = "" // STMP服务端口号
    val user = Option("") // STMP服务用户邮箱
    val password = Option("") // STMP服务邮箱密码
    val timeout = Option(10000) //setSocketTimeout 默认60s
    val connectionTimeout = Option(10000) //setSocketTimeout 默认60s
    val configuration: SMTPConfiguration = new SMTPConfiguration(
      host, port, false, false, false,
      user, password, false, timeout,
      connectionTimeout, ConfigFactory.empty(), false) // STMP服务SMTPConfiguration
    val mailer: SMTPMailer = new SMTPMailer(configuration)

    mailer.send(email) // 发送邮件

这时候问题来了,以下是SMTPConfiguration class的source code

case class SMTPConfiguration(
    host: String,
    port: Int,
    ssl: Boolean = false,
    tls: Boolean = false,
    tlsRequired: Boolean = false,
    user: Option[String] = None,
    password: Option[String] = None,
    debugMode: Boolean = false,
    timeout: Option[Int] = None,
    connectionTimeout: Option[Int] = None,
    props: Config = ConfigFactory.empty(),
    mock: Boolean = false
)

这是网上找到office365的邮件客户端的配置
在这里插入图片描述可以看到case class SMTPConfiguration对于office365来说只有IMAP加密方法TLS和POP加密方法 TLS,但是官方要求SMTP的加密方式必须是STARTTLS

解决方案

我们知道java mail中使用Properties这个类来设置mail的配置,而scala底层又是用java写的
于是回看SMTPConfiguration这个类

case class SMTPConfiguration(
    host: String,
    port: Int,
    ssl: Boolean = false,
    tls: Boolean = false,
    tlsRequired: Boolean = false,
    user: Option[String] = None,
    password: Option[String] = None,
    debugMode: Boolean = false,
    timeout: Option[Int] = None,
    connectionTimeout: Option[Int] = None,
    props: Config = ConfigFactory.empty(),
    mock: Boolean = false
)

我们会发现有个props是config类

    props: Config = ConfigFactory.empty()

点进props中看,会跳到abstract class CommonsMailer的createEmail方法中,有这么一段code

// After the email was set up we can now also manipulate the session properties directly
    val mailProperties = email.getMailSession.getProperties();
    conf.props.entrySet().asScala.foreach(prop => {
      mailProperties.setProperty("mail.smtp." + prop.getKey(), prop.getValue().unwrapped().toString)
      mailProperties.setProperty("mail.smtps." + prop.getKey(), prop.getValue().unwrapped().toString)
    })
    email.setMailSession(Session.getInstance(mailProperties, authenticator.orNull))

发现这其实和java mail中使用Properties的功能非常类似
回到props处,点进ConfigFactory类中,会发现里面有个方法叫做parseProperties,返回的居然就是config类型的Properties

/**
     * Like {@link #parseProperties(Properties, ConfigParseOptions)} but uses default
     * parse options.
     * @param properties
     *            a Java Properties object
     * @return the parsed configuration
     */
    public static Config parseProperties(Properties properties) {
        return parseProperties(properties, ConfigParseOptions.defaults());
    }

可以看到官方注释中表明到这就是java Properties object
于是大胆猜测可以在这里设置STARTTLS属性
以下是解决方案的code

	//增加部分
 	val properties = new Properties()
    properties.put("starttls.enable", "true")
    
    val configuration: SMTPConfiguration = new SMTPConfiguration(
      mailHost, mailPort, false, false, false,
      Option(mailUser), Option(mailPassword), false, Option(timeout),
      Option(connectionTimeout), ConfigFactory.parseProperties(properties), false)
    new SMTPMailer(configuration)

增加一个properties属性,并做如下设置,使用ConfigFactory.parseProperties(properties)填入SMTP配置中即可解决

后话

本文仅适用于使用office365的SMTP服务发送邮件的情况,笔者在网上没找相应的解决方案后想到发此文,但也应会有比我更好的解决方案。初次写文难免有顾及不周之处,请各位见谅,欢迎各位大佬来讨论和指导!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值