上一篇介绍了第一部分:定时任务动态配置及持久化
本篇介绍第二部分:可视化的管理界面,可以非常清晰的管理自己的所有定时任务
先来看一下管理后台对应的界面
可以看到在这里我把定时任务的状态分为两大类,任务状态跟业务有关,分为已发布和未发布;计划状态跟定时任务的运行有关,分为None,正常运行,已暂停,任务执行中,线程阻塞,未计划,错误
关键代码如下
1.计划状态
function formatPlan(value, rowData, rowIndex){
if(value=="None"){
return "None"
}
if(value=="NORMAL"){
return "正常运行"
}
if(value=="PAUSED"){
return "已暂停"
}
if(value=="COMPLETE"){
return "任务执行中"
}
if(value=="BLOCKED"){
return "线程阻塞"
}
if(value=="ERROR"){
return "错误"
}else{
return "未计划"
}
}
2.操作逻辑
function formatOpt(value, rowData, rowIndex) {
var msg = "";
msg+="编辑";
//已发布,
if(rowData.jobStatus=='1'){
var value = rowData.planStatus;
if(value=="None"|| value==null){
msg +='计划';
}
if(value=="NORMAL"){
msg += '立即执行'
+ '暂停'
+'移除';
}
if(value=="PAUSED"){
msg += '立即执行'
+ '计划'
+'移除';
}
if(value=="COMPLETE"){
msg += '立即执行'
}
if(value=="BLOCKED"){
msg += '立即执行'
}
if(value=="ERROR"){
}
}
return msg;
}
简单概述为:已发布的定时任务出现【计划】按钮;执行【计划】后,定时任务正常运行,且出现【立即执行】【暂停】【移除】三个按钮,【立即执行】用于测试当前定时任务的业务逻辑是否正确,【暂停】很容易理解,就是把当前任务暂停,及时到达cron定义的时间,定时任务也不会执行,【移除】仅仅是把计划列表中相应的任务暂时清除掉,你可以理解为清除缓存中的定时任务,并不是物理删除
3.定时任务详情
点击规则弹出页面如下:
管理后台控制层
/**
* 定时任务
* @author wison
*
*/
@Controller
@RequestMapping(value = "/task")
public class TimeTaskController extends BaseController {
private static String JOB_URL ="http://localhost:8080/quartz";
private static String ALL_JOB = JOB_URL+"/opt/getAllJob"; //所有计划中的任务列表
private static String RUNNING_JOB = JOB_URL+"/opt/getRunningJob";//所有正在运行的job
private static String ADD_JOB = JOB_URL+"/opt/addJob";//添加任务
private static String PAUSE_JOB =JOB_URL+ "/opt/pauseJob";//暂停一个job
private static String RESUME_JOB = JOB_URL+"/opt/resumeJob";//恢复一个job
private static String DELETE_JOB = JOB_URL+"/opt/deleteJob";//删除一个job
private static String RUNA_JOB =JOB_URL+ "/opt/runAJobNow";//立即执行job
private static String UPDATE_JOB = JOB_URL+"/opt/updateJobCron";//更新job时间表达式
private static final Logger logger = LoggerFactory.getLogger(TimeTaskController.class);
@Autowired
private STimetaskService stimetaskService;
@InitBinder
public void initBinder(WebDataBinder binder) {
DateFormat fmt = new SimpleDateFormat(DateUtil.STANDARD_DATE_FORMAT_STR);
CustomDateEditor dateEditor = new CustomDateEditor(fmt, true);
binder.registerCustomEditor(Date.class, dateEditor);
}
/**
* 列表页面跳转
* @return
*/
@RequestMapping(value="/list")
public ModelAndView userList(STimetask task){
ModelAndView mv = this.getModelAndView();
mv.setViewName("system/timeTaskList");
return mv;
}
/**
* 列表
* @return
*/
@RequestMapping(value="/task_list")
@ResponseBody
public JsonResult taskList(DataTablesUtil dataTables, STimetask task, Page page, HttpSession session){
List list = stimetaskService.selectByPage(task, page);
// 查询task的运行状态
String result = HttpConnectUtil.httpRequest(RUNNING_JOB, Const.REQUEST_METHOD_POST, null);
if(result!=null){
JSONObject jsonResult = JSONObject.fromObject(result);
Map map = new HashMap();
if( jsonResult.get("code").equals("2000")){
JSONObject js = (JSONObject) jsonResult.get("data");
JSONArray dataArray = (JSONArray) js.get("job");
if(dataArray.size() > 0){
List jobList = JSONArray.toList(dataArray,ScheduleJob.class);
for(ScheduleJob job: jobList){
map.put(job.getJobId().toString(), job);
}
}
}
for(STimetask st: list){
if(map.containsKey(st.getId())){
st.setConcurrent(true);
}
}
}
// 查询task的计划状态
String planResult = HttpConnectUtil.httpRequest(ALL_JOB, Const.REQUEST_METHOD_POST, null);
if(planResult!=null){
JSONObject jsonPlanResult = JSONObject.fromObject(planResult);
Map planMap = new HashMap();
if(jsonPlanResult.get("code").equals("2000")){
JSONObject js = (JSONObject) jsonPlanResult.get("data");
JSONArray dataArray = (JSONArray) js.get("job");
if(dataArray.size() > 0){
List jobList = JSONArray.toList(dataArray,ScheduleJob.class);
for(ScheduleJob job: jobList){
planMap.put(job.getJobId().toString(), job);
}
}
}
for(STimetask st: list){
if(planMap.containsKey(st.getId())){
String status = planMap.get(st.getId()).getJobStatus();
st.setPlanStatus(status);
}
}
}
//返回dataTable所需数据
dataTables = this.getDataTables(page, dataTables, list);
return new JsonResult("2000", dataTables);
}
/**
* 立即执行一次job
* 用于测试任务是否正确
* @param id
* @return
*/
@RequestMapping(value="/run_task2job")
@ResponseBody
public JsonResult run_task2job(String id){
//查询task
STimetask stimetask = stimetaskService.selectByPrimaryKey(id);
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
JSONObject jsonArray = JSONObject.fromObject(stimetask,jsonConfig);
String result = HttpConnectUtil.httpRequest(RUNA_JOB, Const.REQUEST_METHOD_POST, jsonArray.toString());
logger.info(result);
if(result ==null){
return new JsonResult("5000", "定时项目未启动",null);
}else{
return new JsonResult("2000", null);
}
}
/**
* 添加job到计划列表
* @param id
* @return
*/
@RequestMapping(value="/add_task2job")
@ResponseBody
public JsonResult add_task2job(String id){
//查询task
STimetask stimetask = stimetaskService.selectByPrimaryKey(id);
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
JSONObject jsonArray = JSONObject.fromObject(stimetask,jsonConfig);
String result = HttpConnectUtil.httpRequest(ADD_JOB, Const.REQUEST_METHOD_POST, jsonArray.toString());
logger.info(result);
if(result ==null){
return new JsonResult("5000", "定时项目未启动",null);
}else{
return new JsonResult("2000", null);
}
}
/**
* 从计划列表中暂停job
* @param id
* @return
*/
@RequestMapping(value="/stop_task2job")
@ResponseBody
public JsonResult stop_task2job(String id){
//查询task
STimetask stimetask = stimetaskService.selectByPrimaryKey(id);
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
JSONObject jsonArray = JSONObject.fromObject(stimetask,jsonConfig);
String result = HttpConnectUtil.httpRequest(PAUSE_JOB, Const.REQUEST_METHOD_POST, jsonArray.toString());
logger.info(result);
if(result ==null){
return new JsonResult("5000", "定时项目未启动",null);
}else{
return new JsonResult("2000", null);
}
}
/**
* 从计划列表中移除job
* @param id
* @return
*/
@RequestMapping(value="/remove_task2job")
@ResponseBody
public JsonResult remove_task2job(String id){
//查询task
STimetask stimetask = stimetaskService.selectByPrimaryKey(id);
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
JSONObject jsonArray = JSONObject.fromObject(stimetask,jsonConfig);
String result = HttpConnectUtil.httpRequest(DELETE_JOB, Const.REQUEST_METHOD_POST, jsonArray.toString());
logger.info(result);
if(result ==null){
return new JsonResult("5000", "定时项目未启动",null);
}else{
return new JsonResult("2000", null);
}
}
/**
* 变更job状态
* @param id
* @return
*/
@RequestMapping(value="/update_task")
@ResponseBody
public JsonResult update_task(String ids,String type){
//查询task
String[] idArray = ids.split(",");
Map selectedIdMap = new HashMap();
List idList = new ArrayList();
for (int i = 0; i < idArray.length; i++) {
idList.add(idArray[i]);
}
int ret = stimetaskService.updatebyOperate(idList,type);
if(ret >0){
return new JsonResult(true);
}else{
return new JsonResult(false);
}
}
/**
* 删除job
* @param id
* @return
*/
@RequestMapping(value="/delete_task")
@ResponseBody
public JsonResult delete_task(String ids){
//查询task
String[] idArray = ids.split(",");
Map selectedIdMap = new HashMap();
List idList = new ArrayList();
for (int i = 0; i < idArray.length; i++) {
idList.add(idArray[i]);
}
int ret = stimetaskService.deleteByIds(idList);
if(ret >0){
return new JsonResult(true);
}else{
return new JsonResult(false);
}
}
/**
* 详情页面
* @return
*/
@RequestMapping(value="/task_detail")
public ModelAndView detail(String id){
ModelAndView mv = this.getModelAndView();
STimetask model = new STimetask();
model = stimetaskService.selectByPrimaryKey(id);
mv.addObject("model", model);
mv.setViewName("system/timeTaskDetail");
return mv;
}
/**
* 解析cron
* @return
*/
@RequestMapping(value="/analysis_cron")
@ResponseBody
public JsonResult analysisCron(String cron){
try {
Date date = new Date();
String dateStr = DateUtil.formatStandardDatetime(date);
List dateList = CronUtil.cronAlgBuNums(cron, dateStr, 5);
return new JsonResult("2000", dateList);
} catch (Exception e) {
e.printStackTrace();
return new JsonResult("5000", null);
}
}
@RequestMapping(value="/check_name")
@ResponseBody
public Boolean check_name(String id, String groupName, String name){
if(StringUtil.isEmpty(groupName,name)){
throw new BusinessException(Message.M4003);
}
STimetask task = new STimetask();
task.setId(id);
task.setGroupName(groupName);
task.setName(name);
STimetask queryTask = stimetaskService.checkName(task);
if(queryTask !=null){
logger.debug("组.任务名 exists,return false");
return false;
}else{
logger.debug("组.任务名 not exists,return true");
return true;
}
}
/**
* 保存
* @return
*/
@RequestMapping(value="/task_save")
@ResponseBody
public JsonResult userSave(STimetask task, HttpSession session){
User currentUser = (User) session.getAttribute(Const.SESSION_USER);
task.setModifyUserId(currentUser.getUserId());
try{
int ret= stimetaskService.insertOrUpdateByUser(task,currentUser);
if(ret > 0){
return new JsonResult("2000",task);
}else{
return new JsonResult("5000");
}
}catch(BusinessException e){
return new JsonResult("5001",e.getMessage(),null);
}
}
}
定时任务接口,此处的out.write();可以使用springMVC直接返回json,无需像我这样自己再单独处理
@Component
@RequestMapping(value = "/opt")
public class JobSerlvet {
public final Logger log = Logger.getLogger(this.getClass());
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
/**
* 获取所有计划中的任务列表
*
* @return
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/getAllJob")
@ResponseBody
public void getAllJob(HttpServletRequest request,HttpServletResponse response) throws SchedulerException, IOException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
GroupMatcher matcher = GroupMatcher.anyJobGroup();
Set jobKeys = scheduler.getJobKeys(matcher);
List jobList = new ArrayList();
for (JobKey jobKey : jobKeys) {
List extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
ScheduleJob job = new ScheduleJob();
job.setJobId(trigger.getDescription());//description 放的是job的id
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDescription("触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
}
//输出
if(jobList.size() >0){
JSONArray listArray=JSONArray.fromObject(jobList);
Map m =new HashMap();
m.put("job", listArray);
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\",\"data\":"+m+"}");
out.close();
}else{
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"5000\",\"message\":\"没有计划任务\"}");
out.close();
}
}
/**
* 所有正在运行的job
*
* @return
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/getRunningJob")
@ResponseBody
public void getRunningJob(HttpServletRequest request,HttpServletResponse response) throws SchedulerException, IOException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
List executingJobs = scheduler.getCurrentlyExecutingJobs();
List jobList = new ArrayList(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
ScheduleJob job = new ScheduleJob();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDescription("触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
//输出
if(jobList.size() >0){
JSONArray listArray=JSONArray.fromObject(jobList);
Map m =new HashMap();
m.put("job", listArray);
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\",\"data\":"+m+"}");
out.close();
}else{
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"5000\",\"message\":\"没有正在执行的任务\"}");
out.close();
}
}
/**
* 添加任务
*
* @param
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/addJob")
@ResponseBody
public void addJob(HttpServletRequest request,HttpServletResponse response) throws SchedulerException, IOException {
StringBuffer info=new StringBuffer();
ServletInputStream in = request.getInputStream();
BufferedInputStream buf = new BufferedInputStream(in);
byte[] buffer=new byte[1024];
int iRead;
while((iRead=buf.read(buffer))!=-1){
info.append(new String(buffer,0,iRead,"UTF-8"));
}
// 释放资源
buf.close();
in.close();
ScheduleJob job = new ScheduleJob();
if(info!=null&&!StringUtil.isEmpty(info.toString())){
JSONObject json = JSONObject.parseObject(info.toString());
STimetask sTimetask = JSONObject.toJavaObject(json, STimetask.class);
if(sTimetask !=null){
job.setJobId(sTimetask.getId());
job.setJobGroup(sTimetask.getGroupName()); //任务组
job.setJobName(sTimetask.getName());// 任务名称
job.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
job.setIsConcurrent(sTimetask.getConcurrent()?"1":"0"); // 运行状态
job.setCronExpression(sTimetask.getCron());
job.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
job.setMethodName(sTimetask.getMethodName());
job.setJobData(sTimetask.getJobData()); //参数
}
}
InitQuartzJob.addJob(job);
//输入
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\"}");
out.close();
}
/**
* 暂停一个job
*
* @param scheduleJob
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/pauseJob")
@ResponseBody
public void pauseJob(HttpServletRequest request,HttpServletResponse response) throws SchedulerException, IOException {
StringBuffer info=new StringBuffer();
ServletInputStream in = request.getInputStream();
BufferedInputStream buf = new BufferedInputStream(in);
byte[] buffer=new byte[1024];
int iRead;
while((iRead=buf.read(buffer))!=-1){
info.append(new String(buffer,0,iRead,"UTF-8"));
}
// 释放资源
buf.close();
in.close();
if(info!=null&&!StringUtil.isEmpty(info.toString())){
JSONObject json = JSONObject.parseObject(info.toString());
STimetask sTimetask = JSONObject.toJavaObject(json, STimetask.class);
if(sTimetask !=null){
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
scheduler.pauseJob(jobKey);
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\"}");
out.close();
}else{
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"5000\",\"message\":\"任务不存在\"}");
out.close();
}
}
}
/**
* 恢复一个job
*
* @param scheduleJob
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/resumeJob")
@ResponseBody
public void resumeJob(HttpServletRequest request,HttpServletResponse response) throws SchedulerException, IOException {
StringBuffer info=new StringBuffer();
ServletInputStream in = request.getInputStream();
BufferedInputStream buf = new BufferedInputStream(in);
byte[] buffer=new byte[1024];
int iRead;
while((iRead=buf.read(buffer))!=-1){
info.append(new String(buffer,0,iRead,"UTF-8"));
}
// 释放资源
buf.close();
in.close();
if(info!=null&&!StringUtil.isEmpty(info.toString())){
JSONObject json = JSONObject.parseObject(info.toString());
STimetask sTimetask = JSONObject.toJavaObject(json, STimetask.class);
if(sTimetask !=null){
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
scheduler.resumeJob(jobKey);
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\"}");
out.close();
}else{
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"5000\",\"message\":\"任务不存在\"}");
out.close();
}
}
}
/**
* 删除一个job
*
* @param scheduleJob
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/deleteJob")
@ResponseBody
public void deleteJob(HttpServletRequest request,HttpServletResponse response) throws SchedulerException, IOException {
StringBuffer info=new StringBuffer();
ServletInputStream in = request.getInputStream();
BufferedInputStream buf = new BufferedInputStream(in);
byte[] buffer=new byte[1024];
int iRead;
while((iRead=buf.read(buffer))!=-1){
info.append(new String(buffer,0,iRead,"UTF-8"));
}
// 释放资源
buf.close();
in.close();
if(info!=null&&!StringUtil.isEmpty(info.toString())){
JSONObject json = JSONObject.parseObject(info.toString());
STimetask sTimetask = JSONObject.toJavaObject(json, STimetask.class);
if(sTimetask !=null){
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
scheduler.deleteJob(jobKey);
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\"}");
out.close();
}else{
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"5000\",\"message\":\"任务不存在\"}");
out.close();
}
}
}
/**
* 立即执行job
*
* @param scheduleJob
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/runAJobNow")
@ResponseBody
public void runAJobNow(HttpServletRequest request,HttpServletResponse response) throws SchedulerException, IOException {
StringBuffer info=new StringBuffer();
ServletInputStream in = request.getInputStream();
BufferedInputStream buf = new BufferedInputStream(in);
byte[] buffer=new byte[1024];
int iRead;
while((iRead=buf.read(buffer))!=-1){
info.append(new String(buffer,0,iRead,"UTF-8"));
}
// 释放资源
buf.close();
in.close();
if(info!=null&&!StringUtil.isEmpty(info.toString())){
JSONObject json = JSONObject.parseObject(info.toString());
STimetask sTimetask = JSONObject.toJavaObject(json, STimetask.class);
if(sTimetask !=null){
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
scheduler.triggerJob(jobKey);
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\"}");
out.close();
}else{
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"5000\",\"message\":\"任务不存在\"}");
out.close();
}
}
}
/**
* 更新job时间表达式
*
* @param scheduleJob
* @throws SchedulerException
* @throws IOException
*/
@RequestMapping(value="/updateJobCron")
@ResponseBody
public void updateJobCron(HttpServletRequest request,HttpServletResponse response) throws SchedulerException{
try {
StringBuffer info=new StringBuffer();
ServletInputStream in;
in = request.getInputStream();
BufferedInputStream buf = new BufferedInputStream(in);
byte[] buffer=new byte[1024];
int iRead;
while((iRead=buf.read(buffer))!=-1){
info.append(new String(buffer,0,iRead,"UTF-8"));
}
// 释放资源
buf.close();
in.close();
if(info!=null&&!StringUtil.isEmpty(info.toString())){
JSONObject json = JSONObject.parseObject(info.toString());
STimetask sTimetask = JSONObject.toJavaObject(json, STimetask.class);
if(sTimetask !=null){
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
TriggerKey triggerKey = TriggerKey.triggerKey(sTimetask.getName(), sTimetask.getGroupName());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(sTimetask.getCron());
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
scheduler.rescheduleJob(triggerKey, trigger);
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"2000\",\"message\":\"成功\"}");
out.close();
}else{
//输出
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"code\":\"5000\",\"message\":\"任务不存在\"}");
out.close();
}
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
前端代码
timeTaskList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
定时任务管理
<%@include file="/jsp/common/tag.jsp"%>
<%@include file="/jsp/common/easyui-style.jsp"%>
<%@include file="/jsp/header.jsp"%>
<%@include file="/jsp/menu.jsp"%>
timeTaskDetail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
定时任务详情
<%@include file="/jsp/common/tag.jsp"%>
<%@include file="/jsp/common/easyui-style.jsp"%>
<%@include file="/jsp/header.jsp"%>
<%@include file="/jsp/menu.jsp"%>
cron.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<% String cssPath = request.getContextPath();
String cssBasePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+cssPath+"/";
%>
规则
<%@include file="/jsp/common/tag.jsp"%>
每秒 允许的通配符[, - * /]
周期从
-
秒
从
秒开始,每
秒执行一次
指定
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
分钟 允许的通配符[, - * /]
周期从
-
分钟
从
分钟开始,每
分钟执行一次
指定
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
小时 允许的通配符[, - * /]
周期从
-
小时
从
小时开始,每
小时执行一次
指定
AM:
00
01
02
03
04
05
06
07
08
09
10
11
PM:
12
13
14
15
16
17
18
19
20
21
22
23
日 允许的通配符[, - * / L W]
不指定
周期从
-
日
从
日开始,每
天执行一次
每月
号最近的那个工作日
本月最后一天
指定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
月 允许的通配符[, - * /]
不指定
周期从
-
月
从
日开始,每
月执行一次
指定
1
2
3
4
5
6
7
8
9
10
11
12
周 允许的通配符[, - * / L #]
不指定
周期 从星期
-
第
周 的星期
本月最后一个星期
指定
1
2
3
4
5
6
7
不指定 允许的通配符[, - * /] 非必填
每年
周期 从
-
cron.js
try{!function(){var t;window._SF_&&window._SF_._global_&&window._SF_._global_._ssp?(t=window._SF_._global_._ssp,t.DUP_4_SF=!0,t.destroy=function(){}):t=window._ssp_global=window._ssp_global||{};var e={global:t,proxyName:!1,basePath:"https://cpro.baidustatic.com/cpro/ui/dup/"};!function(){var i={name:"oojs",namespace:"",classes:{},noop:function(){},$oojs:function(){var i={};if("undefined"!=typeof window&&window&&"undefined"!=typeof document&&document?(this.runtime="browser",i.global=window):(this.runtime="node",i.global=t),i.proxyName="proxy",i.path="node"===this.runtime?process.cwd()+"/src/":"/src/","undefined"!=typeof e)for(var n in e)n&&e.hasOwnProperty(n)&&(i[n]=e[n]);this.global=i.global,i.proxyName&&(Function.prototype[i.proxyName]=this.proxy),this.setPath(i.path),this.global.oojs=this.global.oojs||this},path:{},pathCache:{},getPath:function(t){var e=t?t.split("."):!1,i=this.path;if(e)for(var n=0,o=e.length;o>n;n++){var r=e[n].toLowerCase();if(!i[r])break;i=i[r]}return i.pathValue},setPath:function(t,e){var i=this.path;if("object"!=typeof t){if(e)for(var n=t.split("."),o=0,r=n.length;r>o;o++){var s=n[o].toLowerCase();i[s]=i[s]||{pathValue:i.pathValue},i=i[s]}else e=t;i.pathValue=e,this.pathCache={}}else for(var a in t)a&&t.hasOwnProperty(a)&&this.setPath(a,t[a])},getClassPath:function(t){if(!this.pathCache[t]){this.pathCache[t]=this.getPath(t)+t.replace(/\./gi,"/")+".js";var e=this.getPath(t),i=e.length-1;e.lastIndexOf("\\")!==i&&e.lastIndexOf("/")!==i&&(e+="/"),this.pathCache[t]=e+t.replace(/\./gi,"/")+".js"}return this.pathCache[t]},loadDeps:function(t,e){e=e||{};var i=t.__deps,n=(t.__namespace,[]);for(var o in i)if(i.hasOwnProperty(o)&&i[o]){var r;if("string"!=typeof i[o]?(t[o]=i[o],t[o]&&t[o].__name&&(r=t[o].__full)):(r=i[o],t[o]=this.find(r)),!r||e[r])continue;if(e[r]=!0,t[o])t[o].__deps&&(n=n.concat(this.loadDeps(t[o],e)));else{if("node"===this.runtime)try{t[o]=require(this.getClassPath(r))}catch(s){n.push(r)}t[o]||n.push(r)}}return n},fastClone:function(t){var e=function(){};e.prototype=t;var i=new e;return i},deepClone:function(t,e){"number"!=typeof e&&(e=10);var i,n=e-1;if(e>0)if(t instanceof Date)i=new Date,i.setTime(t.getTime());else if(t instanceof Array){i=[];for(var o=0,r=t.length;r>o;o++)i[o]=this.deepClone(t[o],n)}else if("object"==typeof t){i={};for(var s in t)if(t.hasOwnProperty(s)){var a=t[s];i[s]=this.deepClone(a,n)}}else i=t;else i=t;return i},proxy:function(t,e){var i=Array.prototype.slice.apply(arguments),n=i.shift(),o="function"==typeof this?this:i.shift();return function(){var t=Array.prototype.slice.apply(arguments);return o.apply(n,t.concat(i))}},find:function(t){var e,i=t.split(".");e=this.classes[i[0]];for(var n=1,o=i.length;o>n;n++){if(!e||!e[i[n]]){e=null;break}e=e[i[n]]}return e},reload:function(t){var e=this.find(t);if(e)if(e.__registed=!1,"node"===this.runtime){var i=this.getClassPath(t);delete require.cache[require.resolve(i)],e=require(i)}else e=this.define(e);else e=this.using(t);return e},create:function(t,e,i,n,o,r){"string"==typeof t&&(t=this.using(t));var s=new t.__constructor(e,i,n,o,r);return s},using:function(t){var e=this.find(t);return e||"node"===this.runtime&&(require(this.getClassPath(t)),e=this.find(t)),e},define:function(t){var e=t.name||"__tempName",i=t.namespace||"";t.__name=e,t.__namespace=i,t.__full=i.length>1?i+"."+e:e,t.__deps=t.deps,t.__oojs=this,t.__constructor=function(t,e,i,n,o){if(this.__clones&&this.__clones.length>0)for(var r=0,s=this.__clones.length;s>r;r++){var a=this.__clones[r];this[a]=this.__oojs.deepClone(this[a])}this.__constructorSource(t,e,i,n,o)},t.__constructorSource=t[e]||this.noop,t.__staticSource=t["$"+e]||this.noop,t.__staticUpdate=function(){var e=[];for(var i in this)if(this.hasOwnProperty(i)){var n=this[i];"object"!=typeof n||null===n||"deps"===i||0===i.indexOf("__")||t.__deps&&t.__deps[i]||e.push(i)}this.__clones=e,this.__constructor.prototype=this},t.__static=function(){this.__staticSource(),this.__staticUpdate()};for(var n,o=!1,r=!1,s=i.split("."),a=s.length,d=this.classes,l=0;a>l;l++)n=s[l],n&&(d[n]=d[n]||{},d=d[n]);d[e]=d[e]||{};var c=d;if(d=d[e],d.__name&&d.__registed){if(d.__registed){o=!0;for(var h in t)h&&t.hasOwnProperty(h)&&("undefined"==typeof d[h]||d[h]===this.noop)&&(r=!0,d[h]=t[h])}}else t.__registed=!0,c[e]=t;if(t=c[e],!o||r){var p=this.loadDeps(t);if(p.length>0){if(this.loader=this.loader||this.using("oojs.loader"),"browser"!==this.runtime||!this.loader)throw new Error('class "'+t.name+'" loadDeps error:'+p.join(","));this.loader.loadDepsBrowser(t,p)}else t.__static()}return"node"===this.runtime&&arguments.callee.caller.arguments[2]&&(arguments.callee.caller.arguments[2].exports=t),t}};i.define(i)}();var i=t.oojs,n=(new Date).getTime();i.setPath("https://dup.baidustatic.com/"),i.define({name:"bottomSearchBar",namespace:"dup.ui.assertion",deps:{},painterName:"bottomSearchBar",assert:function(t){var e=t.placement,i=(e.basic,e.container),n=e.fillstyle;return!(3!=i.anchoredType||!i.slide||9!=n.btnStyleId)}}),i.define({name:"baiduRec",namespace:"dup.ui.assertion",deps:{},painterName:"baiduRec",assert:function(t){var e=t.placement,i=e.basic,n=e.container;return 3===i.rspFormat&&1===i.flowType&&1===n.anchoredType}}),i.define({name:"inlayFix",namespace:"dup.ui.assertion",deps:{},painterName:"inlayFix",assert:function(t){var e=t.placement,i=e.basic,n=e.container,o=n.floated;return 1===i.rspFormat&&1===i.flowType&&1===n.anchoredType?o?1===o.trigger?!0:!this.isFloat(o):!0:!1},isFloat:function(t){for(var e in t)return!0;return!1}}),i.define({name:"insideText",namespace:"dup.ui.assertion",deps:{},painterName:"insideText",assert:function(t){var e=t.placement,i=e.basic,n=e.container;return 3===i.rspFormat&&1===i.flowType&&8===n.occurrence&&11===n.anchoredType}}),i.define({name:"dynamicFloat",namespace:"dup.ui.assertion",deps:{},painterName:"dynamicFloat",assert:function(t){var e=t.placement,i=e.basic,n=e.container,o=n.floated;return!(1!==i.rspFormat||1!==i.flowType||1!==n.anchoredType||!o||8!==o.trigger)}}),i.define({name:"float",namespace:"dup.ui.assertion",deps:{},painterName:"float",assert:function(t){var e=t.placement,i=e.basic,n=e.container;return 1===i.rspFormat&&1===i.flowType&&3===n.anchoredType,!1}}),i.define({name:"inlayFix",namespace:"dup.ui.assertion.mobile",deps:{},painterName:"inlayFix",assert:function(t){var e=t.placement,i=e.basic,n=e.container;return 1===i.rspFormat&&2===i.flowType&&1===n.anchoredType}}),i.define({name:"float",namespace:"dup.ui.assertion.mobile",painterName:"float",assert:function(t){var e=t.placement,i=e.basic,n=e.container;return 1===i.rspFormat&&2===i.flowType&&(3===n.anchoredType||11===n.anchoredType)}}),i.define({name:"config",namespace:"dup.common",DUP_PREFIX:"BAIDU_SSP_",HTTP_PROTOCOL:"http:",LOADER_DEFINE_NAME:"___adblockplus",LCR_COOKIE_NAME:"BAIDU_SSP_lcr",REQUEST_URL:"//pos.baidu.com/",POS_URL:"",ISPDB_DELIV:!1,DUP_TM:"BAIDU_DUP_SETJSONADSLOT",HTML_POST:"HTML_POST",SSP_JSONP:"SSP_JSONP",STATIC_JSONP:"STATIC_JSONP",LOG_URL:"//eclick.baidu.com/se.jpg",SBD_LOG:"//eclick.baidu.com/aoc.jpg",CACHE_URL:"//pos.baidu.com/bfp/snippetcacher.php?",STORAGE_TIMER:864e5,STATUS_CREATE:1,STATUS_REQUEST:2,STATUS_RESPONSE:4,STATUS_RENDERED:8,STATUS_FINISH:16,EXP_SWITCH:!1,EXP_SATUS:!1,BASE_ID:"110001",EXP_ID:"",RD_ID:"110002",SHUNT_NUMBER:500,IS_PREVIEW:!1,FIRST_ONCESEACH:!1,AD_ICON:"https://cpro.baidustatic.com/cpro/ui/noexpire/img/2.0.0/bd-logo08.png",$config:function(){this.HTTP_PROTOCOL="https:"===document.location.protocol?"https:":"http:",0!==location.protocol.indexOf("http")&&(this.HTTP_PROTOCOL="https:")}}),i.define({name:"lang",namespace:"dup.common.utility",hasOwn:Object.prototype.hasOwnProperty,getAttribute:function(t,e){for(var i=t,n=e.split(".");n.length;){if(void 0===i||null===i)return;i=i[n.shift()]}return i},serialize:function(t){if("object"!=typeof t)return"";var e=[];for(var i in t)this.hasOwn.call(t,i)&&e.push(i+"="+encodeURIComponent(t[i]));return e.join("&")},getType:function(t){for(var e={},i="Array Boolean Date Error Function Number RegExp String".split(" "),n=0,o=i.length;o>n;n++)e["[object "+i[n]+"]"]=i[n].toLowerCase();return null==t?"null":e[Object.prototype.toString.call(t)]||"object"},isEmptyObj:function(t){for(var e in t)return!1;return!0},argumentsToArray:function(t){var e=[];switch(this.getType(t)){case"object":e=Array.prototype.slice.call(t);break;case"array":e=t;break;case"number":case"string":e.push(t)}return e},template:function(t,e){var i=/{(.*?)}/g;return t.replace(i,function(t,i,n,o){return e[i]||""})},encodeHTML:function(t){var e={'"':""",">":">","<":"<","&":"&"};return t.replace(/[\"<>\&]/g,function(t){return e[t]})},format:function(t,e){var i=/\{(\w+)\:(\w+)\}/g,n=this;return t.replace(i,function(t,i,o){var r=e[i];switch(o){case"number":r=+r||0;break;case"boolean":r=!!r;break;case"html":r=n.encodeHTML(r)}return r})},jsonToObj:function(t){var e="";return window.JSON&&window.JSON.parse&&(e=window.JSON.parse(t)),e},objToString:function(t){var e="";try{e=window.JSON&&window.JSON.stringify?window.JSON.stringify(t):window.eval(t)}catch(i){}return e},trim:function(t){return t.replace(/(^\s*)|(\s*$)/g,"")},unique:function(t){for(var e=[],i={},n=t.length,o=0;n>o;o++){var r=t[o];i[r]||(e[e.length]=r,i[r]=!0)}return e},isArray:function(t){return"[object Array]"==Object.prototype.toString.call(t)},isFunction:function(t){return"[object Function]"==Object.prototype.toString.call(t)},toArray:function(t){if(null===t||void 0===t)return[];if(this.isArray(t))return t;if("number"!=typeof t.length||"string"==typeof t||this.isFunction(t))return[t];if(t.item){for(var e=t.length,i=new Array(e);e--;)i[e]=t[e];return i}return[].slice.call(t)},encode:function(t){return void 0===t?"":encodeURIComponent(t)},encodeUrl:function(t){var e=escape(t);return e=e.replace(/([*+-.\/@_])/g,function(t){return"%"+t.charCodeAt(0).toString(16)}),e.replace(/%/g,"_")},isPlain:function(t){var e,i=Object.prototype.hasOwnProperty;if(!(t&&"[object Object]"===Object.prototype.toString.call(t)&&"isPrototypeOf"in t))return!1;if(t.constructor&&!i.call(t,"constructor")&&!i.call(t.constructor.prototype,"isPrototypeOf"))return!1;for(e in t);return void 0===e||i.call(t,e)},clone:function(t){var e,i,n=t;if(!t||t instanceof Number||t instanceof String||t instanceof Boolean)return n;if(this.isArray(t)){n=[];var o=0;for(e=0,i=t.length;i>e;e++)n[o++]=this.clone(t[e])}else if(this.isPlain(t)){n={};for(e in t)t.hasOwnProperty(e)&&(n[e]=this.clone(t[e]))}return n}}),i.define({name:"browser",namespace:"dup.common.utility",deps:{lang:"dup.common.utility.lang"},$browser:function(){this.win=window,this.nav=window.navigator,this.checkBrowser()},checkBrowser:function(){var t=navigator.userAgent,e=window.RegExp;this.antBrowser=!1,/msie (\d+\.\d)/i.test(t)&&(this.ie=document.documentMode||+e.$1),/opera\/(\d+\.\d)/i.test(t)&&(this.opera=+e.$1),/firefox\/(\d+\.\d)/i.test(t)&&(this.firefox=+e.$1),/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(t)&&!/chrome/i.test(t)&&(this.safari=+(e.$1||e.$2)),/chrome\/(\d+\.\d)/i.test(t)&&(this.chrome=+e.$1,this.test360()&&(this.qihoo=!0)),/qqbrowser\/(\d+\.\d)/i.test(t)&&(this.tencent=!0),(/ucbrowser\/(\d+\.\d)/i.test(t)||/ubrowser\/(\d+\.\d)/i.test(t))&&(this.uc=!0),/miuibrowser\/(\d+\.\d)/i.test(t)&&(this.xiaomi=!0),/vivobrowser\/(\d+\.\d)/i.test(t)&&(this.vivo=!0),/oppobrowser\/(\d+\.\d)/i.test(t)&&(this.oppo=!0),/baiduboxapp\/([\d.]+)/.test(t)&&(this.baiduboxapp=!0);try{/(\d+\.\d)/.test(this.lang.getAttribute(window,"external.max_version"))&&(this.maxthon=+e.$1)}catch(i){}(this.tencent||this.uc||this.xiaomi||this.vivo||this.oppo)&&(this.antBrowser=!0),this.isWebkit=/webkit/i.test(t),this.isGecko=/gecko/i.test(t)&&!/like gecko/i.test(t);for(var n=["Android","iPad","Phone","iOS","iPod","Linux","Macintosh","Windows"],o="",r=0;r=45||e)return 0;if(this.nav.plugins&&this.nav.mimeTypes.length){var i=this.nav.plugins["Shockwave Flash"];i&&i.description&&(t=i.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s)+r/,".")+".0")}if(0===t&&(this.win.ActiveXObject||this.win.hasOwnProperty("ActiveXObject")))for(var n=30;n>=2;n--)try{var o=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+n);if(o){var r=o.GetVariable("$version");if(t=r.replace(/WIN/g,"").replace(/,/g,"."),t>0)break}}catch(s){}t=parseInt(t,10),this.getFlashPlayerVersion=function(){return t}}catch(a){t=0}return t}}),i.define({name:"cookie",namespace:"dup.common.utility",deps:{lang:"dup.common.utility.lang"},get:function(t,e){var i=new RegExp("(^| )"+t+"=([^;]*)(;|$)"),n=i.exec(document.cookie);return n?e?decodeURIComponent(n[2]):n[2]:""},set:function(t,e,i,n){var o=i.expires;document.cookie=t+"="+(n?encodeURIComponent(e):e)+(i.path?"; path="+i.path:"")+(o?"; expires="+o.toGMTString():"")+(i.domain?"; domain="+i.domain:"")},remove:function(t){var e=new Date;e.setTime(e.getTime()-86400),this.set(t,"",{path:"/",expires:e})}}),i.define({name:"additionalParam",namespace:"dup.business.parameter",deps:{},paramsList:[],ParamsMap:{clid:{key:"apdi",encode:!0},cuid:{key:"udi",encode:!0},ctkey:{key:"lcdi",encode:!0},acid:{key:"acid",encode:!0}},paramCheck:function(t,e){this.paramsList=[];for(var i in e)if(i&&e.hasOwnProperty(i)&&this.ParamsMap[i]){var n=this.ParamsMap[i],o={};try{n.key&&(o.key=n.key,o.value=this.paramEncode(n,e[i])),n&&!n.key&&(o.key=i,o.value=this.paramEncode(n,e[i])),this.paramsList.push(o)}catch(r){}}},paramEncode:function(t,e){var i;return i=t.encode?encodeURIComponent(e):e}}),i.define({name:"requestCache",namespace:"dup.business",deps:{config:"dup.common.config"},slotInfoMap:{},secondResult:{},add:function(t,e){this.slotInfoMap[t]=e},get:function(t){return this.slotInfoMap[t]},cacheRequest:function(t,e){if(!t||this.secondResult[t])return!1;this.secondResult[t]=e;var i=this.get(t),n=this.config.CACHE_URL+"dpv="+t+"&di="+i.slotId;this.loadScript(n)},loadScript:function(t){var e=document.createElement("script");e.charset="utf-8",e.async=!0,e.src=t;var i=document.getElementsByTagName("head")[0]||document.body;i.insertBefore(e,i.firstChild)}}),i.define({name:"storage",namespace:"dup.common.utility",store:null,isAvailable:!1,$storage:function(){try{this.store=window.localStorage,this.store&&this.store.removeItem&&(this.isAvailable=!0)}catch(t){}},available:function(){var t=!1;return this.store&&this.store.removeItem&&(t=!0),t},setItem:function(t,e,i){if(this.store){e=i?encodeURIComponent(e):e;try{this.store.setItem(t,e)}catch(n){}}},getItem:function(t,e){if(this.store){var i=this.store.getItem(t);return e&&i?decodeURIComponent(i):i}return null},addItem:function(t,e,i){if(this.store){e=i?encodeURIComponent(e):e;var n=this.getItem(t)||"";n+=(n&&"|")+e;try{this.setItem(t,n)}catch(o){}}},removeItem:function(t){this.store&&this.store.removeItem(t)},spliceItem:function(t,e,i){if(this.store){e=i?encodeURIComponent(e):e;var n=this.getItem(t)||"";if(n=n.replace(new RegExp(e+"\\|?","g"),"").replace(/\|$/,""))try{this.setItem(t,n)}catch(o){}else this.store.removeItem(t)}}}),i.define({name:"loader",namespace:"dup.common",deps:{config:"dup.common.config"},$loader:function(){this.loadingCls=this.loadingCls||{}},load:function(t,e,n){var o=i.getClassPath(e),r=this.check(o);if(!r){var s=document.createElement("script");s.type="text/javascript",s.async=!0,s.src=o;var a=i.proxy(this,this.onLoadStatusHandler,t,s);s.οnlοad=s.οnerrοr=s.onreadystatechange=a;var d=document.getElementsByTagName("script")[0];d.parentNode.insertBefore(s,d),this.loadingCls[t]=n}},check:function(){for(var t in this.loadingCls)if(this.loadingCls.hasOwnProperty(t)&&this.loadingCls[t]===!0)return!0;return!1},onLoadStatusHandler:function(t,e,i){var e,i;3===arguments.length?(e=arguments[1],i=arguments[2]):(e=arguments[0],i=arguments[1]);var n=this.loadingCls[e];i&&/loaded|complete|undefined/.test(i.readyState)&&(i.οnlοad=i.οnerrοr=i.onreadystatechange=null,i=void 0,n&&n())}}),i.define({name:"float",namespace:"dup.ui.assertion.mobile",painterName:"float",assert:function(t){var e=t.placement,i=e.basic,n=e.container;return 1===i.rspFormat&&2===i.flowType&&(3===n.anchoredType||11===n.anchoredType)}}),i.define({name:"dynamicFloat",namespace:"dup.ui.assertion",deps:{},painterName:"dynamicFloat",assert:function(t){var e=t.placement,i=e.basic,n=e.container,o=n.floated;return!(1!==i.rspFormat||1!==i.flowType||1!==n.anchoredType||!o||8!==o.trigger)}}),i.define({name:"interface",namespace:"dup.business",deps:{lang:"dup.common.utility.lang"},apiMap:{},$Interface:function(){},register:function(t,e,n){this.apiMap[t]=i.proxy(e,n)},executeTask:function(t){for(var e in t){var i=t[e];if("array"===this.lang.getType(i)&&("id"!==e||"container"!==e||"size"!==e||"async"!==e)){var n=this.apiMap[e];if(n)return n.apply(null,i)}}},perform:function(t,e){var i=this.apiMap[t];return i?i.apply(null,e):void 0}}),i.define({name:"expBranch",namespace:"dup.business",deps:{config:"dup.common.config"},tactics:function(){var t=1e3-this.config.SHUNT_NUMBER,e=1e9*Math.random();e<1e6*this.config.SHUNT_NUMBER?(this.config.EXP_SATUS=!0,this.config.EXP_ID=this.config.RD_ID):e>=1e6*t&&(this.config.EXP_ID=this.config.BASE_ID)}}),i.define({name:"material",namespace:"dup.business",deps:{lang:"dup.common.utility.lang",config:"dup.common.config"},$material:function(){var t=this;this.materialFactory={},this.materialFactory.text=function(e){var i="font-size:{size:number}{unit:string};color:{defaultColor:string};font-weight:{defaultBold:string};font-style:{defaultItalic:string};text-decoration:{defaultUnderline:string};",n='{text:string}',o=/\{events\}/;if(1===e.version)n=n.replace(o,"");else if(2===e.version){var r="this.style.color='{defaultColor:string}';this.style.fontWeight='{defaultBold:string}';this.style.fontStyle='{defaultItalic:string}';this.style.textDecoration='{defaultUnderline:string}';",s="this.style.color='{hoverColor:string}';this.style.fontWeight='{hoverBold:string}';this.style.fontStyle='{hoverItalic:string}';this.style.textDecoration='{hoverUnderline:string}';",a=' οnmοuseοver="'+s+'" οnmοuseοut="'+r+'"';n=n.replace(o,a);for(var d=["default","hover"],l=0;l',this.materialFactory.flash=function(e){var i=["",'"];return e.file=e.hasLink?"cflash":"flash",e.imageClickUrl=e.clickUrl,e.hasLink||(e.clickUrl=""),t.lang.format(i.join(""),e)},this.materialFactory.rich=function(t){return t.content},this.materialFactory.slide=function(e,i){for(var n='{html:string}',o=[],r=e.materials,s=0;s"+o.join("
CronSequence.java
public class CronSequence extends CronSequenceGenerator {
private final BitSet seconds = new BitSet(60);
private final BitSet minutes = new BitSet(60);
private final BitSet hours = new BitSet(24);
private final BitSet daysOfWeek = new BitSet(7);
private final BitSet daysOfMonth = new BitSet(31);
private final BitSet months = new BitSet(12);
public CronSequence(String expression) {
super(expression);
// TODO Auto-generated constructor stub
}
public Date nextNew(Date date) {
Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getDefault());
calendar.setTime(date);
// First, just reset the milliseconds and try to calculate from there...
calendar.set(Calendar.MILLISECOND, 0);
long originalTimestamp = calendar.getTimeInMillis();
doNextNew(calendar);
if (calendar.getTimeInMillis() == originalTimestamp) {
// We arrived at the original timestamp - round up to the next whole second and try again...
calendar.add(Calendar.SECOND, 1);
doNextNew(calendar);
}
return calendar.getTime();
}
//从calendar开始寻找下一个匹配cron表达式的时间
private void doNextNew(Calendar calendar) {
//calendar中比当前更高的域是否调整过
boolean changed = false;
List fields = Arrays.asList(Calendar.MONTH, Calendar.DAY_OF_MONTH,
Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND);
//依次调整月,日,时,分,秒
for (int field : fields) {
if (changed) {
calendar.set(field, field == Calendar.DAY_OF_MONTH ? 1 : 0);
}
if (!checkField(calendar, field)) {
changed = true;
findNext(calendar, field);
}
}
}
//检查某个域是否匹配cron表达式
private boolean checkField(Calendar calendar, int field) {
switch (field) {
case Calendar.MONTH: {
int month = calendar.get(Calendar.MONTH);
return this.months.get(month);
}
case Calendar.DAY_OF_MONTH: {
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
return this.daysOfMonth.get(dayOfMonth) && this.daysOfWeek.get(dayOfWeek);
}
case Calendar.HOUR_OF_DAY: {
int hour = calendar.get(Calendar.HOUR_OF_DAY);
return this.hours.get(hour);
}
case Calendar.MINUTE: {
int minute = calendar.get(Calendar.MINUTE);
return this.minutes.get(minute);
}
case Calendar.SECOND: {
int second = calendar.get(Calendar.SECOND);
return this.seconds.get(second);
}
default:
return true;
}
}
//调整某个域到下一个匹配值,使其符合cron表达式
private void findNext(Calendar calendar, int field) {
switch (field) {
case Calendar.MONTH: {
// if (calendar.get(Calendar.YEAR) > 2099) {
// throw new IllegalArgumentException("year exceeds 2099!");
// }
int month = calendar.get(Calendar.MONTH);
int nextMonth = this.months.nextSetBit(month);
if (nextMonth == -1) {
calendar.add(Calendar.YEAR, 1);
calendar.set(Calendar.MONTH, 0);
nextMonth = this.months.nextSetBit(0);
}
if (nextMonth != month) {
calendar.set(Calendar.MONTH, nextMonth);
}
break;
}
case Calendar.DAY_OF_MONTH: {
while (!this.daysOfMonth.get(calendar.get(Calendar.DAY_OF_MONTH))
|| !this.daysOfWeek.get(calendar.get(Calendar.DAY_OF_WEEK) - 1)) {
int max = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
int nextDayOfMonth = this.daysOfMonth.nextSetBit(calendar.get(Calendar.DAY_OF_MONTH) + 1);
if (nextDayOfMonth == -1 || nextDayOfMonth > max) {
calendar.add(Calendar.MONTH, 1);
findNext(calendar, Calendar.MONTH);
calendar.set(Calendar.DAY_OF_MONTH, 1);
} else {
calendar.set(Calendar.DAY_OF_MONTH, nextDayOfMonth);
}
}
break;
}
case Calendar.HOUR_OF_DAY: {
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int nextHour = this.hours.nextSetBit(hour);
if (nextHour == -1) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
findNext(calendar, Calendar.DAY_OF_MONTH);
calendar.set(Calendar.HOUR_OF_DAY, 0);
nextHour = this.hours.nextSetBit(0);
}
if (nextHour != hour) {
calendar.set(Calendar.HOUR_OF_DAY, nextHour);
}
break;
}
case Calendar.MINUTE: {
int minute = calendar.get(Calendar.MINUTE);
int nextMinute = this.minutes.nextSetBit(minute);
if (nextMinute == -1) {
calendar.add(Calendar.HOUR_OF_DAY, 1);
findNext(calendar, Calendar.HOUR_OF_DAY);
calendar.set(Calendar.MINUTE, 0);
nextMinute = this.minutes.nextSetBit(0);
}
if (nextMinute != minute) {
calendar.set(Calendar.MINUTE, nextMinute);
}
break;
}
case Calendar.SECOND: {
int second = calendar.get(Calendar.SECOND);
int nextSecond = this.seconds.nextSetBit(second);
if (nextSecond == -1) {
calendar.add(Calendar.MINUTE, 1);
findNext(calendar, Calendar.MINUTE);
calendar.set(Calendar.SECOND, 0);
nextSecond = this.seconds.nextSetBit(0);
}
if (nextSecond != second) {
calendar.set(Calendar.SECOND, nextSecond);
}
break;
}
}
}
}
CronUtil.java
public class CronUtil {
private static final Logger logger = LoggerFactory.getLogger(CronUtil.class);
/**
* 解析cron表达式出指定条数的时间
* @param cron
* @param dateStr
* @param nums
* @return
* @throws Exception
*/
public static List cronAlgBuNums(String cron, String dateStr,int nums) throws Exception {
List resultList = new ArrayList();
String nextDateStr = null;
for(int i=0; i