【问题标题】:testing mail with appengine development server (java)使用 appengine 开发服务器 (java) 测试邮件
【发布时间】:2011-03-06 04:02:03
【问题描述】:

我正在使用 javamail 从我的 appengine 应用程序发送邮件。它在部署中完美运行,但我不知道如何使用开发服务器来做到这一点。每当我需要测试 sendmail 时,我都必须部署应用程序,这很烦人。

背景信息(为什么日志不起作用):

我们知道电子邮件会转到 appengine 开发服务器上的日志。但是,想要从开发服务器发送电子邮件的主要原因是能够测试电子邮件的格式。它看起来怎么样?是否需要对电子邮件模板进行更改,使其在电子邮件客户端 A、B 和 C 中看起来不错,并且是否可以快速完成,而无需每次都部署到真实的默认 appengine 版本。

我们不是垃圾邮件发送者。我们不会试图规避任何类型的安全性。简而言之,我们希望能够合法地在一个或多个电子邮件客户端中看到真实的电子邮件,然后立即进行代码更改,以便我们可以调整它们而无需经历编辑、编译、等待 5 分钟的艰苦过程为其部署、测试、重复循环。由于每个电子邮件客户端如何呈现电子邮件没有标准,因此通过尝试让某些东西在许多客户端中工作来放大这个艰苦的过程。

问题:

如何将 Java Google App Engine 开发服务器配置为从本地计算机或 SMTP 服务发送电子邮件,以测试发送到真实电子邮件客户端的电子邮件?

