好多朋友用过Windows的任务计划也有不少程序迷自己曾写过时钟报警系统自动关机等趣味程序可却很少有朋友在Web工程中实现过类似功能
当Web工程启动时定时器能自动开始计时在整个Web工程的生命期里定时器能在每晚深夜触发一次任务因此定时器的存放位置也值得考查不能简单的存在于单个Servlet或JavaBean中必须能让定时器宿主的存活期为整个Web工程生命期在工程启动时能自动加载运行结合这两点跟 Servlet上下文有关的侦听器就最合适不过了通过在工程的配置文件中加以合理配置会在工程启动时自动运行并在整个工程生命期中处于监听状态
下面就Servlet侦听器结合Java定时器来讲述整个实现过程要运用Servlet侦听器需要实现 javaxservletServletContextListener接口同时实现它的contextInitialized (ServletContextEvent event)和contextDestroyed(ServletContextEvent event)两个接口函数考虑定时器有个建立和销毁的过程看了前面两个接口函数就不容置疑的把建立的过程置入 contextInitialized把销毁的过程置入contextDestroyed了
我把ServletContextListener的实现类取名为ContextListener在其内添加一个定时器示例代码如下所示
import javautilTimer;
import javaxservletServletContextEvent;
import javaxservletServletContextListener;
import javaxservletServletException;
import javaxservletServletRequest;
import javaxservletServletResponse;
import javaxservlethttpHttpServlet;
public class ContextListener
extends HttpServlet
implements ServletContextListener {
public ContextListener() {
}
private javautilTimer timer = null;
public void contextInitialized(ServletContextEvent event) {
timer = new javautilTimer(true);
eventgetServletContext()log(定时器已启动);
timerschedule(new MyTask(eventgetServletContext()) **);
eventgetServletContext()log(已经添加任务调度表);
}
public void contextDestroyed(ServletContextEvent event) {
timercancel();
eventgetServletContext()log(定时器销毁);
}
}
以上代码中 timerschedule(new MyTask(eventgetServletContext()) **)这一行为定时器调度语句其中MyTask是自定义需要被调度的执行任务(在我的财政数据中心项目中就是报表计算引擎入口)从 javautilTimerTask继承下面会重点讲述第三个参数表示每小时(即**毫秒)被触发一次中间参数表示无延迟其它代码相当简单不再详细说明
下面介绍MyTask的实现上面的代码中看到了在构造MyTask时传入了javaxservletServletContext类型参数是为记录Servlet日志方便而传入因此需要重载MyTask的构造函数(其父类javautilTimerTask原构造函数是没有参数的)在timerschedule()的调度中设置了每小时调度一次因此如果想实现调度任务每小时被执行一次还需要判断一下时钟点以常量C_SCHEDULE_HOUR表示(晚上点也即点)同时为防止小时执行下来任务还未执行完(当然一般任务是没有这么长的)避免第二次又被调度以引起执行沖突设置了当前是否正在执行的状态标志isRunning示例代码如下所示
import javautil*;
import javaxservletServletContextEvent;
import javaxservletServletContextListener;
import javaxservletServletException;
import javaxservletServletRequest;
import javaxservletServletResponse;
import javaxservlethttpHttpServlet;
import javaxservlet*;
public class MyTask extends TimerTask {
private static final int C_SCHEDULE_HOUR = ;
private static boolean isRunning = false;
private ServletContext context = null;
public MyTask() {
}
public MyTask(ServletContext context) {
ntext = context;
}
public void run() {
Calendar cal = CalendargetInstance();
if (!isRunning) {
if (C_SCHEDULE_HOUR == calget(CalendarHOUR_OF_DAY)) {
isRunning = true;
contextlog(开始执行指定任务);
//TODO 添加自定义的详细任务以下只是示例
//系统定时接收邮件
Email email=new Email();
emailrecieve();
isRunning = false;
contextlog(指定任务执行结束);
}
}
else {
contextlog(上一次任务执行还未结束);
}
}
}
到这儿ServletContextListener和MyTask的代码都已完整了最后一步就是把ServletContextListener部署到您的Web工程中去在您工程的webxml配置文件中加入如下三行
<listener>
<listenerclass>comtestContextListener</listenerclass>
</listener>
当然上面的comtest得换成您自己的包名了保存webxml文件后把工程打包部署到Tomcat中即可任务会在每晚点至凌晨点之间被执行