【问题标题】:How to receive Email in Java EE application如何在 Java EE 应用程序中接收电子邮件
【发布时间】:2011-02-08 06:49:02
【问题描述】:

显然,通过 JavaMail 从 Java EE 应用程序发送电子邮件并不难。我感兴趣的是接收电子邮件的最佳模式(主要是通知退回)?我对基于 IMAP/POP3 的方法(轮询收件箱)不感兴趣 - 我的应用程序应对入站电子邮件做出反应

我能想到的一种方法是

  • 保留现有的 MTA(在我的例子中是 linux 上的 postfix)-> 运维团队已经知道如何配置/操作它
  • 对于每封到达的邮件,生成一个 Java 应用程序来接收数据并通过 JMS 发送出去。我可以通过 /etc/aliases 中的条目来做到这一点,例如 myuser: "|/path/to/javahelper",使用 javahelper 调用 Java 应用程序,并传递 STDIN。
  • MDB(Java EE 应用程序的一部分)接收 JMS 消息,对其进行解析,检测退回消息并采取相应措施。

另一种方法可能是

  • 在 Java EE 应用程序容器的端口 25 上打开一个监听网络套接字。
  • 将 SessionBean 与套接字关联。 Bean 是 Java EE 应用程序的一部分,可以直接解析/检测退回/处理消息。
  • 将现有 MTA 保留为入站中继,执行所有安全/垃圾邮件过滤,但将电子邮件转发到 myuser(通过过滤器)到 Java EE 应用程序容器的端口 25。

我以前做过的第一种方法(尽管使用不同的语言/设置)。

从性能和(感知的)清洁度的角度来看,我认为第二种方法更好,但它需要我提供适当的 SMTP 传输实现。另外,我不知道是否可以将网络套接字与bean连接......

您的建议是什么?你有关于第二种方法的详细信息吗?

【问题讨论】:

  • 你最终选择了哪种方法?
  • 这个项目被搁置了很长一段时间。现在我正在再次处理它,但我还没有实现接收部分。到目前为止,我的计划是按照 sleske 的建议,通过 IMAP 定期扫描电子邮件收件箱。
  • 去掉 op 1 中的 jms,然后通过生成的 curl/http 将它发送到一个 rest 端点,你就可以剪掉 conf/complexity 的一部分(JMS/MDB)。
  • @alphazero - 谢谢,但 JMS 不是问题,OP 是关于接收电子邮件的最佳模式。
  • @hank - 明白。指出 JMS 不是必需的。它肯定了模式 1:使用(主动)外部系统通过 REST 将邮件推送到 JEE 容器。

标签: java email jakarta-ee smtp ejb-3.0


【解决方案1】:

也许SubEtha SMTP [编辑:现在从 Google 代码重新定位到 GitHub] 会很有趣——它是一个 Java 库,允许您的应用程序接收 SMTP 邮件。我准备试试看。

这是一个有点相关的 Stack Overflow 问题(有人建议使用 SubEthaSMP):
What is the easiest way for a Java application to receive incoming email?

