【发布时间】:2016-01-01 21:26:42
【问题描述】:
我一直在 google 和 stackoverflow 上搜索服务器是否可以发送自动电子邮件,例如每个星期一,使用 servlet 而无需任何用户交互。 目前,用户必须登录并且代码被执行。 我想要的是服务器在特定时间执行代码,用户不必登录甚至看不到。 我不想中继用户,我想中继服务器。
【问题讨论】:
我一直在 google 和 stackoverflow 上搜索服务器是否可以发送自动电子邮件,例如每个星期一,使用 servlet 而无需任何用户交互。 目前,用户必须登录并且代码被执行。 我想要的是服务器在特定时间执行代码,用户不必登录甚至看不到。 我不想中继用户,我想中继服务器。
【问题讨论】:
您的服务器中需要有一个非交互式线程。理想情况下,该线程应该由ServletContextListener 启动,以确保它甚至在第一次客户端连接之前就处于活动状态。
您可以从头开始构建一些东西,也可以使用专用工具,例如出色的 Quartz scheduler,它会为您编写样板代码。
一旦有了调度程序,您只需要能够通过 SMTP 将邮件发送到邮件服务器。再次,您可以手动实现协议(SMTP 并不难),但如果您不想重新发明一个已经有圆形轮子的椭圆轮,请使用来自的 javamail API Java EE SDK 或其他第三方库,例如 the one provided by Apache
【讨论】:
Servlet 的init 方法,因为容器可以延迟初始化直到容器确定需要servlet 来服务请求。在 web.xml 文件中或在您使用完整的 java 初始化使用 WebListener 注释或通过 ServletContext 上定义的 addListener 方法之一进行注册时,改为声明 ServletContextListener
只要您的服务器应用程序正在运行,您就可以使用 Quartz 来安排您的电子邮件发送过程。
【讨论】:
您应该能够通过设置另一个作为服务执行的应用程序来做您想做的事情。在下面,这个应用程序可以使用诸如Quartz 之类的东西来管理预定的事件。
您可以通过使用某些数据库使其与 Web 应用程序保持同步。这种方法应该允许电子邮件传输的自动化。
【讨论】:
您可以使用 Quartz 安排作业在指定的日期和时间运行。 Quartz 2 中有两种类型的触发器
SimpleTrigger - 这个允许设置开始时间、结束时间、重复间隔。
CronTrigger - 它允许 Unix cron 表达式指定运行作业的日期和时间。
您可以从 official website 或 maven 存储库获取 Quartz 库。
内部解决方案
如果您不想为此目的使用任何第三方 jar,还有另一种方法。从 J2SE 1.3 开始,Java 包含可用于此目的的 java.util.Timer 和 java.util.TimerTask 类
【讨论】:
您需要运行一个后台线程并等待下一次发送电子邮件。 Java 5 添加了一些类以使此类后台线程和任务变得非常容易。
其他一些答案提到了 Quartz 库。我没用过,它可能有很好的功能。但这当然不是您的目的所必需的。 Java 内置的类就足够了。
ServletContextListener创建ServletContextListener 的子类。保证在处理任何 servlet 请求之前调用此类。所以这是初始化您的网络应用程序使用的对象的地方。当您的 Web 应用程序关闭时,也会调用此类。
ScheduledExecutorService在您的 servlet 上下文侦听器中,当您的 Web 应用程序启动时,实例化一个 ScheduledExecutorService。此类使用线程池在后台运行任务。您在首次运行之前指定初始延迟(可选),并指定重复任务的频率。
在您的 servlet 上下文侦听器中,请务必在您的 Web 应用程序关闭时关闭您的 ScheduledExecutorService。如果不这样做,池中的后台线程将继续存在。在您的主机操作系统上启动以运行您的 servlet 容器的 java 进程将继续而不是退出。
请务必在您的任务周围添加一个 try-catch。任何到达 ScheduledExecutorService 的异常都会导致服务静默停止。见this funny post(小心,调皮的语言)。
搜索 StackOverflow 以获取更多详细信息和示例。这个问题基本上是重复的,所以我保持这个答案简短。
【讨论】: