使用 JAVA Mail API 的连续电子邮件服务器连接

Posted

技术标签:

【中文标题】使用 JAVA Mail API 的连续电子邮件服务器连接【英文标题】:Continuous email server Connection using JAVA Mail API 【发布时间】:2012-01-06 03:31:06 【问题描述】:

我们打算开发一种服务,该服务始终保持连接到电子邮件服务器,这样每当用户触发邮件时,它就会通过使用连接发送而不是获得新的连接并发送邮件。 是否有可能我们始终使用 JAVA Mail API 保持与电子邮件服务器的连接?? 请帮助我。

【问题讨论】:

【参考方案1】:

当您连接到 SMTP 服务器时(也使用javax.mail API 时),您使用套接字连接(参见SMTPTransport and Transport classes 的源代码)。套接字允许您连接到远程服务器,并且该连接保持打开状态,直到显式关闭。这意味着理论上您可以创建一个连接并让他们重用它。

但是,许多 SMTP 服务器非常邪恶,会终止连接 if you are using it "too slow" 或 if you try to resuse your SMTP session to often。 (我为您查找了postfix 设置。)

Java Mail API 允许您创建连接并随时关闭它。嗯。像这样:

        Transport transport = session.getTransport("smtp");
        transport.connect();
        transport.sendMessage(msg, addressArray);
        // you can do transport.close(); later

但是,由于 SMTP 服务器的实际情况,您不能只执行一次connect() 而忘记它。最多,您可以做的是通过再次重新连接来正确处理强制断开连接。 Java Mail API 中有一个通知机制可以做到这一点(看看notifyConnectionListeners 方法的用法)

【讨论】:

感谢您的快速回复,我会检查并回复您。 嗨,我试过上面的代码,它工作正常,但有一个问题。如果我想使用与消息类型相同的连接连续发送消息作为 html(MinmeMessage 和 MimeBodyPart),则上一条消息将附加到下一封邮件中。你知道它附加的原因吗? 嗨,忽略上面的评论,我试过上面的代码,它工作正常,再次感谢。【参考方案2】:

但是,由于 SMTP 服务器的实际情况,您不能只 执行一次 connect() 并忘记它。最多,你能做的,是 通过重新连接正确处理强制断开连接。

同意!

您实际上可以使用以下逻辑重用 JavaMail SMTP 连接:

Transport transport = null;
MimeMessage message = null;

Properties prop = new Properties();
// load all smtp properties

Session session = Session.getDefaultInstance(prop, null);
transport = session.getTransport("smtp");

for (EachMail eachMail : list) 
    if (!transport.isConnected()) 
        if (port != null && port.length() > 0) 
            transport.connect(host, Integer.parseInt(port), "<username>", "<password>");
         else 
            transport.connect(host, "<username>", "<password>");
        
    

    // set all mail attributes from eachMail object
    message.saveChanges();
    transport.sendMessage(message, message.getAllRecipients());

像魅力一样工作。干杯!

【讨论】:

【参考方案3】:

如果你想要一个始终在线的连接,你应该在发送方法之外创建你的传输,但是为了避免发送时出现异常(SMTPSendFailedException 421 超时数据客户端),你应该检查传输是否连接,如果没有再次连接它发送前:

 if (!transport.isConnected())//make sure the connection is alive
            transport.connect();
 transport.sendMessage(message, message.getAllRecipients());

【讨论】:

以上是关于使用 JAVA Mail API 的连续电子邮件服务器连接的主要内容,如果未能解决你的问题,请参考以下文章

Java调用api使用企业邮箱账户发送邮件

Java实战-用Java mail实现Exchange发邮件给你喜欢的人

SpringBoot Mail邮件任务

SpringBoot Mail邮件任务

通过 apache common java api 转发带有附件的电子邮件(使用 JavaMailApi 读取)

通过java api验证SMTP服务器身份验证(包括AUTH的Healthcheck)