【讨论】:

    【解决方案2】:

    根据 Java EE 架构,“正确”的方法是使用 JCA 连接器与 SMTP 服务器进行入站/出站连接。

    JCA 连接器可以做任何你想做的事情,包括线程和使用套接字连接到外部系统。实际上,JMS 只是一种特殊的 JCA 连接器,它连接到 JMS 代理并将消息传递到“常规”MDB。然后,JCA 连接器可以轮询 SMTP 服务器并将消息传递到自定义 MDB。

    关于 JCA 的最佳文档是Creating Resource Adapters with J2EE Connector Architecture 1.5,它确实使用了电子邮件传递的示例。祝你好运:) 我建议你看看它。该代码可以作为 Java EE 示例的一部分找到并使用 JavaMail,但我不知道它是否已准备好生产。

    相关:

    【讨论】:

    • 这看起来很复杂... 为什么不直接实现一个无状态 EJB 来定期检查新电子邮件(使用计时器服务)? JCA 方法是否在性能、可靠性等方面给我带来任何额外的优势?
    • @Theo 您确实可以使用 EJB 计时器或从 ServletContextListener 生成线程。我已经将两者都用于后台作业,但根据 JEE“哲学”,此类基础设施应该由应用程序服务器本身或 JCA 连接器处理,而不是应用程序代码的一部分。此外,基础设施设置(如 SMTP 设置)不应被视为与 env-entry 的“业务”设置相同。但归根结底,这是一个设计纯度问题,以及您希望它完成的工作。因此,请继续使用对您来说最简单的方法。
    • ewernli 在这里是 100% 正确的(事实上,这听起来像是一个非常有潜力的 OSS 项目)。 您在容器管理的功能集之外所做的任何事情包含在 JEE 应用程序服务器的 SLA 中。如果您开始跨容器分发,这将变得特别重要。
    • 我之前在生产环境中使用过示例中的 JCA Inbound Mail 连接器。 (交互式营销,每天数百万的电子邮件)通过我自己的代码审查做了一些小改动,主要是关于错误处理和输入验证。即,如果没有 DKIM 标头,则抛出异常。它工作得很好。需要记住,JCA 规范涵盖了多种类型的集成和连接场景,这就是它看起来如此复杂的原因。
    【解决方案3】:

    阿帕奇詹姆斯呢?

    它实现了所有堆栈,并让您以类似 servlet 的方法对收到的邮件作出反应;它是开源的,完全获得 apache 许可(因此可用于商业产品),并且已经过多年测试。

    【讨论】:

    • 好主意,我会研究一下!听起来它可以实现我的基于事件的方法。
    【解决方案4】:

    使用 ESB - 独立或嵌入式。

    “ESB 将转换和路由等与流相关的概念引入了面向服务的架构。ESB 还可以为端点提供抽象。这提高了传输层的灵活性,并实现了服务之间的松散耦合和轻松连接。 "

    例如 MULE “Mule ESB 是使用最广泛的开源 ESB。一个轻量级的集成平台和服务容器,Mule ESB 提供了 Web 服务、消息路由、中介、转换和事务管理的功能,帮助开发人员在几小时而不是几周内集成他们的应用程序”

    如何通过 mule 接收电子邮件 http://books.dzone.com/articles/mule-messaging-chapter?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+zones%2Fsoa+(SOA+Zone)

    下面是简单的配置,它发送 JMS 消息作为对收到消息的反应(这就是你所需要的) - 定义入站 (imap/pop3/etc) - 定义出站。

    <imap:inbound-endpoint user="bob" password="password" host="localhost" port="65433" checkFrequency="3000"/> 
    <jms:outbound-endpoint queue="my.destination" connector-ref="jmsQueueConnector"/>
    

    【讨论】:

    • 您的 imap:inbound-endpoint 示例将通过 IMAP 检索邮件,这正是 OP 明确拒绝的。
    • 事实上,从文档看来,Mule 甚至不支持传入 SMTP,只支持传出。所以骡子在这里可能帮不上忙……
    • 虽然这不是 OP 想要的,但我发现这对于企业来说是一个更合适的解决方案,因为它将电子邮件处理与应用程序分离,应用程序可以公开服务端点用于消息。
    【解决方案5】:

    我认为第二种方法不是“更干净”。相反,它需要您实现标准 MTA 的重要部分,因此我建议您不要这样做。

    我相信轮询 POP/IMAP 服务器实际上是最干净的方法。你为什么决定反对它?如果 POP/IMAP 服务器和您的服务在同一个 LAN 中(或者甚至在同一个机器上),那么轮询将非常便宜。您可以每 10-20 秒执行一次,以最大限度地减少延迟,这不会造成问题。虽然这在技术上可能看起来有点不雅,但您将使用标准互操作协议 (POP3/IMAP),它为您提供了灵活性,同时避免了重新实现邮件服务器。

    生成 Java 应用的方法似乎也可行,但我更喜欢轮询,因为:

    a) 您使用的接口 (POP3/IMAP) 更加标准化,而您用来“插入”到邮件服务器的接口将是特定于服务器的(在 Unix 上,您可以使用例如 procmail,但您仍然取决于具体的软件)

    b) 为每封邮件启动一个单独的进程可能会比轮询产生更多的开销。

    顺便说一句:第三种方法是以某种方式将传入的邮件作为文件转储到“传入”目录中(许多邮件服务器可以这样做),然后轮询该目录。轮询目录将比轮询服务器更便宜。请注意同步问题(阅读写一半的邮件,多个并发阅读器阅读同一个邮件文件......)

    我的经验:

    我已经使用这两种方法(IMAP 轮询和生成单独的进程)实现了系统。轮询是针对一个相当大的 Java 应用程序,它处理人们发送到邮箱的数据;我没有遇到任何轮询问题。生成方法是针对一个小的 Perl 脚本。我只是这样做,因为它是一个简单的程序,每天只处理几封邮件,并且插入邮件服务器比在 Perl 中做 IMAP 更容易。

    【讨论】:

    • @sleske:感谢您的详细回复!不幸的是,MTA 不提供 POP3/IMAP 设施(今天)......我会考虑哪个部分更容易。
    猜你喜欢
    • 2013-01-17
    • 1970-01-01
    • 2023-03-08
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    相关资源
    最近更新 更多