SpringMVC集成Quartz2.3.2
集成Quartz持久化
Quartz是一个完全由java编写的开源作业调度框架。本文将简单记录一下SpringMVC+Mybatis+boostrap集成Quartz2.3.2的步骤。
下载jar导入jar包
下载quartz-2.3.2.jar和quartz-jobs-2.3.2.jar链接: link.
配置properties
# 固定前缀org.quartz
# 主要分为scheduler、threadPool、jobStore、plugin等部分
#
## 调度器名称,默认名称 [WanCC 2021/2/2 09:01]
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
# 实例化ThreadPool时,使用的线程类为SimpleThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# threadCount和threadPriority将以setter的形式注入ThreadPool实例
## 并发个数,最小为1 [WanCC 2021/2/2 09:02]
org.quartz.threadPool.threadCount = 5
## 优先级 [WanCC 2021/2/2 09:02]
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 5000
# 默认存储在内存中
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
## 持久化存储,和内存存储只能启用一个 [WanCC 2021/2/2 09:03]
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
## 数据表前缀,改这个你能自定义一套自己的数据表 [WanCC 2021/2/2 09:02]
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = qzDS
## 假如已经在bean里声明了数据源,以下四句可以直接注释掉,二选一配置数据源 [WanCC 2021/2/2 09:04]
#org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
#org.quartz.dataSource.qzDS.URL = jdbc:mysql://localhost:3306/quartzDB?useUnicode=true&characterEncoding=UTF-8
#org.quartz.dataSource.qzDS.user = root
#org.quartz.dataSource.qzDS.password = 123456
#org.quartz.dataSource.qzDS.maxConnections = 10
配置xml数据源
<!-- 定时任务配置 start -->
<bean id="customJobFactory" class="net.suresec.platform.sysBasic.controller.quartz.job.CustomJobFactory"></bean>
<bean id="schedulerBean" name="schedulerBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!--可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -->
<property name="overwriteExistingJobs" value="true" />
<!--必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 -->
<property name="startupDelay" value="10" />
<!-- 让任务在程序启动时加载 -->
<property name="autoStartup" value="true" />
<property name="jobFactory" ref="customJobFactory"></property>
<property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
<property name="configLocation" value="classpath:resources/quartz.properties" />
</bean>
<!-- 定时任务配置 end -->
导入数据表
Quartz自带的表
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS
(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_SIMPLE_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CRON_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(200) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_BLOB_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CALENDARS
(
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_FIRED_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
CREATE TABLE QRTZ_SCHEDULER_STATE
(
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
CREATE TABLE QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
commit;
本人新增的业务表
CREATE TABLE `qrtz_suresec_job` (
`id` VARCHAR(32) NOT NULL primary key COMMENT '编号',
`job_name` varchar(500) COMMENT '任务名',
`job_group` varchar(500) COMMENT '任务组名称',
`job_desc` varchar(1000) COMMENT 'job描述',
`cron` varchar(500)COMMENT 'cron表达式',
`status` int(1) COMMENT '状态'
) COMMENT='quartz任务表' ENGINE=InnoDB DEFAULT CHARSET=utf8;
xml配置中用到的工厂类
此类解决Job中无法注入Service的问题
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
/**
* @author Wan CC
* @create 2021-02-04 14:46
* @Description: 解决Spring quartz Job不能依赖注入问题
*/
public class CustomJobFactory extends SpringBeanJobFactory
{
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
自定义Job
public interface BaseJob extends Job
{
}
public class NewJob implements BaseJob
{
private static Logger _log = Logger.getLogger(NewJob.class);
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException
{
_log.info("New Job执行时间: " + HelpUtils.getStrCurrentTime());
}
}
Controller层
/**
* @author Wan CC
* @create 2021-02-02 09:16
* @Description: Quartz任务管理
*/
@Controller
@RequestMapping("/quartzJobController")
public class QuartzJobController
{
private Logger logger = Logger.getLogger(this.getClass().getName());
@Autowired
private QuartzJobService quartzJobService;
/*
* @Author WanCC
* @Date 2021/2/2 10:05
* @Description 添加任务
*/
@ResponseBody
@RequestMapping(value = "/addjob")
public ErrorInfoDataVo addjob(QrtzSuresecJob vo,HttpServletRequest request) throws Exception
{
ErrorInfoDataVo result = new ErrorInfoDataVo();
// 校验输入的jobGroup和jobClassName是否已经存在定时任务了 [WanCC 2021/2/2 16:26]
result = quartzJobService.checkGroupAndClassName(vo);
if(result.getErrorCode()!=PubConfigValue.RETURN_CODE_SUCCESS){
return result;
}
try{
if(HelpUtil.isEmpty(vo.getId())){
//插入信息
ErrorInfoVo errorInfoVo = quartzJobService.addJob(vo.getJobClassName(), vo.getJobGroup(), vo.getCron());
if(errorInfoVo.getErrorCode()==PubConfigValue.RETURN_CODE_SUCCESS){
result=quartzJobService.insertSelective(vo);
result.setData(vo.getId());
}else{
result.setErrorCode(errorInfoVo.getErrorCode());
result.setMessage(errorInfoVo.getMessage());
}
}else{
//修改信息
ErrorInfoVo errorInfoVo = quartzJobService.jobreschedule(vo.getJobClassName(), vo.getJobGroup(), vo.getCron());
if(errorInfoVo.getErrorCode()==PubConfigValue.RETURN_CODE_SUCCESS){
result=quartzJobService.updateInfo(vo);
result.setData(vo.getId());
}else{
result.setErrorCode(errorInfoVo.getErrorCode());
result.setMessage(errorInfoVo.getMessage());
}
}
}catch(Exception e){
result.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
result.setMessage("系统出现错误,请联系管理员");
logger.error("Failed to invoke addjob method", e);
}finally{
return result;
}
}
/*
* @Author WanCC
* @Date 2021/2/2 10:07
* @Description 删除任务
*/
@ResponseBody
@RequestMapping(value = "/deletejob")
public ErrorInfoVo deletejob(HttpServletRequest request) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
String id = request.getParameter("id");
QrtzSuresecJob vo = quartzJobService.selectByPrimaryKey(id);
try{
errorInfoVo = quartzJobService.jobdelete(vo.getJobClassName(), vo.getJobGroup());
if(errorInfoVo.getErrorCode()==PubConfigValue.RETURN_CODE_SUCCESS){
vo.setStatus(PubConfigValue.JOB_STATUS_DELETE);
errorInfoVo=quartzJobService.updateJobStatus(vo);
}else{
errorInfoVo.setErrorCode(errorInfoVo.getErrorCode());
errorInfoVo.setMessage(errorInfoVo.getMessage());
}
}catch(Exception e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("系统出现错误,请联系管理员");
logger.error("Failed to invoke deletejob method", e);
}finally{
return errorInfoVo;
}
}
/*
* @Author WanCC
* @Date 2021/2/2 10:06
* @Description 暂停任务
*/
@ResponseBody
@RequestMapping(value = "/pausejob")
public ErrorInfoVo pausejob(HttpServletRequest request) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
String id = request.getParameter("id");
QrtzSuresecJob vo = quartzJobService.selectByPrimaryKey(id);
try{
errorInfoVo = quartzJobService.jobPause(vo.getJobClassName(), vo.getJobGroup());
if(errorInfoVo.getErrorCode()==PubConfigValue.RETURN_CODE_SUCCESS){
vo.setStatus(PubConfigValue.JOB_STATUS_PAUSE);
errorInfoVo=quartzJobService.updateJobStatus(vo);
}else{
errorInfoVo.setErrorCode(errorInfoVo.getErrorCode());
errorInfoVo.setMessage(errorInfoVo.getMessage());
}
}catch(Exception e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("系统出现错误,请联系管理员");
logger.error("Failed to invoke pausejob method", e);
}finally{
return errorInfoVo;
}
}
/*
* @Author WanCC
* @Date 2021/2/2 10:06
* @Description 恢复任务
*/
@ResponseBody
@RequestMapping(value = "/resumejob")
public ErrorInfoVo resumejob(HttpServletRequest request) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
String id = request.getParameter("id");
QrtzSuresecJob vo = quartzJobService.selectByPrimaryKey(id);
try{
errorInfoVo = quartzJobService.jobresume(vo.getJobClassName(), vo.getJobGroup());
if(errorInfoVo.getErrorCode()==PubConfigValue.RETURN_CODE_SUCCESS){
vo.setStatus(PubConfigValue.JOB_STATUS_RUN);
errorInfoVo=quartzJobService.updateJobStatus(vo);
}else{
errorInfoVo.setErrorCode(errorInfoVo.getErrorCode());
errorInfoVo.setMessage(errorInfoVo.getMessage());
}
}catch(Exception e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("系统出现错误,请联系管理员");
logger.error("Failed to invoke resumejob method", e);
}finally{
return errorInfoVo;
}
}
}
Service层
/**
* @author Wan CC
* @create 2021-02-02 09:51
* @Description:
*/
@Service
public class QuartzJobService
{
private Logger logger = Logger.getLogger(this.getClass().getName());
@Autowired
private QrtzSuresecJobDao qrtzSuresecJobDao;
@Autowired
private Scheduler schedulerBean;
以下为Quartz的接口,尽量不要动 [WanCC 2021/2/2 11:26]
/*
* @Author WanCC
* @Date 2021/2/2 10:05
* @Description 添加任务
*/
public ErrorInfoVo addJob(String jobClassName, String jobGroupName, String cronExpression) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
// 启动调度器
schedulerBean.start();
//构建job信息
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName, jobGroupName).build();
//表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withSchedule(scheduleBuilder).build();
try{
schedulerBean.scheduleJob(jobDetail, trigger);
}catch(SchedulerException e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("创建定时任务失败");
e.printStackTrace();
}
logger.info("创建定时任务结果:"+errorInfoVo.toString());
return errorInfoVo;
}
/*
* @Author WanCC
* @Date 2021/2/2 10:08
* @Description 更新任务
*/
public ErrorInfoVo jobreschedule(String jobClassName, String jobGroupName, String cronExpression) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
try{
TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) schedulerBean.getTrigger(triggerKey);
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
schedulerBean.rescheduleJob(triggerKey, trigger);
}catch(SchedulerException e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("更新定时任务失败");
e.printStackTrace();
}
logger.info("更新定时任务结果:"+errorInfoVo.toString());
return errorInfoVo;
}
/*
* @Author WanCC
* @Date 2021/2/2 10:07
* @Description 删除任务--删除操作前应该暂停该任务的触发器,并且停止该任务的执行
*/
public ErrorInfoVo jobdelete(String jobClassName, String jobGroupName) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
try{
schedulerBean.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName));
schedulerBean.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName));
schedulerBean.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
}catch(Exception e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("删除定时任务失败");
e.printStackTrace();
}
logger.info("删除定时任务结果:"+errorInfoVo.toString());
return errorInfoVo;
}
/*
* @Author WanCC
* @Date 2021/2/2 10:06
* @Description 暂停任务
*/
public ErrorInfoVo jobPause(String jobClassName, String jobGroupName) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
try{
schedulerBean.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));
}catch(Exception e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("暂停定时任务失败");
e.printStackTrace();
}
logger.info("暂停定时任务结果:"+errorInfoVo.toString());
return errorInfoVo;
}
/*
* @Author WanCC
* @Date 2021/2/2 10:06
* @Description 恢复任务
*/
public ErrorInfoVo jobresume(String jobClassName, String jobGroupName) throws Exception
{
ErrorInfoVo errorInfoVo = new ErrorInfoVo();
try{
schedulerBean.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));
}catch(Exception e){
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
errorInfoVo.setMessage("恢复定时任务失败");
e.printStackTrace();
}
logger.info("恢复定时任务结果:"+errorInfoVo.toString());
return errorInfoVo;
}
public static BaseJob getClass(String classname) throws Exception
{
Class<?> class1 = Class.forName(classname);
return (BaseJob) class1.newInstance();
}
/*
* @Author WanCC
* @Date 2021/2/2 16:44
* @Description 校验输入的jobGroup和jobClassName是否已经存在定时任务了
*/
public ErrorInfoDataVo checkGroupAndClassName(QrtzSuresecJob vo)
{
ErrorInfoDataVo errorInfoVo = new ErrorInfoDataVo();
Map<String,Object> map = new HashMap<>();
map.put("jobGroup", vo.getJobGroup());
map.put("jobClassName", vo.getJobClassName());
map.put("id", vo.getId());
map.put("status", PubConfigValue.JOB_STATUS_DELETE);
List<QrtzSuresecJob> list = qrtzSuresecJobDao.checkGroupAndClassName(map);
if(list!=null && list.size()>0){
errorInfoVo.setMessage("该任务已注册");
errorInfoVo.setErrorCode(PubConfigValue.RETURN_CODE_ERROR);
}
logger.info("校验结果:"+errorInfoVo.toString());
return errorInfoVo;
}
jsp
<form class="form-horizontal" id="form1">
<div class="form-group">
<label for="jobName" class="col-xs-2 control-label">任务名称</label>
<div class="col-xs-6">
<input type="text" class="form-control" id="jobName" name="jobName"
value="${vo.jobName}" placeholder="任务名称">
</div>
</div>
<div class="form-group">
<label for="jobClassName" class="col-xs-2 control-label">任务类名</label>
<div class="col-xs-6">
<input type="text" class="form-control" id="jobClassName" name="jobClassName"
value="${vo.jobClassName}" placeholder="任务类名">
</div>
</div>
<div class="form-group">
<label for="jobGroup" class="col-xs-2 control-label">任务所在组</label>
<div class="col-xs-6">
<input type="text" class="form-control" id="jobGroup" name="jobGroup"
value="${vo.jobGroup}" placeholder="任务所在组">
</div>
</div>
<div class="form-group">
<label for="cron" class="col-xs-2 control-label">cron表达式</label>
<div class="col-xs-6">
<input type="text" class="form-control" id="cron" name="cron"
value="${vo.cron}" placeholder="cron表达式">
</div>
</div>
<div class="form-group">
<label for="cron" class="col-xs-2 control-label">cron生成器</label>
<div class="col-xs-6">
https://www.bejson.com/othertools/cron/
</div>
</div>
<div class="form-group">
<label for="jobDesc" class="col-xs-2 control-label">描述</label>
<div class="col-xs-6">
<input type="text" class="form-control" id="jobDesc" name="jobDesc"
value="${vo.jobDesc}" placeholder="描述">
</div>
</div>
<div class="col-xs-12">
<div class="box-footer text-right">
<button type="button" class="btn btn-default" onclick="model_close()">
<i class="fa fa-reply"> 取消</i>
</button>
<button type="button" id="save_btn" class="btn btn-primary" onclick="model_save()">
<i class="fa fa-save"> 保存</i>
</button>
</div>
</div>
<!-- 隐藏表单 -->
<input type="hidden" name="id" id="id" value="${vo.id}">
</form>
页面效果图
参考
感谢以下。