Quartz+JAVA+Servlet实现任务调度系统(简洁)

前言

该系统使用场景:

在12306上买了一张火车票,30分钟内需要支付(需要添加一个倒计时),30分钟还没有支付就请求取消订单的接口(自动根据url请求),如果支付了收到了支付的回调通知后,就删除计时器上的该任务

1.项目结构图

2.引入所需要依赖的jar包

<dependency>    <groupId>org.quartz-scheduler</groupId>    <artifactId>quartz</artifactId>    <version>2.2.2</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-core</artifactId>    <version>2.5.3</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-databind</artifactId>    <version>2.5.3</version></dependency>

<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils --><dependency>    <groupId>commons-beanutils</groupId>    <artifactId>commons-beanutils</artifactId>    <version>1.9.2</version></dependency><!-- https://mvnrepository.com/artifact/commons-collections/commons-collections --><dependency>    <groupId>commons-collections</groupId>    <artifactId>commons-collections</artifactId>    <version>3.2.2</version></dependency><!-- https://mvnrepository.com/artifact/commons-lang/commons-lang --><dependency>    <groupId>commons-lang</groupId>    <artifactId>commons-lang</artifactId>    <version>2.6</version></dependency><!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --><dependency>    <groupId>commons-logging</groupId>    <artifactId>commons-logging</artifactId>    <version>1.2</version></dependency><!-- https://mvnrepository.com/artifact/net.sf.ezmorph/ezmorph --><dependency>    <groupId>net.sf.ezmorph</groupId>    <artifactId>ezmorph</artifactId>    <version>1.0.6</version></dependency><!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib --><dependency>    <groupId>net.sf.json-lib</groupId>    <artifactId>json-lib</artifactId>    <version>2.4</version>    <classifier>jdk15</classifier></dependency>

3.编写以下类:

  3.1Config.java

    

public class Config {    public static String token="liujun";    private Config() {        super();    }}

  3.2  JobGroupInfo.java

    

public class JobGroupInfo {    private String jobName;//任务名字    private String jobGroupName;//组名字    private Long nextFireTime;//下次执行时间

    public String getJobName() {        return jobName;    }

    public void setJobName(String jobName) {        this.jobName = jobName;    }

    public String getJobGroupName() {        return jobGroupName;    }

    public void setJobGroupName(String jobGroupName) {        this.jobGroupName = jobGroupName;    }

    public Long getNextFireTime() {        return nextFireTime;    }

    public void setNextFireTime(Long nextFireTime) {        this.nextFireTime = nextFireTime;    }    public JobGroupInfo() {        super();    }    public JobGroupInfo(String jobName, String jobGroupName, Long nextFireTime) {        super();        this.jobName = jobName;        this.jobGroupName = jobGroupName;        this.nextFireTime = nextFireTime;    }}

  3.3  TaskInfo.java

    

public class TaskInfo {    private String backUrl;//任务回调地址    private String jobName;//任务名字    private Integer seconds;//计时时间    private Object context;//其他内容    private Integer errormaxcount;//失败请求的次数    private String jobGorupName;//任务组名字

    public String getBackUrl() {        return backUrl;    }

    public void setBackUrl(String backUrl) {        this.backUrl = backUrl;    }

    public String getJobName() {        return jobName;    }

    public void setJobName(String jobName) {        this.jobName = jobName;    }

    public Integer getSeconds() {        return seconds;    }

    public void setSeconds(Integer seconds) {        this.seconds = seconds;    }

    public Object getContext() {        return context;    }

    public void setContext(Object context) {        this.context = context;    }

    public Integer getErrormaxcount() {        return errormaxcount;    }

    public void setErrormaxcount(Integer errormaxcount) {        this.errormaxcount = errormaxcount;    }

    public String getJobGorupName() {        return jobGorupName;    }

