cronExpression从页面定义生成

来源:互联网 发布:php社交网站源码 编辑:程序博客网 时间:2024/09/21 09:22
1. 目的:动态设置时间,触发相应的任务

2. 系统架构为 struts + spring + hibernate

3. 实现步骤:
  • 在页面上设置时间;
  • 将时间转换为Unix Cron Expression;
  • 将转换后的时间规则表达式记录到数据库中(也可以写入xml文件中,这里是项目需要记录入数据库中);
  • 从数据库中得到相应的时间规则表达式;
  • 更新您的任务触发器的时间设置;
  • RESCHEDULE THE JOB。; - )
4. 具体实现细节:
1)在页面上设置时间
根据具体的业务需求,设置时间规则,下面以某一项目为例,需要按每月、每周、自定义分为三种规则。
 1 < tr >
 2           < th > 执行这个任务 </th >
 3           < td  style ="font-weight:bold;" >
 4            < html:radio property ="everyWhat" styleClass ="InputBorderNone" value ="monthly" onclick ="changeStatus(this.value)"> 每月 </ html:radio >
 5            < html:radio property ="everyWhat" styleClass ="InputBorderNone" value ="weekly" onclick ="changeStatus(this.value)"> 每周 </ html:radio >
 6            < html:radio property ="everyWhat" styleClass ="InputBorderNone" value ="userDefined" onclick ="changeStatus(this.value)"> 自定义 </ html:radio >
 7            < html:hidden property ="jobName" value ="compare"  />
 8           </ td >
 9 </ tr>
10

每月则需要选择该月的第几个星期的星期几
 1 < tr  style ="display:"  id ="whichWeek" >
 2           < th > 选择第几个星期 </th >
 3           < td  style ="font-weight:bold;" >
 4            < html:select property ="week">
 5             < html:option value ="1" > </html:option >
 6             < html:option value ="2" > </html:option >
 7             < html:option value ="3" > </html:option >
 8             < html:option value ="4" > </html:option >
 9            </ html:select>
10            < html:select property ="dayOfMonth">
11             < html:option value ="1" > 星期日 </html:option >
12             < html:option value ="2" > 星期一 </html:option >
13             < html:option value ="3" > 星期二 </html:option >
14             < html:option value ="4" > 星期三 </html:option >
15             < html:option value ="5" > 星期四 </html:option >
16             < html:option value ="6" > 星期五 </html:option >
17             < html:option value ="7" > 星期六 </html:option >
18            </ html:select>
19          </ td >  
20  </ tr >
21

每周则需要选择星期几
 1 < tr  style ="display:none"  id ="whichDay" >
 2           < th > 选择星期 </th >
 3           < td  style ="font-weight:bold;" >
 4            < html:select property ="dayOfWeek">
 5             < html:option value ="1" > 星期日 </html:option >
 6             < html:option value ="2" > 星期一 </html:option >
 7             < html:option value ="3" > 星期二 </html:option >
 8             < html:option value ="4" > 星期三 </html:option >
 9             < html:option value ="5" > 星期四 </html:option >
10             < html:option value ="6" > 星期五 </html:option >
11             < html:option value ="7" > 星期六 </html:option >
12            </ html:select>
13         </ td>  
14    </tr >
15

自定义则选择具体的日期,如 2007-1-10

三种规则都需要设定时间点
 1 < tr >
 2           < th > 起始时间 </th >
 3           < td  style ="font-weight:bold;" >
 4            < html:select property ="timeType" styleId ="type" onchange ="changeStatus2(this.value)">
 5             < html:option value ="AM"> 上午 </ html:option >
 6             < html:option value ="PM"> 下午 </ html:option >
 7            </ html:select>
 8            < html:select property ="hour" styleId ="amHours">
 9             < html:option value ="1" > 1 </html:option >