【问题讨论】:

    标签: java google-app-engine email


    【解决方案1】:

    在 Eclipse 中,选择运行菜单、调试配置...,然后选择您应用的 配置。选择参数选项卡,然后在“VM 参数”部分中,设置 VM 像这样的属性:

    -Dmail.log_mail_level=WARNING -Dmail.log_mail_body=true

    【讨论】:

    • 这实际上并没有发送电子邮件,对吧?它只是将原始标记打印到日志中?对吗?
    • 我回答这个问题已经很久了,我真的不记得了。如果你在 Windows 平台上工作,你可以使用 test-mail-server-tool toolheap.com/test-mail-server-tool 来测试邮件是否发送出去。
    【解决方案2】:

    当我使用电子邮件服务实现时,我使用了一个很酷的提示。因此,如果您也使用MimeMessage,并且只想检查邮件的格式是否符合预期、检查附件是否存在、HTML 格式是否正确、图像是否正确引用等等,您可以构建整个邮件,并在调试期间你可以有一些这样的代码:

    MimeMessage msg = new MimeMessage(session);
    ...
    if ("1".equals(System.getProperty("mail.debug"))) {
        msg.writeTo(new FileOutputStream(new File("/tmp/sentEmail.eml")));
    }
    

    每次执行此操作时,MimeMessage 实例都会保存到 emailSent.eml。您可以使用电子邮件阅读器打开此文件并检查是否一切正常。

    当然,您需要使用 -Dmail.debug=1 参数来执行您的应用程序。

    使用这种方法的带有附件、文本消息和 html 消息的示例可能是这样的:

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    import javax.activation.DataHandler;
    import javax.activation.FileDataSource;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.Multipart;
    import javax.mail.Session;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    
    import org.junit.Test;
    
    public class MimeMessageTest {
    
        @Test
        public void tesstMimeMessage() throws MessagingException, FileNotFoundException, IOException {
            Session session = Session.getDefaultInstance(new Properties(), null);
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress("admin@foo.bar", "Foo Admin"));
            msg.addRecipient(Message.RecipientType.TO, new InternetAddress("baz@foo.bar", "Baz User"));
            msg.setSubject("Subject from admin e-mail to baz user");
    
            // create and fill the first message part
            MimeBodyPart mbp1 = new MimeBodyPart();
            mbp1.setText("test message and so on");
            mbp1.setContent("<h1>test message and so on in HTML</h1>", "text/html");
    
            // create the second message part
            MimeBodyPart mbp2 = new MimeBodyPart();
    
            // attach the file to the message
            FileDataSource fds = new FileDataSource("/tmp/fileToBeAttached");
            mbp2.setDataHandler(new DataHandler(fds));
            mbp2.setFileName(fds.getName());
    
            // create the Multipart and add its parts to it
            Multipart mp = new MimeMultipart();
            mp.addBodyPart(mbp1);
            mp.addBodyPart(mbp2);
    
            // add the Multipart to the message
            msg.setContent(mp);
    
            if ("1".equals(System.getProperty("debug"))) {
                msg.writeTo(new FileOutputStream(new File("/tmp/sentEmail.eml")));
            }
        }
    }
    

    【讨论】:

    • 嗨 Spaeth,这看起来很棒!好主意。一个问题,您可以从 GAE 开发服务器写入文件系统,还是在 GAE Java SDK 之外运行它?
    • 我在外面跑GAE但是,如果您无法将其保存到文件中,例如:将其打印到标准输出并复制/粘贴到文件中(因为 mimeMessage 是一个所有附件都经过 Base64 编码的文本文件),这可以是检查附件是否存在、HTML 格式、链接是否正常、图像是否正确引用等的解决方案。因此,您需要进行此更改:msg.writeTo(System.out); 而不是 msg.writeTo(new FileOutputStream(new File("/tmp/sentEmail.eml")));
    • 好的,我已经将整个模板写入输出流,但不是作为电子邮件消息,而是作为模板。这实际上看起来并不需要我很长时间才能实现。我会在周末测试一下。谢谢。
    • 另一种方法,您可以将整个消息保存在商店中并创建一个 servlet 来访问它。如果您只想进行测试,另一种可能性是将最后发送的电子邮件存储在静态字段中,并创建一个 servlet 以使用 mime-type multipart/mixed 下载它
    • Spaeth,这是我在整个互联网上看到的针对这个特定问题的最佳答案! writeTo(System.out) 然后复制/粘贴到文件即可!必须复制/粘贴仍然有点慢,但这是解决自该平台首次引入以来困扰许多 AppEngine 开发人员的问题的一个很好的开始,这就是 提前必须每次部署! +200 先生!
    【解决方案3】:

    来自the docs

    当应用程序在 开发服务器调用邮件 发送电子邮件的服务, 消息被打印到日志中。这 Java开发服务器不发送 电子邮件。

    因此,当您打算发送邮件时,只需检查日志,并确保它显示在那里。不会真正发送真正的邮件。

    【讨论】:

    • 这不行,因为我还需要检查其他的东西;邮件的格式是否正确,附件是否可下载,邮件是否已送达。
    • 你不能用开发服务器做那种集成测试。我建议您在部署中设置它,例如使用单独的应用程序或使用您自己的邮件服务器而不是 App Engine API。
    • @hleinone - 只是想让你知道这个问题有赏金,听起来你可能知道如何解决这个问题。
    • @jmort253 您可能会通过使用第三方邮件提供商(例如 MailChimp mailchimp.com 或 MailGun mailgun.net)获得更好的结果——这些服务专注于电子邮件发送,可能会给您更多选择比 App Engine 做的更好。
    • 嗨,杰森,感谢您的回复。由于对此有赏金,我真的在寻找这种实现的实际示例。到目前为止,包括这里在内的互联网上的大多数答案都只是猜测。再次感谢您的提示,祝您好运! :)
    【解决方案4】:

    GAE 使用 JavaMail,所以让它工作起来并不难。您需要更改两件事。

    首先是为您的 STMP 服务器正确设置 JavaMail 会话。为此,不要使用Session.getDefaultInstance,而是使用Session.getInstance,至少提供mail.smtp.host 属性。请参阅JavaMail SMTP reference,或仅查找通用 JavaMail SMTP 教程。

    第二个变化是您需要停止 GAE 处理您的电子邮件。这样做是因为这条线

    rfc822=gm
    

    在 SDK jar 中的 META-INF/javamail.address.map 中。您可以包含自己的地址映射 - 但这很烦人,因为我假设您只希望它用于调试 - 或者从代码修改地址映射。就是这么简单

    session.setProtocolForAddress("rfc822", "smtp");
    

    在您在第一步中创建的会话上。这应该将您的所有电子邮件路由到标准 SMTP 处理程序。

    【讨论】:

      【解决方案5】:

      您可以执行以下操作在开发服务器上设置电子邮件

      final String username = "xxxxxxxxx@gmail.com";//change accordingly
      final String password = "xxxxxxx";//change accordingly
      
      // Assuming you are sending email through gmail
      String host = "smtp.gmail.com";
      
      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "587");
      
      // Get the Session object.
      Session session = Session.getInstance(props,
      new javax.mail.Authenticator() {
       protected PasswordAuthentication getPasswordAuthentication() {
          return new PasswordAuthentication(username, password);
       }
      });
      session.setProtocolForAddress("rfc822", "smtp");
      

      并正常使用会话发送邮件:

      try {
          Message msg = new MimeMessage(session);
          msg.setFrom(new InternetAddress("xxxx@gmail.com", "xxxx"));
          msg.addRecipient(Message.RecipientType.TO,
          new InternetAddress("user@testdomain.com,"Mr. User"));
          msg.setSubject("Test email from GAE/J development");
          msg.setText("This is test:);
          Transport.send(msg);
      
      } catch (Exception e) {
          e.printStackTrace();
      }
      

      另外你需要在构建路径和war/WEB-INF/lib下添加以下两个库:

      • javax.mail.jar
      • javax.activation.jar

      您可以通过谷歌搜索轻松找到链接。

      最后,如果您想使用 gmail 作为 smtp 服务器,您需要转到您的帐户,并为不太安全的应用程序启用访问权限 https://www.google.com/settings/security/lesssecureapps

      【讨论】:

        【解决方案6】:

        如果其他人偶然发现这个问题,这里是configuring your local GAE server to send mail的说明

        【讨论】:

          猜你喜欢
          • 2018-02-22
          • 2011-02-16
          • 1970-01-01
          • 1970-01-01
          • 2017-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-24
          相关资源
          最近更新 更多