    public void setJobGorupName(String jobGorupName) {        this.jobGorupName = jobGorupName;    }    public TaskInfo() {        super();    }    public TaskInfo(String backUrl, String jobName, Integer seconds,                    Object context, Integer errormaxcount, String jobGorupName) {        super();        this.backUrl = backUrl;        this.jobName = jobName;        this.seconds = seconds;        this.context = context;        this.errormaxcount = errormaxcount;        this.jobGorupName = jobGorupName;    }    @Override    public String toString() {        return "TaskInfo [backUrl=" + backUrl + ", jobName=" + jobName                + ", seconds=" + seconds + ", context=" + context                + ", errormaxcount=" + errormaxcount + ", jobGorupName="                + jobGorupName + "]";    }}

  3.4 JobBack.java

    

public class JobBack implements Job{    //回调执行方法    public void execute(JobExecutionContext context) throws JobExecutionException {        //得到添加任务中的参数        TaskInfo task = (TaskInfo) context.getMergedJobDataMap().get("task");        sendBack(task);    }

    private void sendBack(TaskInfo task) {        task.setErrormaxcount(task.getErrormaxcount() - 1);        // 得到参数请求回调        try {            //拼装请求地址以及参数            String uri = "jobName=" + task.getJobName() + "&context=" + task.getContext() + "&jobGorupName="                    + task.getJobGorupName() + "&paramkey=" + Md5Util.GetMD5Code(Config.token);            //请求并得到返回值            String res = HttpUtil.request_post(task.getBackUrl(), uri);            //如果返回值不是“SUCCESS” 就等待10S进行重复请求(此处避免请求失败就结束请求,参数中传递了一个失败请求次数)            if (!res.trim().equals("SUCCESS")) {                //如果请求错误次数还大于0                if (task.getErrormaxcount() >= 1) {                    Thread.sleep(10000);                    sendBack(task);                }            }        } catch (Exception e) {            System.out.println(e.getMessage());            if (task.getErrormaxcount() >= 1) {                try {                    Thread.sleep(10000);                } catch (InterruptedException e1) {                    e1.printStackTrace();                }                sendBack(task);            }        }    }}

  3.5 JobManger.java

    

public class JobManger {    private final static String TRIGGER_GROUP_NAME = "QUARTZ_TRIGGERGROUP";//触发器组    private final static SchedulerFactory sf = new StdSchedulerFactory();    /**     * 添加任务     * @param jobName 任务名称     * @param job 任务处理类 需要继承Job     * @param context 处理任务可以获取的上下文 通过context.getMergedJobDataMap().getString("context"); 获取     * @param seconds 间隔秒     * @return     */    public static int addJob(String jobName, Class<? extends Job> job, Object task, int seconds, String jobGorupName){        try {            //判断任务是否存在            Scheduler sche = sf.getScheduler();            JobKey jobKey = JobKey.jobKey(jobName,jobGorupName);            if(sche.checkExists(jobKey)){                return 1;//任务已经存在            }            //创建一个JobDetail实例,指定SimpleJob            Map<String, Object> JobDetailmap =new HashMap<String, Object>();            JobDetailmap.put("name", jobName);//设置任务名字            JobDetailmap.put("group", jobGorupName);//设置任务组            JobDetailmap.put("jobClass",job.getCanonicalName());//指定执行类  Task.class.getCanonicalName()            JobDetail jobDetail= JobDetailSupport.newJobDetail(JobDetailmap);            //添加数据内容            jobDetail.getJobDataMap().put("task",task);//传输的上下文            //通过SimpleTrigger定义调度规则:马上启动,每2秒运行一次,共运行100次  等。。。。            SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();            simpleTrigger.setName(jobName);            simpleTrigger.setGroup(TRIGGER_GROUP_NAME);            //什么时候开始执行            simpleTrigger.setStartTime(new Date(new Date().getTime()+1000*seconds));            //间隔时间            simpleTrigger.setRepeatInterval(1000*seconds);            //最多访问次数  默认执行一次            simpleTrigger.setRepeatCount(0);            //通过SchedulerFactory获取一个调度器实例            SchedulerFactory schedulerFactory = new StdSchedulerFactory();            Scheduler scheduler = schedulerFactory.getScheduler();            scheduler.scheduleJob(jobDetail, simpleTrigger);//④ 注册并进行调度            scheduler.start();//⑤调度启动            return 0;//添加成功        } catch (Exception e) {            return 2;//操作异常        }    }    /**     * 关闭任务调度     * @param jobName 任务名称     * @return 0 关闭成功 1: 关闭失败 2:操作异常     */    public static int closeJob(String jobName,String jobGorupName){        //关闭任务调度        try {            Scheduler sche = sf.getScheduler();            JobKey jobKey = JobKey.jobKey(jobName,jobGorupName);            return sche.deleteJob(jobKey)==true?0:1;        } catch (SchedulerException e) {            return 2;        }    }    private JobManger() {}}

  3.6 AddJob.java

    

@WebServlet("/addJob.do")public class AddJob extends HttpServlet{    private static final long serialVersionUID = 1L;

    public AddJob() {        super();    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //避免get 请求        response.sendError(403);        // doPost(request, response);    }

    /**     * 处理添加任务     */    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 设置编码        request.setCharacterEncoding("utf-8");        response.setCharacterEncoding("utf-8");        response.setContentType("utf-8");        // 得到请求        String jobName = request.getParameter("jobName");// 得到任务名称        // 得到token        //String token = request.getParameter("token");        // 验证签名        /*if (!MD5Util.GetMD5Code(jobName + Config.token + "zhangke is shabi!").equals(token)) {            return;        }*/        // 得到回调        String backUrl = request.getParameter("backUrl");        // 得到请求定时时间        Integer seconds = Integer.valueOf(request.getParameter("seconds"));        String errMaxCount = request.getParameter("errormaxcount");        Integer errormaxcount = errMaxCount == null ? 1 : Integer.valueOf(errMaxCount);// 回调请求失败的次数        // 默认为一次        // 得到其他参数        String context = request.getParameter("context");        // 得到任务组        String jobGorupName = request.getParameter("jobGorupName");

        TaskInfo t = new TaskInfo(backUrl, jobName, seconds, context, errormaxcount, jobGorupName);        // 添加任务        Integer res = JobManger.addJob(jobName, JobBack.class, t, seconds, jobGorupName);        response.getWriter().write(res.toString());    }}

  3.7 MonitoringJob.java

    

@WebServlet("/monitoringJob.do")public class MonitoringJob extends HttpServlet {    private static final long serialVersionUID = 1L;

    /**     * @see HttpServlet#HttpServlet()     */    public MonitoringJob() {        super();    }    protected void doGet(HttpServletRequest request,                         HttpServletResponse response) throws ServletException, IOException {        doPost(request, response);    }

    protected void doPost(HttpServletRequest request,                          HttpServletResponse response) throws ServletException, IOException {        request.setCharacterEncoding("utf-8");        response.setCharacterEncoding("utf-8");        response.setContentType("text/json;char=utf-8");        // 得到任务组名字        String jobGroupName = request.getParameter("jobGroupName");        // 验证是否为空        //monitoringJob.do        List<JobGroupInfo> list=new ArrayList<JobGroupInfo>();        try {            Scheduler scheduler = new StdSchedulerFactory().getScheduler();            for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(jobGroupName==null?"":jobGroupName))) {                String jobName = jobKey.getName();                String jobGroup = jobKey.getGroup();                // get job‘s trigger                List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);                Date nextFireTime = triggers.get(0).getNextFireTime(); // 下一次执行时间、                JobGroupInfo gri=new JobGroupInfo(jobName, jobGroup, nextFireTime.getTime());                list.add(gri);            }            response.getWriter().write(JSONArray.fromObject(list).toString());        } catch (SchedulerException e) {            e.printStackTrace();        }    }}

  3.8 RemoveJob.java

    

@WebServlet("/removeJob.do")public class RemoveJob extends HttpServlet {    private static final long serialVersionUID = 1L;

    public RemoveJob() {        super();    }    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        response.sendError(403);    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //得到任务名        String jobName=request.getParameter("jobName");        //得到签名        String token =request.getParameter("token");        //得到任务组        String jobGorupName=request.getParameter("jobGorupName");        //验证签名        /*if(!MD5Util.GetMD5Code(jobName+Config.token+"zhangke is sb!").equals(token)){            response.getWriter().write("2");            return;        }*/        //执行移除操作        int res= JobManger.closeJob(jobName,jobGorupName);        if(res==0){//成功            response.getWriter().write("0");        }else if(res==1){//不存在            response.getWriter().write("1");        }else{            //报错啦!            response.getWriter().write("2");        }    }}

  3.9 TestBack.java

    

@WebServlet("/testback")public class TestBack extends HttpServlet {    private static final long serialVersionUID = 1L;

    public TestBack() {        super();    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        System.out.println("get请求");    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        request.setCharacterEncoding("utf-8");        Map<String, String[]> map=request.getParameterMap();        Iterator<String> iter = map.keySet().iterator();        while (iter.hasNext()) {            String key=iter.next();            System.out.println("key:"+key+" value:"+map.get(key)[0]);        }        response.getWriter().write("SUCCESS");    }}

  3.10 HttpUtil.java

    

public class HttpUtil {    public static String request_get(String httpUrl) {        BufferedReader reader = null;        String result = null;        StringBuffer sbf = new StringBuffer();

        try {            URL url = new URL(httpUrl);            HttpURLConnection connection = (HttpURLConnection) url                    .openConnection();            connection.setRequestMethod("GET");            connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

            connection.setDoOutput(true);            connection.setDoInput(true);            connection.setConnectTimeout(5000);            connection.setReadTimeout(20000);            connection.connect();            InputStream is = connection.getInputStream();            reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));            String strRead = null;            while ((strRead = reader.readLine()) != null) {                sbf.append(strRead);                sbf.append("\r\n");            }            reader.close();            result = sbf.toString();        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    public static String request_post(String httpUrl, String httpArg) {        BufferedReader reader = null;        String result = null;        StringBuffer sbf = new StringBuffer();

        try {            URL url = new URL(httpUrl);            HttpURLConnection connection = (HttpURLConnection) url                    .openConnection();            connection.setRequestMethod("POST");            connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

            connection.setDoOutput(true);            connection.setDoInput(true);            connection.setConnectTimeout(5000);            connection.setReadTimeout(20000);            connection.getOutputStream().write(httpArg.getBytes("UTF-8"));            connection.connect();            InputStream is = connection.getInputStream();            reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));            String strRead = null;            while ((strRead = reader.readLine()) != null) {                sbf.append(strRead);                sbf.append("\r\n");            }            reader.close();            result = sbf.toString();        } catch (Exception e) {            e.printStackTrace();        }        return result;    }}

  3.11 Md5Util.java

public class Md5Util {    private final static String[] strDigits = { "0", "1", "2", "3", "4", "5",            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    public Md5Util() {    }

    private static String byteToArrayString(byte bByte) {        int iRet = bByte;        if (iRet < 0) {            iRet += 256;        }        int iD1 = iRet / 16;        int iD2 = iRet % 16;        return strDigits[iD1] + strDigits[iD2];    }

    private static String byteToNum(byte bByte) {        int iRet = bByte;        System.out.println("iRet1=" + iRet);        if (iRet < 0) {            iRet += 256;        }        return String.valueOf(iRet);    }

    private static String byteToString(byte[] bByte) {        StringBuffer sBuffer = new StringBuffer();        for (int i = 0; i < bByte.length; i++) {            sBuffer.append(byteToArrayString(bByte[i]));        }        return sBuffer.toString();    }

    public static String GetMD5Code(String strObj) {        String resultString = null;        try {            resultString = new String(strObj);            MessageDigest md = MessageDigest.getInstance("MD5");            resultString = byteToString(md.digest(strObj.getBytes()));        } catch (NoSuchAlgorithmException ex) {            ex.printStackTrace();        }        return resultString;    }}

4.启动maven https://blog.csdn.net/nandao158/article/details/809021935.测试  postman

5秒后看控制台



原文地址:https://www.cnblogs.com/liujun-dqw/p/10758163.html

时间: 2024-11-10 20:26:04

Quartz+JAVA+Servlet实现任务调度系统(简洁)的相关文章

Java+Servlet投票系统

原文:Java+Servlet投票系统 源代码下载地址:http://www.zuidaima.com/share/1550463722228736.htm 简单的投票系统 采用技术 1. Java 2. Servlet 3. MySQL 4. JQuery 经确认,该分享的db文件缺少table,我联系作者提供吧,大家注意. 另外确认jar包 http://www.zuidaima.com/jar/search/servlet-api-2.4.htm

clover分布式任务调度系统

1.clover分布式调度介绍 clover分布式任务调度是完全使用Java技术自主开发 特点如下: 1.防单点故障 2.job可部署多台,但任务调度时,只有一台参执行.如果一台下线, clover选择其他已在zookeeper注册job来执行. 3.可管理监控程序 ,相关负责人的job不可用会发送邮件通知 4.提供管理后台,可手动停止任务,设置任务执行频率.恢复策 略.人工干预指定哪些job来工作,可查看任务执行进度.任务执行失败时会收到报警并记录日志. 5.执行中的任务,但未执行完成,不会再

java 进销存系统 库存管理 销售报表 商户管理 springmvc SSM项目

统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3  SSM 普通java web(非maven, 附赠pom.xml文件)  数据库:mysql 3.开发工具:myeclipse  eclipse idea 均可, 没有限制. 我这边myeclipse 2014 导出来的项目源码 ----------------------------------------

java 进销存系统 库存管理 商户管理 springmvc SSM 销售报表 项目

统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3  SSM 普通java web(非maven, 附赠pom.xml文件)  数据库:mysql 3.开发工具:myeclipse  eclipse idea 均可, 没有限制. 我这边myeclipse 2014 导出来的项目源码 ----------------------------------------

java 进销存系统 crm 库存管理 销售报表 商户管理 springmvc SSM项目

统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3  SSM 普通java web(非maven, 附赠pom.xml文件)  数据库:mysql 3.开发工具:myeclipse  eclipse idea 均可, 没有限制. 我这边myeclipse 2014 导出来的项目源码 ----------------------------------------

如何构建延迟任务调度系统

一.需求目标 1.需求描述之前笔者接触过一些营销业务场景,比如说: 用户注册未登录过APP第二天早上10点发一条营销短信促活红包过期前两天短信通知,下午16:00发送等等定时任务处理业务.采用的技术方案是定时任务扫数据汇总表,分页读取一定数量然后处理然而随着业务的发展,业务多元化,遇到了以下场景: 拼团砍价活动过期前半小时提醒订单提交半小时内没有完成支付,订单自动取消,库存退还用户几天内没有操作过系统,发放激活短信以上场景处理时间不是固定的某个点,而是业务发生的时间推迟一段时间,针对以上的业务场

linux 任务调度 系统任务调度

linux  at 针对运行一次的任务 crontab   控制计划任务的命令 crond系统服务 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程, 与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具, 并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务, 如果有要执行的任务,则自动执行该任务. 系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘.日志清理等.在/etc目录下有一个crontab文件

OSGI(面向Java的动态模型系统)

基本简介编辑 OSGI服务平台提供在多种网络设备上无需重启的动态改变构造的功能.为了最小化耦合度和促使这些耦合度可管理,OSGi技术提供一种面向服务的架构,它能使这些组件动态地发现对方.OSGi联 OSGI 盟已经开发了为例如象HTTP服务器.配置.日志.安全.用户管理.XML等很多公共功能标准组件接口.这些组件的兼容性插件实现可以从进行了不同优化和使用代价的不同计算机服务提供商得到.然而,服务接口能够基于专有权基础上开发. 因为OSGi技术为集成提供了预建立和预测试的组件子系统,所以OSGi技

Java Servlet API中文说明文档

Java Servlet API中文说明文档译者前言:       近来在整理有关Servlet资料时发现,在网上竟然找不到一份中文的Java Servlet API的说明文档,而在有一本有关JSP的书后面附的Java Servlet API说明竟然不全,而这份文档的2.1a版在1998年的11月份就已定稿.所以我决定翻译一份中文的文档(其中一些与技术关系不大的部分已被略去),有兴趣的读者可以从http: //java.sun.com/products/servlet/2.1/servletsp