10             < html:option value ="2" > 2 </html:option >
11             < html:option value ="3" > 3 </html:option >
12             < html:option value ="4" > 4 </html:option >
13             < html:option value ="5" > 5 </html:option >
14             < html:option value ="6" > 6 </html:option >
15             < html:option value ="7" > 7 </html:option >
16             < html:option value ="8" > 8 </html:option >
17             < html:option value ="9" > 9 </html:option >
18             < html:option value ="10"> 10 </ html:option >
19             < html:option value ="11"> 11 </ html:option >
20             < html:option value ="12"> 12 </ html:option >
21            </ html:select>
22            < html:select property ="hour" styleId ="pmHours" style ="display:none">
23             < html:option value ="13"> 13 </ html:option >
24             < html:option value ="14"> 14 </ html:option >
25             < html:option value ="15"> 15 </ html:option >
26             < html:option value ="16"> 16 </ html:option >
27             < html:option value ="17"> 17 </ html:option >
28             < html:option value ="18"> 18 </ html:option >
29             < html:option value ="19"> 19 </ html:option >
30             < html:option value ="20"> 20 </ html:option >
31             < html:option value ="21"> 21 </ html:option >
32             < html:option value ="22"> 22 </ html:option >
33             < html:option value ="23"> 23 </ html:option >
34             < html:option value ="0" > 0 </html:option >
35            </ html:select>  点
36             < html:text property ="minute" name ="minute" style ="width:20px;" value ="0" onchange ="valTime(this.value)"  />  分
37             < html:text property ="second" name ="second" style ="width:20px;" value ="0" onchange ="valTime(this.value)"  />  秒(0-59之间的整数)
38       </ td>  
39 </ tr>
40

OK. 这样我们的页面设置就完成了。: - ) 
上回说到,我们的设置页面已经做好了,接下来就是将时间转换为Unix Cron Expression。

2) 将时间转换为Unix Cron Expression

需要ActionForm将页面表单数据映射到Action中,然后在Action中转换为cron expression:

 1 SchedulerForm schedulerForm  =  (SchedulerForm) form;
 2         String jobName =  schedulerForm.getJobName();
 3         String cronExpression =   "" ;
 4         String[] commonNeeds =   {schedulerForm.getSecond(), schedulerForm.getMinute(), schedulerForm.getHour()};
 5         String[] monthlyNeeds =   {schedulerForm.getWeek(), schedulerForm.getDayOfMonth()};
 6         String weeklyNeeds =  schedulerForm.getDayOfWeek();
 7         String userDefinedNeeds =  schedulerForm.getDate();
 8         String everyWhat =  schedulerForm.getEveryWhat();
 9         // 得到时间规则
10         cronExpression  =  CronExpConversion.getCronExpression(everyWhat, commonNeeds,
11                 monthlyNeeds, weeklyNeeds, userDefinedNeeds);
12

