【问题标题】:Cannot send email from Play framework无法从 Play 框架发送电子邮件
【发布时间】:2013-09-26 07:29:21
【问题描述】:

我正在尝试使用 Play Framework 发送电子邮件。在 applications.conf 中,当我设置 smtp.mock=true 时,它​​运行良好:

[info] application - HTML: Welcome to Play20StartApp. <br> Click on this link : http://localhost:9000/confirm/d77ea256-0d2e-4df5-b66e-e034159f8042 to confirm your email.<br><br>--<br>null
[debug] application - Mail sent - SMTP:smtp.google.com:465 SSL:yes user:username@gmail.com password:password

但是,当我评论 smtp.mock=true 并尝试发送真实电子邮件时,我收到此错误:

[debug] application - Mail.sendMail: Mail will be sent to user1@gmail.com
[ERROR] [09/26/2013 03:46:05.014] [application-akka.actor.default-dispatcher-2] [TaskInvocation] From address required
org.apache.commons.mail.EmailException: From address required

我已将 smtp.user 设置为适当的值,即 server@businessdomain.com 。知道是什么导致了这个错误吗?

故障排除步骤

  1. 使用的电子邮件是真实的电子邮件,出于发布的目的,它们是匿名的。同样,使用真实域名
  2. 使用工作的本地邮件服务器 (exim) 进行测试,以及通过 Gmail (smtp.google.com) 和 Google Apps (aspmx.l.google.com) 服务器直接发送。这些设置已使用邮件客户端进行验证。
  3. 下面的Java代码sn-p完美运行,

    导入 java.util.; 导入 javax.mail.; 导入 javax.mail.internet.; 导入 javax.activation.;

    public class SendEmail
    {
        public static void main(String [] args)
        {
            String to = "recipient@mydomain.com";
            String from = "sender@mydomain.com";
            String host = "localhost";
    
            Properties properties = System.getProperties();
    
            // Setup mail server
            properties.setProperty("mail.smtp.host", host);
    
            // Get the default Session object.
            Session session = Session.getDefaultInstance(properties);
    
            try{
                MimeMessage message = new MimeMessage(session);
    
                // Set From: header field of the header.
                message.setFrom(new InternetAddress(from));
    
                message.addRecipient(Message.RecipientType.TO,
                        new InternetAddress(to));
                message.setSubject("Subject of email");
                message.setText("This is actual message");
    
                Transport.send(message);
                System.out.println("Sent message successfully....");
            }catch (MessagingException mex) {
                mex.printStackTrace();
            }
        }
    }
    

【问题讨论】:

  • 我对 Play 框架一无所知;它没有使用您在上面发布的(工作)Java 代码吗?您实际上是在电子邮件消息中设置发件人地址,还是只是用于验证的 SMTP 用户名?
  • 不,它没有使用 Java 代码。我使用具有确切电子邮件配置(从、到、smtp 服务器)的 Java 代码只是为了确保问题不在于 SMTP/传输位。即普通 javax.mail 有效。当我尝试从 Play Framework 发送电子邮件时,它失败并抱怨表单地址无效。
  • 那么我的猜测是你需要告诉 Play Framework 设置 From 地址,而只是设置 SMTP 用户。
  • @BillShannon 没错。这就是我在 application.conf 文件中所做的 smtp.host=smtp.google.com smtp.port=465 smtp.from="my.email@gmail.com" 那没有用。
  • 看来您需要一位 Play Framework 专家。尝试在Play Framework users list 上发帖。

标签: java playframework jakarta-mail playframework-2.2


【解决方案1】:

如果您将邮件操作包装在 Future(或 Play Java 等效项)中,那么您遇到的可能是变量范围问题:

这行得通:

val mail = use[MailerPlugin].email
val async: Future[Unit] = Future{
  mail.setSubject(subject)
  mail.setRecipient(recipient)
  mail.setFrom(from)
  mail.send(body)
}
async.onFailure{case(e)=>
  Logger.error(s"mailer failed for $recipient due to: ${e.getMessage}")
}

行不通

val mail = use[MailerPlugin].email
mail.setSubject(subject)
mail.setRecipient(recipient)
mail.setFrom(from)
val async: Future[Unit] = Future{mail.send(body)}
async.onFailure{case(e)=>
  Logger.error(s"mailer failed for $recipient due to: ${e.getMessage}")
}

我假设封闭范围在 Future 闭包中可用;在这种情况下,绝对不是因为底层的 Apache Commons 邮件程序使用“需要发件人地址”来保释。果然,设置 smtp.mock=true 表明当 mail.setFrom 和朋友在 Future{...} 范围之外填充时 fromAddress 为 null。

有趣的是,即使我将 async val 分解为本地方法并传入构造的邮件和正文:

private def async(mail: MailerAPI, body: String): Future[Unit] = Future{
  mail.send(body)
}

尽管直接传递了一个构造的邮件程序,但在 Future 之外设置的邮件属性仍然为 null —— 令人惊讶,不是吗?

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    相关资源
    最近更新 更多