版权声明:本文为博主原创文章,转载请附上原文链接,谢谢! https://blog.csdn.net/qq_21454973/article/details/81979660
以上,感谢。
首先引入jar:
<!-- quartz定时任务 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
然后数据库,两个表,如图:
s_timetask:
s_timetask_log:
mapper/model/dao层用mybatis generator 自动生成,此处省略;
service/impl也没有写逻辑,此处省略;
各类我放入一个package中:
public class InitQuartzJob implements ApplicationContextAware {
private static final Logger logger = Logger.getLogger(InitQuartzJob.class);
private static ApplicationContext appCtx;
public static SchedulerFactoryBean schedulerFactoryBean = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// TODO Auto-generated method stub
if (this.appCtx == null) {
this.appCtx = applicationContext;
}
}
public static void init() {
/*
* STimetaskService sTimetaskService = (STimetaskService)
* SpingInit.getApplicationContext().getBean("sTimetaskServiceImpl");
*/
STimetaskService sTimetaskService = (STimetaskService) SpringUtils.getBean(STimetaskService.class);
schedulerFactoryBean = (SchedulerFactoryBean) appCtx.getBean(SchedulerFactoryBean.class);
Scheduler scheduler = schedulerFactoryBean.getScheduler();
try {
logger.info(scheduler.getSchedulerName());
} catch (SchedulerException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 这里从数据库中获取任务信息数据
STimetaskExample example = new STimetaskExample();
STimetaskExample.Criteria c = example.createCriteria();
c.andJobStatusEqualTo("1"); // 已发布的定时任务
List<STimetask> list = sTimetaskService.selectByExample(example);
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
for (STimetask sTimetask : list) {
ScheduleJob job1 = new ScheduleJob();
job1.setJobId(sTimetask.getId());
job1.setJobGroup(sTimetask.getGroupName()); // 任务组
job1.setJobName(sTimetask.getName());// 任务名称
job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
// 1:run
// 0:stop
job1.setCronExpression(sTimetask.getCron());
job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
job1.setMethodName(sTimetask.getMethodName());
job1.setJobData(sTimetask.getJobData()); // 参数
jobList.add(job1);
}
for (ScheduleJob job : jobList) {
try {
addJob(job);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 添加任务
*
* @param scheduleJob
* @throws SchedulerException
*/
public static void addJob(ScheduleJob job) throws SchedulerException {
if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
return;
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
logger.info(scheduler + "...........................................add");
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 不存在,创建一个
if (null == trigger) {
Class clazz = ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent()) ? QuartzJobFactory.class
: QuartzJobFactoryDisallowConcurrentExecution.class;
JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup())
.usingJobData("data", job.getJobData()).build();
jobDetail.getJobDataMap().put("scheduleJob", job);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
trigger = TriggerBuilder.newTrigger().withDescription(job.getJobId().toString())
.withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
} else {
// Trigger已存在,那么更新相应的定时设置
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).usingJobData("data", job.getJobData())
.withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
if ("0".equals(job.getIsConcurrent())) {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
scheduler.pauseJob(jobKey);
}
}
}
public class QuartzJobFactory implements Job {
public final Logger log = Logger.getLogger(this.getClass());
public void execute(JobExecutionContext context) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);
}
}
@DisallowConcurrentExecution
public class QuartzJobFactoryDisallowConcurrentExecution implements Job {
public final Logger log = Logger.getLogger(this.getClass());
public void execute(JobExecutionContext context) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);
}
}
public class ScheduleJob {
public static final String STATUS_RUNNING = "1"; // 正在运行
public static final String STATUS_NOT_RUNNING = "0"; // 已停止
public static final String CONCURRENT_IS = "1";
public static final String CONCURRENT_NOT = "0";
private String jobId;
private Date createTime;
private Date updateTime;
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 任务状态 是否启动任务
*/
private String jobStatus;
/**
* cron表达式
*/
private String cronExpression;
/**
* 描述
*/
private String description;
/**
* 任务执行时调用哪个类的方法 包名+类名
*/
private String beanClass;
/**
* 任务是否有状态
*/
private String isConcurrent;
/**
* spring bean
*/
private String springId;
/**
* 任务调用的方法名
*/
private String methodName;
private String jobData;
public String getJobData() {
return jobData;
}
public void setJobData(String jobData) {
this.jobData = jobData;
}
public String getSpringId() {
return springId;
}
public void setSpringId(String springId) {
this.springId = springId;
}
public String getJobId() {
return jobId;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public String getJobStatus() {
return jobStatus;
}
public void setJobStatus(String jobStatus) {
this.jobStatus = jobStatus;
}
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getBeanClass() {
return beanClass;
}
public void setBeanClass(String beanClass) {
this.beanClass = beanClass;
}
public String getIsConcurrent() {
return isConcurrent;
}
public void setIsConcurrent(String isConcurrent) {
this.isConcurrent = isConcurrent;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
}
public class TaskUtils {
public final static Logger log = Logger.getLogger(TaskUtils.class);
private static STimetaskLogService sTimetaskLogService = (STimetaskLogService)
SpringUtils.getBean(STimetaskLogService.class);
/**
* 通过反射调用scheduleJob中定义的方法
*
* @param scheduleJob
*/
@SuppressWarnings("unchecked")
public static void invokMethod(ScheduleJob scheduleJob) {
Object object = null;
Class clazz = null;
boolean flag = true;
if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
object = SpringUtils.getBean(scheduleJob.getSpringId());
} else if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
try {
clazz = Class.forName(scheduleJob.getBeanClass());
object = clazz.newInstance();
} catch (Exception e) {
flag = false;
STimetaskLog tlog = new STimetaskLog();
tlog.setId(UuidUtils.creatUUID());
tlog.setCreateDate(new Date());
tlog.setJobId(scheduleJob.getJobId().toString());
tlog.setReason("未找到"+scheduleJob.getBeanClass()+"对应的class");
tlog.setState("fail");
sTimetaskLogService.insertSelective(tlog);
e.printStackTrace();
}
}
if (object == null) {
flag = false;
log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!");
STimetaskLog tlog = new STimetaskLog();
tlog.setId(UuidUtils.creatUUID());
tlog.setCreateDate(new Date());
tlog.setJobId(scheduleJob.getJobId().toString());
tlog.setReason("未找到"+scheduleJob.getBeanClass()+"对应的class");
tlog.setState("fail");
sTimetaskLogService.insertSelective(tlog);
return;
}
clazz = object.getClass();
Method method = null;
try {
method = clazz.getDeclaredMethod(scheduleJob.getMethodName(), new Class[] { String.class });
} catch (NoSuchMethodException e) {
flag = false;
log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!");
STimetaskLog tlog = new STimetaskLog();
tlog.setId(UuidUtils.creatUUID());
tlog.setCreateDate(new Date());
tlog.setJobId(scheduleJob.getJobId().toString());
tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法");
tlog.setState("fail");
sTimetaskLogService.insertSelective(tlog);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (method != null) {
try {
method.invoke(object, scheduleJob.getJobData());
} catch (IllegalAccessException e) {
flag = false;
STimetaskLog tlog = new STimetaskLog();
tlog.setId(UuidUtils.creatUUID());
tlog.setCreateDate(new Date());
tlog.setJobId(scheduleJob.getJobId().toString());
tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误");
tlog.setState("fail");
sTimetaskLogService.insertSelective(tlog);
e.printStackTrace();
} catch (IllegalArgumentException e) {
flag = false;
STimetaskLog tlog = new STimetaskLog();
tlog.setId(UuidUtils.creatUUID());
tlog.setCreateDate(new Date());
tlog.setJobId(scheduleJob.getJobId().toString());
tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误");
tlog.setState("fail");
sTimetaskLogService.insertSelective(tlog);
e.printStackTrace();
} catch (InvocationTargetException e) {
flag = false;
STimetaskLog tlog = new STimetaskLog();
tlog.setId(UuidUtils.creatUUID());
tlog.setCreateDate(new Date());
tlog.setJobId(scheduleJob.getJobId().toString());
tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误");
tlog.setState("fail");
sTimetaskLogService.insertSelective(tlog);
e.printStackTrace();
}
}
if(flag){
System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]----------启动成功");
STimetaskLog tlog = new STimetaskLog();
tlog.setId(UuidUtils.creatUUID());
tlog.setCreateDate(new Date());
tlog.setJobId(scheduleJob.getJobId().toString());
tlog.setState("success");
sTimetaskLogService.insertSelective(tlog);
}
}
}
InitQuartzJob 是程序初始化定时任务,QuartzJobFactory 是管理的工厂类(其实我也不知道干啥的...),ScheduleJob 是定时任务的实体类,TaskUtils 是定时任务的执行结果,会入库到表.
管理定时任务的类:
@Controller
@RequestMapping(value = "/admin/task")
public class ManageTimetaskController {
static Logger logger = Logger.getLogger(ManageTimetaskController.class);
@Autowired
STimetaskService sTimetaskService;
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@SystemControllerLog(description="增加定时任务")
@RequestMapping(value = "/add", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
@ResponseBody
public String add(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
try {
Managers manager = (Managers) httpSession.getAttribute("managers");
if (manager == null) {
code = "200";
message = "用户登录异常";
return GiveBack.make(code, message, data);
}
String name = request.getParameter("name");
String desccription = request.getParameter("desccription");
String cron = request.getParameter("cron");
String jobStatus = request.getParameter("jobStatus");
String jobData = request.getParameter("jobData");
String methodName = request.getParameter("methodName");
if (StringUtils.isBlank(name) || StringUtils.isBlank(desccription) || StringUtils.isBlank(cron)
|| StringUtils.isBlank(jobStatus) || StringUtils.isBlank(jobData) || StringUtils.isBlank(methodName)
) {
code = "200";
message = "必要参数为空";
return GiveBack.make(code, message, data);
}
if (name.length() > 50 || desccription.length() > 1000 || (!isValidExpression(cron)) || (!isOne(jobStatus))
|| jobData.length() > 2000 || (!checkMethodName(methodName))) {
code = "201";
message = "参数异常";
return GiveBack.make(code, message, data);
}
String[] ipList = jobData.split(",");
for (int i = 0; i < ipList.length; i++) {
String tempIp = ipList[i];
if(!isIP(tempIp)){
code = "201";
message = "jobData异常";
return GiveBack.make(code, message, data);
}
}
STimetask record = new STimetask();
record.setId(UuidUtils.creatUUID());
record.setName(name);
record.setGroupName("pdu");
Date date = new Date();
record.setStartTime(date);
record.setEndTime(date);
record.setCron(cron);
record.setJobStatus(jobStatus);
record.setIsConcurrent(0);
record.setPlanStatus("-1");
record.setJobData(jobData);
record.setMethodName(methodName);
record.setBeanName("com.utils.tprs_pdu.TPRSOrderSendHelper");
record.setDesccription(desccription);
record.setCreateUserId(manager.getId());
record.setCreateDate(date);
int i = sTimetaskService.insertSelective(record);
if (i < 1) {
code = "1";
message = "请求成功但未发生任何更改";
return GiveBack.make(code, message, data);
}
code = "0";
return GiveBack.make(code, message, data);
} catch (Exception e) {
code = "-1";
message = "系统异常";
return GiveBack.make(code, message, data);
}
}
@SystemControllerLog(description="删除定时任务")
@RequestMapping(value = "/del", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
@ResponseBody
public String del(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
try {
String id = request.getParameter("id");
String[] idList = id.split(",");
JSONArray arr = new JSONArray();
code = "0";
for (int i = 0; i < idList.length; i++) {
JSONObject json = new JSONObject();
String singleId = idList[i];
final STimetask sTimetask = sTimetaskService.selectByPrimaryKey(singleId);
final String name = sTimetask.getName();
final String groupName = sTimetask.getGroupName();
int res = sTimetaskService.deleteByPrimaryKey(singleId);
if (res < 1) {
code = "1";
json.put(singleId, "请求成功但未发生任何更改");
}else{
json.put(singleId, "请求成功");
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(name, groupName);
try {
scheduler.deleteJob(jobKey);
} catch (SchedulerException e1) {
e1.printStackTrace();
code = "-1";
json.put(singleId, "系统异常导致任务删除成功,但计划仍在执行,请联系管理员");
}
arr.add(json);
}
data = arr.toJSONString();
return GiveBack.make(code, message, data);
} catch (Exception e) {
code = "-1";
message = "系统异常";
return GiveBack.make(code, message, data);
}
}
@SystemControllerLog(description="更新定时任务")
@RequestMapping(value = "/update", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
@ResponseBody
public String update(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
try {
Managers manager = (Managers) httpSession.getAttribute("managers");
if (manager == null) {
code = "200";
message = "用户登录异常";
return GiveBack.make(code, message, data);
}
final String id = request.getParameter("id");
String name = request.getParameter("name");
String desccription = request.getParameter("desccription");
String cron = request.getParameter("cron");
String jobStatus = request.getParameter("jobStatus");
String jobData = request.getParameter("jobData");
String methodName = request.getParameter("methodName");
if (StringUtils.isBlank(name) || StringUtils.isBlank(desccription) || StringUtils.isBlank(cron)
|| StringUtils.isBlank(jobStatus) || StringUtils.isBlank(jobData) || StringUtils.isBlank(methodName)
) {
code = "200";
message = "必要参数为空";
return GiveBack.make(code, message, data);
}
if (name.length() > 50 || desccription.length() > 1000 || (!isValidExpression(cron)) || (!isOne(jobStatus))
|| jobData.length() > 2000 || (!checkMethodName(methodName)) ) {
code = "201";
message = "参数异常";
return GiveBack.make(code, message, data);
}
STimetask record = new STimetask();
record.setId(id);
record.setName(name);
record.setGroupName("pdu");
Date date = new Date();
record.setStartTime(date);
record.setEndTime(date);
record.setCron(cron);
record.setJobStatus(jobStatus);
record.setJobData(jobData);
record.setMethodName(methodName);
record.setBeanName("com.utils.tprs_pdu.TPRSOrderSendHelper");
record.setDesccription(desccription);
record.setModifyUserId(manager.getId());
record.setModifyDate(date);
int i = sTimetaskService.updateByPrimaryKeySelective(record);
if (i < 1) {
code = "1";
message = "请求成功但未发生任何更改";
return GiveBack.make(code, message, data);
}else{
code = "0";
threadPoolTaskExecutor.execute(new Thread(id){
public void run() {
STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
if("1".equals(sTimetask.getJobStatus())&&"1".equals(sTimetask.getPlanStatus())
&&"1".equals(""+sTimetask.getIsConcurrent())){
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
try {
scheduler.deleteJob(jobKey);
} catch (SchedulerException e1) {
e1.printStackTrace();
}
ScheduleJob job1 = new ScheduleJob();
job1.setJobId(sTimetask.getId());
job1.setJobGroup(sTimetask.getGroupName()); // 任务组
job1.setJobName(sTimetask.getName());// 任务名称
job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
// 1:run
// 0:stop
job1.setCronExpression(sTimetask.getCron());
job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
job1.setMethodName(sTimetask.getMethodName());
job1.setJobData(sTimetask.getJobData()); // 参数
try {
InitQuartzJob.addJob(job1);
} catch (SchedulerException e) {
e.printStackTrace();
}
sTimetask.setIsConcurrent(1);
sTimetask.setPlanStatus("1");
sTimetaskService.updateByPrimaryKeySelective(sTimetask);
}
}
});
return GiveBack.make(code, message, data);
}
} catch (Exception e) {
code = "-1";
message = "系统异常";
return GiveBack.make(code, message, data);
}
}
@RequestMapping(value = "/get", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
@ResponseBody
public String get(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
try {
String pageNumStr = request.getParameter("pageNum");
String pageSizeStr = request.getParameter("pageSize");
STimetaskExample example = new STimetaskExample();
STimetaskExample.Criteria criteria = example.createCriteria();
String name = request.getParameter("name");
String jobStatus = request.getParameter("jobStatus");
if(StringUtils.isNotEmpty(name)){
criteria.andNameLike("%"+name+"%");
}
out:if(StringUtils.isNotEmpty(jobStatus)){
if("-1".equals(jobStatus)){
break out;
}
if(!"1".equals(jobStatus)&&!"0".equals(jobStatus)){
code = "201";
message = "参数异常";
return GiveBack.make(code, message, data);
}
criteria.andJobStatusEqualTo(jobStatus);
}
int pageNum = 0;
int pageSize = 0;
try {
pageNum = Integer.parseInt(pageNumStr);
pageSize = Integer.parseInt(pageSizeStr);
} catch (Exception e) {
code = "100";
message = "类型转换异常";
return GiveBack.make(code, message, data);
}
Page<STimetask> page = sTimetaskService.pageSelectByExample(example, pageNum, pageSize);
List<STimetask> list = page.subList(0, page.size());
JSONObject json = new JSONObject();
json.put("pages",page.getPages());
json.put("totals",page.getTotal());
message = json.toString();
JSONArray arr = new JSONArray();
if(list.size() == 0){
data = "";
}else{
for (int i = 0; i < list.size(); i++) {
JSONObject json2 = new JSONObject();
STimetask s = list.get(i);
json2.put("id", s.getId());
json2.put("desccription", s.getDesccription() == null?"":s.getDesccription());
json2.put("name", s.getName() == null?"":s.getName());
json2.put("cron", s.getCron() == null?"":s.getCron());
json2.put("jobStatus", s.getJobStatus() == null?"":s.getJobStatus());
json2.put("isCon", s.getIsConcurrent() == null?"":s.getIsConcurrent());
json2.put("planStatus", s.getPlanStatus() == null?"":s.getPlanStatus());
json2.put("jobData", s.getJobData() == null?"":s.getJobData());
json2.put("methodName", s.getMethodName() == null?"":s.getMethodName());
json2.put("createUserId",s.getCreateUserId() == null?"":s.getCreateUserId());
json2.put("createTime", s.getCreateDate().toLocaleString() == null?"":s.getCreateDate().toLocaleString());
json2.put("modifyUserId",s.getModifyUserId() == null?"":s.getModifyUserId());
json2.put("modifyTime", s.getModifyDate() == null?"":s.getModifyDate());
arr.add(json2);
}
}
code = "0";
data = arr.toJSONString();
return GiveBack.make(code, message, data);
} catch (Exception e) {
code = "-1";
message = e.toString();
return GiveBack.make(code, message, data);
}
}
private static boolean isOne(String str) {
return "1".equals(str) || "0".equals(str) ? true : false;
}
private static boolean checkMethodName(String str) {
if (StringUtils.isBlank(str)) {
return false;
}
String[] names = { "open", "close" };
boolean res = false;
for (int i = 0; i < names.length; i++) {
if (str.equals(names[i])) {
res = true;
}
}
return res;
}
private static boolean isValidExpression(final String cronExpression) {
CronTriggerImpl trigger = new CronTriggerImpl();
try {
trigger.setCronExpression(cronExpression);
Date date = trigger.computeFirstFireTime(null);
return date != null && date.after(new Date());
} catch (Exception e) {
logger.error("[TaskUtils.isValidExpression]:failed. throw ex:" + e);
}
return false;
}
private static boolean isIP(String ip) {
String rexp = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";
return ip.matches(rexp);
}
}
定时任务控制的类:
@Controller
@RequestMapping(value = "/admin/task")
public class TimetaskController {
static Logger logger = Logger.getLogger(ManageTimetaskController.class);
@Autowired
STimetaskService sTimetaskService;
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
@SystemControllerLog(description="加入计划")
@RequestMapping(value = "/addJob", produces = "text/html;charset=UTF-8;")
@ResponseBody
public String addJob(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
String id = request.getParameter("id");
STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
if (sTimetask == null) {
code = "404";
message = "未找到该任务";
return GiveBack.make(code, message, data);
}
//发布即启动
/*if(!"1".equals(sTimetask.getJobStatus())){
code = "1";
message = "请先发布任务";
return GiveBack.make(code, message, data);
}*/
if("1".equals(sTimetask.getPlanStatus())){
code = "1";
message = "该任务已启动";
return GiveBack.make(code, message, data);
}
sTimetask.setJobStatus("1");
sTimetask.setIsConcurrent(1);
sTimetask.setPlanStatus("1");
ScheduleJob job1 = new ScheduleJob();
job1.setJobId(sTimetask.getId());
job1.setJobGroup(sTimetask.getGroupName()); // 任务组
job1.setJobName(sTimetask.getName());// 任务名称
job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
// 1:run
// 0:stop
job1.setCronExpression(sTimetask.getCron());
job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
job1.setMethodName(sTimetask.getMethodName());
job1.setJobData(sTimetask.getJobData()); // 参数
try {
InitQuartzJob.addJob(job1);
sTimetaskService.updateByPrimaryKeySelective(sTimetask);
code = "0";
return GiveBack.make(code, message, data);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
code = "-1";
message = "系统异常,任务启动失败";
return GiveBack.make(code, message, data);
}
}
@SystemControllerLog(description="强制重启")
@RequestMapping(value = "/powerStartJob", produces = "text/html;charset=UTF-8;")
@ResponseBody
public String powerStartJob(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
String id = request.getParameter("id");
STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
try {
scheduler.deleteJob(jobKey);
} catch (SchedulerException e1) {
e1.printStackTrace();
}
ScheduleJob job1 = new ScheduleJob();
sTimetask.setJobStatus("1");
sTimetask.setIsConcurrent(1);
sTimetask.setPlanStatus("1");
job1.setJobId(sTimetask.getId());
job1.setJobGroup(sTimetask.getGroupName()); // 任务组
job1.setJobName(sTimetask.getName());// 任务名称
job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
// 1:run
// 0:stop
job1.setCronExpression(sTimetask.getCron());
job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
job1.setMethodName(sTimetask.getMethodName());
job1.setJobData(sTimetask.getJobData()); // 参数
try {
InitQuartzJob.addJob(job1);
sTimetaskService.updateByPrimaryKeySelective(sTimetask);
code = "0";
return GiveBack.make(code, message, data);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
code = "-1";
message = "系统异常,任务启动失败";
return GiveBack.make(code, message, data);
}
}
@SystemControllerLog(description="暂停计划")
@RequestMapping(value = "/stopJob", produces = "text/html;charset=UTF-8;")
@ResponseBody
public String stopJob(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
String id = request.getParameter("id");
STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
if (sTimetask == null) {
code = "404";
message = "未找到该任务";
return GiveBack.make(code, message, data);
}
if(!"1".equals(sTimetask.getPlanStatus())){
code = "1";
message = "请先加入计划";
return GiveBack.make(code, message, data);
}
if("0".equals(sTimetask.getPlanStatus())){
code = "1";
message = "该任务已暂停";
return GiveBack.make(code, message, data);
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
try {
scheduler.pauseJob(jobKey);
sTimetask.setIsConcurrent(0);
sTimetask.setPlanStatus("0");
sTimetaskService.updateByPrimaryKeySelective(sTimetask);
code = "0";
return GiveBack.make(code, message, data);
} catch (SchedulerException e1) {
e1.printStackTrace();
code = "-1";
message = "暂停失败";
return GiveBack.make(code, message, data);
}
}
@SystemControllerLog(description="恢复计划")
@RequestMapping(value = "/resumeJob", produces = "text/html;charset=UTF-8;")
@ResponseBody
public String resumeJob(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
String id = request.getParameter("id");
STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
if (sTimetask == null) {
code = "404";
message = "未找到该任务";
return GiveBack.make(code, message, data);
}
if(!"0".equals(sTimetask.getPlanStatus())&&!"1".equals(sTimetask.getJobStatus())){
code = "1";
message = "请先加入计划";
return GiveBack.make(code, message, data);
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
try {
scheduler.resumeJob(jobKey);
sTimetask.setIsConcurrent(1);
sTimetask.setPlanStatus("1");
sTimetaskService.updateByPrimaryKeySelective(sTimetask);
code = "0";
return GiveBack.make(code, message, data);
} catch (SchedulerException e1) {
e1.printStackTrace();
code = "-1";
message = "恢复失败";
return GiveBack.make(code, message, data);
}
}
@SystemControllerLog(description="移除计划")
@RequestMapping(value = "/removeJob", produces = "text/html;charset=UTF-8;")
@ResponseBody
public String removeJob(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
String id = request.getParameter("id");
STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
if (sTimetask == null) {
code = "404";
message = "未找到该任务";
return GiveBack.make(code, message, data);
}
if((!"0".equals(sTimetask.getPlanStatus()))&&(!"1".equals(sTimetask.getPlanStatus()))){
code = "1";
message = "该任务已移除";
return GiveBack.make(code, message, data);
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
try {
scheduler.deleteJob(jobKey);
sTimetask.setJobStatus("0");
sTimetask.setIsConcurrent(0);
sTimetask.setPlanStatus("-1");
sTimetaskService.updateByPrimaryKeySelective(sTimetask);
code = "0";
return GiveBack.make(code, message, data);
} catch (SchedulerException e1) {
e1.printStackTrace();
code = "-1";
message = "移除失败";
return GiveBack.make(code, message, data);
}
}
@RequestMapping(value = "/getJob", produces = "text/html;charset=UTF-8;")
@ResponseBody
public String getJob(HttpServletRequest request, HttpSession httpSession) throws SchedulerException {
String code = "";
String message = "";
String data = null;
try {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
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){
data = "";
}else{
data = ObjToJson.JSONPut(jobList).toJSONString();
}
code="0";
return GiveBack.make(code, message, data);
} catch (Exception e) {
code = "-1";
message = "系统异常";
return GiveBack.make(code, message, data);
}
}
}
这里执行的类和方法我写的比较死,当然可以改活.
查看执行日志:
@Controller
@RequestMapping(value = "/admin/task")
public class TimetaskLogController {
static Logger logger = Logger.getLogger(TimetaskLogController.class);
@Autowired
STimetaskLogService sTimetaskLogService;
@Autowired
STimetaskService sTimetaskService;
@RequestMapping(value = "/getLog", produces = "text/html;charset=UTF-8;")
@ResponseBody
public String getLog(HttpServletRequest request, HttpSession httpSession) {
String code = "";
String message = "";
String data = null;
String pageNumStr = request.getParameter("pageNum");
String pageSizeStr = request.getParameter("pageSize");
int pageNum = 0;
int pageSize = 0;
try {
pageNum = Integer.parseInt(pageNumStr);
pageSize = Integer.parseInt(pageSizeStr);
} catch (Exception e) {
code = "100";
message = "类型转换异常";
return GiveBack.make(code, message, data);
}
try {
STimetaskLogExample example = new STimetaskLogExample();
example.setOrderByClause("create_date desc");
Page<STimetaskLog> page = sTimetaskLogService.pageSelectByExample(example, pageNum, pageSize);
List<STimetaskLog> list = page.subList(0, page.size());
JSONObject json = new JSONObject();
json.put("pages",page.getPages());
json.put("totals",page.getTotal());
message = json.toString();
JSONArray arr = new JSONArray();
if(list.size() == 0){
data = "";
}else{
for (int i = 0; i < list.size(); i++) {
JSONObject json2 = new JSONObject();
STimetaskLog s = list.get(i);
json2.put("createDate", s.getCreateDate().toLocaleString());
json2.put("name", sTimetaskService.selectByPrimaryKey(s.getJobId()).getName());
json2.put("result", s.getState());
arr.add(json2);
}
}
code = "0";
data = arr.toJSONString();
return GiveBack.make(code, message, data);
} catch (Exception e) {
code = "-1";
message = "系统异常";
return GiveBack.make(code, message, data);
}
}
}
然后在spring的xml文件中加入(要在扫描其他包之后):
<!-- 初始化springUtils -->
<bean id="springUtils" class="com.utils.base.SpringUtils" />
<!-- 初始化Scheduler -->
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
<!-- 初始化job -->
<bean id="initQuartzJob" class="com.utils.timetask.InitQuartzJob" init-method="init" lazy-init="false" />
前台展示:
这边可以增删改查定时任务,有个抽象的计划表,只有处于计划表的任务才是真正被执行的任务,所以有对计划表的加入/暂停/移除;
这里的cron规则我们的前端妹子扒不下来,于是干脆通过规则自己改+拼接,于是成了这样:
感觉还是可以的.......比那个怪怪的界面比较容易理解.
日志点击可查询执行结果:
前台代码就不贴了,太多了...CSS/JS啥的.
基本到这里就结束了,好了,告辞!