我定义了一个 规则类来处理转换规则(写得不是很好 能用就行 嘿嘿)
 1
 2 /**
 3  * 页面设置转为UNIX cron expressions 转换类
 4  * CronExpConversion
 5  */

 6 public  class  CronExpConversion {
 7     
 8     /**
 9      * 页面设置转为UNIX cron expressions 转换算法
10      * @param  everyWhat
11      * @param  commonNeeds 包括 second minute hour
12      * @param  monthlyNeeds 包括 第几个星期 星期几
13      * @param  weeklyNeeds  包括 星期几
14      * @param  userDefinedNeeds  包括具体时间点
15      * @return  cron expression
16      */

17     public   static  String convertDateToCronExp(String everyWhat,
18             String[] commonNeeds, String[] monthlyNeeds, String weeklyNeeds,
19             String userDefinedNeeds) {
20         String cronEx =   "" ;
21         String commons =  commonNeeds[0 +   "  "   +  commonNeeds[1 +   "  "
22                 +  commonNeeds[2 +   "  " ;
23         String dayOfWeek =   "" ;
24         if  ( " monthly ".equals(everyWhat))  {
25             //  eg.: 6#3 (day 6 = Friday and "#3" = the 3rd one in the
26             //  month)
27             dayOfWeek  =  monthlyNeeds[ 1 ]
28                     +  CronExRelated.specialCharacters
29                             .get(CronExRelated._THENTH) +  monthlyNeeds[0 ];
30             cronEx =  (commons
31                     +  CronExRelated.specialCharacters.get(CronExRelated._ANY)
32                     +   "   "
33                     +  CronExRelated.specialCharacters.get(CronExRelated._EVERY)
34                     +   "   "  +  dayOfWeek  +   "  " ).trim();
35         }
  else  if  ( " weekly" .equals(everyWhat)) {
36             dayOfWeek =  weeklyNeeds; //  1
37             cronEx  =  (commons
38                     +  CronExRelated.specialCharacters.get(CronExRelated._ANY)
39                     +   "   "
40                     +  CronExRelated.specialCharacters.get(CronExRelated._EVERY)
41                     +   "   "  +  dayOfWeek  +   "  " ).trim();
42         }
  else  if  ( " userDefined" .equals(everyWhat)) {
43             String dayOfMonth =  userDefinedNeeds.split(" - " )[ 2];
44             if  (dayOfMonth.startsWith(" 0 " ))  {
45                 dayOfMonth =  dayOfMonth.replaceFirst(" 0 " "");
46             }

47             String month =  userDefinedNeeds.split(" - " )[ 1];
48             if  (month.startsWith(" 0 " ))  {
49                 month =  month.replaceFirst(" 0 " "");
50             }

51             String year =  userDefinedNeeds.split(" - " )[ 0];
52             // FIXME 暂时不加年份 Quartz报错
53              /* cronEx = (commons + dayOfMonth + " " + month + " "
54                     + CronExRelated.specialCharacters.get(CronExRelated._ANY)
55                     + " " + year).trim();*/

56             cronEx =  (commons +  dayOfMonth +   "   "  +  month  +  "   "
57                     +  CronExRelated.specialCharacters.get(CronExRelated._ANY)
58                     +   "   ").trim();
59         }

60         return  cronEx;
61     }
    
62 }

63
这样就将页面的时间设置转为了Cron Expression。
书接上回,上回说到,我们已经将页面的时间设置转为了Cron Expression,下面我记录了时间规则。

3) 记录时间规则

      我将时间规则存入数据库中,目的是为了生成历史日志,也可以存入XML文件中。当然您也可以省略此步,直接将转换后的规则放入相应的Quartz trigger中。

4) 更新任务触发器的时间设置

到了关键的一步了,也是最简单的一步,一个方法就可以实现了。
首先,我们需要通过trigger的名称得到一个CronTriggerBean;
其次,通过trigger的setCronExpression(String cronExp)方法将新的表达式注入;
最后,RESCHEDULE THE JOB,OK!

 1     /**
 2      * 自定义定时器调度时间
 3      * @param
 triggerName 触发器名称
 4       * @throws
 Exception 
 5      */

 6     public   void  updateNotificationInterval(String triggerName, String triggerId)
 7             throws  SchedulerException, ParseException 
{
 8         // 得到trigger

 9         CronTriggerBean trigger  =  (CronTriggerBean) scheduler.getTrigger(
10
                triggerName, Scheduler.DEFAULT_GROUP);
11         // 得到cron expression        

12         String cronExpression  =  schedulerDAO.getCronExpression(triggerId);
13         // 设置trigger的时间规则

14         trigger.setCronExpression(cronExpression);
15         // 重置job

16         scheduler.rescheduleJob(triggerName, Scheduler.DEFAULT_GROUP, trigger);
17     }

18
至此,目的达到了,快乐的看着您的任务在您自定义的时间下快乐的执行,您是否也想像'Happy Feet'中那只快乐的企鹅一样,Show段踢踏呢 ; - D




PS:忘了说我的Quartz任务是怎么配置的了,罪过,罪过。

< bean  id ="compareJob"
        class
="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        
< property  name ="targetObject"  ref ="compareService"   />
        
< property  name ="targetMethod"  value ="compare"   />
        
< property  name ="concurrent"  value ="false"   />
    
</ bean >  

    
< bean  id ="compareTrigger"

        class
="org.springframework.scheduling.quartz.CronTriggerBean">
        
< property  name ="jobDetail"  ref ="compareJob"   />
        
< property  name ="cronExpression" >             
            
< value > 0 39 16 20 * ?</ value >
        
</ property >
    
</ bean >

< bean  id ="schedulerFactory"
        class
="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        
< property  name ="triggers" >
            
< list >                     
                     < ref  local ="compareTrigger"   />

            
</ list >
        
</ property >
    
</ bean >
0 0
原创粉丝点击