概述
一、准备工作
1.java环境搭建,具体参考包中的webapp/resources/doc/平台开发环境安装Guide_V1.0.docx文档
2.使用源码中的webapp/resources/doc/init.sql初始化表结构及数据
t_timetask 任务表
t_timetask_log 任务运行日志
3.数据库连接配置在cloud_parent中的pom.xml中,数据库名称ffxl_cloud,默认账号root,密码123456,同样可在pom.xml中修改
4.运行quartz项目,此处注意,使用的端口号需要与platform_parent下pom.xml中的quartz.job.url的一致,程序中用的是8080端口,具体使用哪个配置,请参考maven中profiles的使用
5.运行admin项目,注意,此处端口要与quartz不同,程序中用的是80端口,浏览器中输入http://localhost/admin 运行结果如图:
二、代码引入
1、文件引入顺序:lib_parent → platform_parent → cloud_parent
2、代码结构
三、程序实现
quartz项目部分代码
1.quartz项目启动时,初始化数据库中的定时任务
package com.ffxl.quartz.init;
import java.util.ArrayList;
import java.util.List;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import com.ffxl.cloud.model.STimetask;
import com.ffxl.cloud.model.STimetaskExample;
import com.ffxl.cloud.model.base.BaseSTimetaskExample.Criteria;
import com.ffxl.cloud.model.warpper.ScheduleJob;
import com.ffxl.cloud.service.STimetaskService;
import com.ffxl.quartz.task.util.QuartzJobFactory;
import com.ffxl.quartz.task.util.QuartzJobFactoryDisallowConcurrentExecution;
/**
* 根据上下文获取spring类
*
* @author
*/
public class InitQuartzJob implements ApplicationContextAware{
private static final Logger logger = LoggerFactory.getLogger(InitQuartzJob.class);
private static ApplicationContext appCtx;
public static SchedulerFactoryBean schedulerFactoryBean = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (this.appCtx == null) {
this.appCtx = applicationContext;
}
}
public static void init() {
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();
}
// 这里从数据库中获取任务信息数据
STimetaskService sTimetaskService = (STimetaskService) appCtx.getBean(STimetaskService.class);
STimetaskExample example = new STimetaskExample();
Criteria c = example.createCriteria();
c.andJobStatusEqualTo("1"); // 已发布的定时任务
List list = sTimetaskService.selectByExample(example);
List jobList = new ArrayList();
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.getConcurrent() ? "1" : "0"); // 运行状态
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.debug(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);
}
}
}
2.提供job对应的操作服务
package com.ffxl.quartz.task;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.ffxl.cloud.annotation.ControllerLogAnnotation;
import com.ffxl.cloud.model.STimetask;
import com.ffxl.cloud.model.warpper.ScheduleJob;
import com.ffxl.platform.util.JsonResult;
import com.ffxl.platform.util.StringUtil;
import com.ffxl.quartz.init.InitQuartzJob;
@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
@ControllerLogAnnotation(description = "获取所有计划中的任务列表")
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();
}
}
}
3.编写 定时清除timeTaskLog 7天之前的记录
@Component
public class TimeTaskLogDispatchController {
private static final Logger LOGGER = Logger.getLogger(TimeTaskLogDispatchController.class);
/**
* 定时清除timeTaskLog 7天之前的记录
*/
public void deleteTimeTaskLog(String data) {
LOGGER.info("【定时清除timeTaskLog 7天之前的记录】>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>开始执行");
STimetaskLogService bActiveService = (STimetaskLogService) ApplicationContextUtils.getBean(STimetaskLogService.class);
Date currentDate = new Date();
int day = -7;
Date deleteDate = DateUtil.getAfterNumDay(currentDate, day);
int ret = bActiveService.deleteLog(deleteDate);
if(ret >0){
LOGGER.info("【定时清除timeTaskLog 7天之前的记录】>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>执行成功");
}else{
LOGGER.info("【定时清除timeTaskLog 7天之前的记录】>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>执行失败");
}
}
}
4.dispatcher-servlet.xml中添加如下配置
admin项目部分代码1.可视化项目的controller层
package com.ffxl.admin.controller.task;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.ffxl.admin.controller.BaseController;
import com.ffxl.admin.util.DataTablesUtil;
import com.ffxl.cloud.model.STimetask;
import com.ffxl.cloud.model.warpper.ScheduleJob;
import com.ffxl.cloud.service.STimetaskService;
import com.ffxl.platform.constant.Const;
import com.ffxl.platform.core.Page;
import com.ffxl.platform.exception.BusinessException;
import com.ffxl.platform.util.CronUtil;
import com.ffxl.platform.util.DateUtil;
import com.ffxl.platform.util.HttpConnectUtil;
import com.ffxl.platform.util.JsonDateValueProcessor;
import com.ffxl.platform.util.JsonResult;
import com.ffxl.platform.util.Message;
import com.ffxl.platform.util.StringUtil;
/**
* 定时任务
* @author wison
*
*/
@Controller
@RequestMapping(value = "/task")
public class TimeTaskController extends BaseController {
private static String JOB_URL = Const.QUARTZ_JOB_URL;
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);
}
}
/**
* 验证名称是否存在
* @param id
* @param groupName
* @param name
* @return
*
*/
@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){
//获取系统操作人员
String longName = "admin";
task.setModifyUserId(longName);
try{
int ret= stimetaskService.insertOrUpdateByUser(task,longName);
if(ret > 0){
return new JsonResult("2000",task);
}else{
return new JsonResult("5000");
}
}catch(BusinessException e){
return new JsonResult("5001",e.getMessage(),null);
}
}
}
2.前端页面
可以看到在这里我把定时任务的状态分为两大类,任务状态跟业务有关,分为已发布和未发布;计划状态跟定时任务的运行有关,分为None,正常运行,已暂停,任务执行中,线程阻塞,未计划,错误
2.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.2操作逻辑
function formatOpt(value, rowData, rowIndex) {
var msg = "";
msg+="编辑";
//已发布,
if(rowData.jobStatus=='1'){
var value = rowData.planStatus;
if(value=="None"|| value==null){
msg +='
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="定时任务按照计划开始执行" >计划
';}
if(value=="NORMAL"){
msg +='
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="紧执行一次" >立即执行
'+'
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="定时任务暂时停止执行" >暂停
'+'
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="定时任务从计划列表中移除" >移除
';}
if(value=="PAUSED"){
msg +='
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="紧执行一次" >立即执行
'+'
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="定时任务按照计划开始执行" >计划
'+'
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="定时任务从计划列表中移除" >移除
';}
if(value=="COMPLETE"){
msg +='
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="紧执行一次" >立即执行
'}
if(value=="BLOCKED"){
msg +='
+'onMouseOver="popTip(this,' '+rowData+' ' )" class="btn btn-info btn-xs" data-toggle="tooltip"'
+' data-placement="top" title="紧执行一次" >立即执行
'}
if(value=="ERROR"){
}
}
return msg;
}
简单概述为:已发布的定时任务出现【计划】按钮;执行【计划】后,定时任务正常运行,且出现【立即执行】【暂停】【移除】三个按钮,【立即执行】用于测试当前定时任务的业务逻辑是否正确,【暂停】很容易理解,就是把当前任务暂停,及时到达cron定义的时间,定时任务也不会执行,【移除】仅仅是把计划列表中相应的任务暂时清除掉,你可以理解为清除缓存中的定时任务,并不是物理删除
3.定时任务详情
3.点击规则弹出页面如下,可自行修改界面,这里我是从网上随便找了个插件,然后按照自己想要的修改下源码
注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
最后
以上就是甜甜煎饼为你收集整理的java定时器quartz实例_Spring+Quartz实现动态添加定时任务的全部内容,希望文章能够帮你解决java定时器quartz实例_Spring+Quartz实现动态添加定时任务所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复