Java报表—-调度器实现特定周期内指定条件任务
调度器实现特定周期内指定条件任务
需求描述
客户针对调度器提出这样一种需求:每天指定时间段(如9:00到12:00)每隔一段时间(如5分钟)去数据库中检索某字段(如flag)值是否为1,若为1则执行任务,导出报表到excel并发送邮件;否则继续检索,直到到12:00flag还不是1,则当天任务也结束。
要求:所有项用户均可配置,即:执行时间段、判断数据库字段状态、导出报表以及发送邮件。
分析
首先简单分析一下调度器的运行机制,首先调度器引擎会去重复去任务序列中查找是否有当前时间该执行的任务;然后根据执行判断条件的返回值决定是否执行任务,若返回true,则根据配置的任务(如导出报表到excel发邮件)。这个需求可以自定义一个任务周期类完成时间段内循环,检索数据库字段状态以及当天是否发送邮件放到润乾表达式中,导出报表和发邮件使用调度器现有功能,最后在任务监听类中更新是否发送邮件状态。
实现步骤
1、配置scheduleCustomConfig.xml,增加自定义任务周期配置,如本例中增加:
<cycle name=”每天9到12点每隔5分钟任务” url=”fiveMinuteTask.jsp”/>
2、定义fiveMinuteTask.jsp页面,如下图示:
3、定义周期类(FiveMinuteTask.java)需实现Icycle接口,实现指定时间段内重复任务
public class FiveMinuteTask implements ICycle {
public Timestamp getNextTime(String timeAndArg) {
String currTime = timeAndArg;//1900-01-01 00:00:00.0{09:00,12:00,5}
String params = “”;
String[] customSet=null;
if(timeAndArg.indexOf(“{“)!=-1){
currTime = timeAndArg.substring(0, timeAndArg.indexOf(“{“));//1900-01-01 00:00:00.0
params = timeAndArg.substring(timeAndArg.indexOf(“{“)+1,timeAndArg.indexOf(“}”));
customSet = params.split(“;”);
}
String startTime = customSet[0];//开始时间09:00:00
String endTime = customSet[1];//结束时间12:00:00
int timeNum = Integer.parseInt(customSet[2]);//时间间隔,以分钟为单位
String expResult=null;
Boolean timeFlag = false;//是否在制定时间段内
Boolean expFlag = false;//执行的润乾表达式结果
String tempStr = currTime.substring(0,10);
if(currTime.compareTo(tempStr+” “+startTime)>=0 && currTime.compareTo(tempStr+” “+endTime)<=0){
timeFlag = true;
}
if(timeFlag){//如果在开始~结束时间范围内,则下次执行时间为:本次执行时间+时间间隔
Calendar cal = Calendar.getInstance();
cal.setTime(DateUtils.StringToDate(currTime));
cal.add(Calendar.MINUTE, timeNum);
return new Timestamp(cal.getTimeInMillis());
}else{//第二天的开始执行时间
Calendar cal = Calendar.getInstance();
cal.setTime(DateUtils.StringToDate(tempStr+” “+startTime));
cal.add(Calendar.DATE, 1);
return new Timestamp(cal.getTimeInMillis());
}
}
}
4、定义任务监听类(FiveMinuteTaskListener)需继承AbstractTaskListener,向数据库中更新当天邮件发送状态
public class FiveMinuteTaskListener extends AbstractTaskListener{
public void beforeRun(TaskInfo ti,Map params,Connection con){}
public void afterRun(TaskInfo ti,Map params,Connection con){
Statement stmt = null;
ResultSet rs = null;
String result = null;
String sql = null;
String sql2 = null;
SimpleDateFormat sf = new SimpleDateFormat(“yyyy-MM-dd”);
Date date = new Date();
String today = sf.format(date);//当前日期
Calendar cal = Calendar.getInstance();//使用默认时区和语言环境获得一个日历。
cal.add(Calendar.DAY_OF_MONTH, +1);//取当前日期的后一天
String tomorrow = sf.format(cal.getTime());
try {
stmt=con.createStatement();
sql=”update if_send_email set flag = ’1′ where date_id=’”+today+”‘”;
sql2=”insert into if_send_email values(‘”+tomorrow+”‘,’0′)”;
stmt.executeUpdate(sql);
stmt.executeUpdate(sql2);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch(SQLException se){
se.printStackTrace();
}
}
}
}
5、完整任务定义
*任务监听器 选择自定义任务监听类名
*任务周期类型 选择scheduleCustomConfig.xml配置新类型,这里是:每天9到12点每隔5分钟任务
*任务执行条件判断规则 选择润乾表达式
在条件判断表达式 中根据实际需要书写润乾表达式,如:if(query(“select flag from test where id=’1′”)==”1″ && query(“select flag from if_send_email where date_id=’”+left(str(now()),10)+”‘”)==”0″,true,false)
点击,任务周期类型后面的“设置”按钮,在弹出的“自定义周期任务设置”页面中设置开始时间、结束时间、时间间隔。