一、前言
xxl-job 是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展。本文介绍如何通过 spring boot 项目,使用 resttemplate 和 feign 的方式调用 xxl-job 后台管理接口,实现任务的全生命周期管理(包括添加、修改、启动、停止、删除、查询执行器、查询日志等操作)。
二、项目结构简述
主要包含三个部分:
- controller:对外提供 rest 接口;
- service:封装对 xxl-job 后台的具体调用逻辑;
- feignclient(可选):用于部分接口远程调用。
三、maven 依赖
只需引入 xxl-job-core
依赖(用于调度执行器 jobhandler 的注册等):
<!-- xxl-job 核心依赖 --> <dependency> <groupid>com.xuxueli</groupid> <artifactid>xxl-job-core</artifactid> <version>2.3.1</version> </dependency>
四、controller 代码详解
@restcontroller @requestmapping("/xxl") public class xxljobcontroller { @autowired private xxljobservice jobservice; /** * 添加任务 */ @postmapping("/add/job") public map addjob(@requestparam string user, @requestparam string pass) { string cookie = jobservice.login(user, pass); return jobservice.createjob(cookie); } /** * 修改任务 */ @postmapping("/update/job") public map updatejob(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.updatejob(cookie, jobid); } /** * 删除任务 */ @postmapping("/remove/job") public resultmodel removejob(@requestparam integer jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.removejob(cookie, jobid); } /** * 启动作业 */ @postmapping("/start/job") public map startjob(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.startjob(cookie, jobid); } /** * 停止作业 */ @postmapping("/stop/job") public map stopjob(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.stopjob(cookie, jobid); } /** * 获取执行器列表 */ @getmapping("/jobgroups") public list<map<string, object>> getjobgrouplist() { string cookie = jobservice.login("admin", "123456"); return jobservice.getjobgrouplist(cookie); } /** * 获取任务列表 */ @getmapping("/tasks") public map getjoblist() { string cookie = jobservice.login("admin", "123456"); return jobservice.getjoblist(null, cookie); } /** * 获取任务日志 */ @postmapping("/joblogs") public map getjoblogs(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.getjoblogs(cookie, jobid); } }
五、service 接口设计
public interface xxljobservice { string login(string user, string pass); map createjob(string cookie); map updatejob(string cookie, string jobid); resultmodel removejob(string cookie, integer jobid); map startjob(string cookie, string jobid); map stopjob(string cookie, string jobid); list<map<string, object>> getjobgrouplist(string cookie); map getjoblist(integer jobgroup, string cookie); map getjoblogs(string cookie, string jobid); }
六、service 实现详解
下面是部分关键实现说明。
1. 登录获取 cookie
@override public string login(string user, string pass) { response response = client.login("application/x-www-form-urlencoded", user, pass); collection<string> cookies = response.headers().get("set-cookie"); for (string cookie : cookies) { if (cookie.contains("xxl_job_login_identity")) { return cookie.split(";")[0]; } } throw new runtimeexception("登录失败"); }
- 使用 feignclient 调用登录接口,提取 cookie,用于后续请求认证。
2. 添加任务
@override public map createjob(string cookie) { resttemplate resttemplate = new resttemplate(); httpheaders headers = new httpheaders(); headers.add("cookie", cookie); multivaluemap<string, string> parammap = new linkedmultivaluemap<>(); parammap.add("jobdesc", "定时任务"); parammap.add("scheduleconf", "0 */1 * * * ?"); parammap.add("executorhandler", "checktimeout"); parammap.add("executorparam", "xxl-feign"); parammap.add("jobgroup", "1"); parammap.add("author", "admin"); parammap.add("scheduletype", "cron"); parammap.add("gluetype", "bean"); parammap.add("executorroutestrategy", "first"); parammap.add("misfirestrategy", "do_nothing"); parammap.add("executorblockstrategy", "serial_execution"); httpentity<multivaluemap<string, string>> entity = new httpentity<>(parammap, headers); responseentity<string> response = resttemplate.postforentity( "http://xxl-job-host:port/xxl-job-admin/jobinfo/add", entity, string.class); return new objectmapper().readvalue(response.getbody(), hashmap.class); }
- 替换
xxl-job-host:port
为你部署的地址; - 参数含义详见 xxl-job 后台手动添加任务页面。
3. 修改任务
@override public map updatejob(string cookie, string jobid) { // 和添加类似,带上任务 id 即可更新 }
4. 启动/停止任务
@override public map startjob(string cookie, string jobid) { // 调用接口:/jobinfo/start }
@override public map stopjob(string cookie, string jobid) { // 调用接口:/jobinfo/stop }
5. 获取执行器/任务/日志列表
/jobgroup/pagelist
:获取执行器;/jobinfo/pagelist
:获取任务列表;/joblog/pagelist
:查询任务日志。
七、统一响应模型(可选)
可以封装一个通用 resultmodel
响应类统一格式返回。
八、调用测试建议
可使用 postman 测试每个接口,注意设置:
- content-type 为
application/x-www-form-urlencoded
; - 传入正确的账号密码和参数值。
九、总结
通过本文提供的代码,你可以用 java 实现对 xxl-job 管理后台的编程式控制,实现任务的全生命周期管理,非常适合自定义调度中心或自动化平台集成。
十、 完整代码
控制器层 xxljobcontroller.java
@restcontroller @requestmapping("/xxl") public class xxljobcontroller { @autowired private xxljobservice jobservice; /** * 新增定时任务 */ @postmapping("/add/job") public map addjob(@requestparam string user, @requestparam string pass) { string cookie = jobservice.login(user, pass); return jobservice.createjob(cookie); } /** * 修改定时任务 */ @postmapping("/update/job") public map updatejob(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.updatejob(cookie, jobid); } /** * 删除定时任务 */ @postmapping("/remove/job") public resultmodel removejob(@requestparam integer jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.removejob(cookie, jobid); } /** * 启动作业 */ @postmapping("/start/job") public map startjob(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.startjob(cookie, jobid); } /** * 停止作业 */ @postmapping("/stop/job") public map stopjob(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.stopjob(cookie, jobid); } /** * 获取执行器列表 */ @getmapping("/jobgroups") public list<map<string, object>> getjobgrouplist() { string cookie = jobservice.login("admin", "123456"); return jobservice.getjobgrouplist(cookie); } /** * 获取任务列表 */ @getmapping("/tasks") public map getjoblist() { string cookie = jobservice.login("admin", "123456"); return jobservice.getjoblist(null, cookie); } /** * 查询任务日志 */ @postmapping("/joblogs") public map getjoblogs(@requestparam string jobid) { string cookie = jobservice.login("admin", "123456"); return jobservice.getjoblogs(cookie, jobid); } }
接口层:xxljobservice.java
public interface xxljobservice { /** * 登录获取 cookie */ string login(string user, string pass); /** * 创建任务 */ map createjob(string cookie); /** * 修改任务 */ map updatejob(string cookie, string jobid); /** * 删除任务 */ resultmodel removejob(string cookie, integer jobid); /** * 启动作业 */ map startjob(string cookie, string jobid); /** * 停止作业 */ map stopjob(string cookie, string jobid); /** * 查询执行器列表 */ list<map<string, object>> getjobgrouplist(string cookie); /** * 查询任务列表 */ map getjoblist(integer jobgroup, string cookie); /** * 获取任务日志 */ map getjoblogs(string cookie, string jobid); }
实现层:xxljobserviceimpl.java
@service public class xxljobserviceimpl implements xxljobservice { @autowired private xxljobfeignclient client; /** * 调用 xxl-job 登录接口,返回 cookie */ @override public string login(string user, string pass) { response response = client.login("application/x-www-form-urlencoded", user, pass); collection<string> cookies = response.headers().get("set-cookie"); if (cookies != null) { for (string cookie : cookies) { if (cookie.contains("xxl_job_login_identity")) { // 截取真正的 cookie 值 // 只取第一个部分 return cookie.split(";")[0]; } } } throw new runtimeexception("登录失败,未获取到认证 cookie"); } @override public map createjob(string cookie) { resttemplate resttemplate = new resttemplate(); // 创建请求头 httpheaders headers = new httpheaders(); headers.add("cookie", cookie); multivaluemap<string, string> parammap = new linkedmultivaluemap<>(); parammap.add("jobdesc", "定时任务"); parammap.add("scheduleconf", "0 */1 * * * ?"); parammap.add("crongen_display", "0 */1 * * * ?"); parammap.add("schedule_conf_cron", "0 */1 * * * ?"); parammap.add("executorhandler", "checktimeout"); parammap.add("executorparam", "xxl-feign"); parammap.add("jobgroup", "33"); parammap.add("author", "admin"); parammap.add("scheduletype", "cron"); parammap.add("gluetype", "bean"); parammap.add("executorroutestrategy", "first"); parammap.add("misfirestrategy", "do_nothing"); parammap.add("executorblockstrategy", "serial_execution"); parammap.add("executortimeout", "0"); parammap.add("executorfailretrycount", "0"); parammap.add("glueremark", "glue代码初始化"); // 创建 httpentity 实例,包含请求头和参数 httpentity<multivaluemap<string, string>> entity = new httpentity<>(parammap, headers); // 发送 post 请求 responseentity<string> response = resttemplate.postforentity("http://192.168.1.xxx:8080/xxl-job-admin/jobinfo/add", entity, string.class); // 解析响应为 hashmap try { return new objectmapper().readvalue(response.getbody(), hashmap.class); } catch (jsonprocessingexception e) { e.printstacktrace(); } return null; } /** * 修改任务(如修改调度频率等) */ @override public map updatejob(string cookie, string jobid) { resttemplate resttemplate = new resttemplate(); // 创建请求头 httpheaders headers = new httpheaders(); headers.add("cookie", cookie); multivaluemap<string, string> job = new linkedmultivaluemap<>(); job.add("id", jobid); job.add("jobgroup", "1"); job.add("jobdesc", "修改任务"); job.add("author", "admin"); job.add("scheduletype", "cron"); // 改为每5分钟执行 job.add("scheduleconf", "0 */5 * * * ?"); job.add("executorroutestrategy", "round"); job.add("executorhandler", "demojobhandler"); job.add("executorparam", "param-updated"); job.add("executorblockstrategy", "serial_execution"); job.add("gluetype", "bean"); job.add("misfirestrategy", "do_nothing"); // 创建 httpentity 实例,包含请求头和参数 httpentity<multivaluemap<string, string>> entity = new httpentity<>(job, headers); // 发送 post 请求 responseentity<string> response = resttemplate.postforentity("http://192.168.1.xxx:8080/xxl-job-admin/jobinfo/update", entity, string.class); // 解析响应为 hashmap try { return new objectmapper().readvalue(response.getbody(), hashmap.class); } catch (jsonprocessingexception e) { e.printstacktrace(); } return null; } /** * 删除任务 */ @override public resultmodel removejob(string cookie, integer jobid) { return client.removejob(cookie, jobid); } /** * 启动作业 */ @override public map startjob(string cookie, string jobid) { resttemplate resttemplate = new resttemplate(); // 创建请求头 httpheaders headers = new httpheaders(); headers.add("cookie", cookie); multivaluemap<string, string> parammap = new linkedmultivaluemap<>(); parammap.add("id", jobid); // 创建 httpentity 实例,包含请求头和参数 httpentity<multivaluemap<string, string>> entity = new httpentity<>(parammap, headers); // 发送 post 请求 responseentity<string> response = resttemplate.postforentity("http://192.168.1.xxx:8080/xxl-job-admin//jobinfo/start", entity, string.class); // 解析响应为 hashmap try { return new objectmapper().readvalue(response.getbody(), hashmap.class); } catch (jsonprocessingexception e) { e.printstacktrace(); } return null; } /** * 停止作业 */ @override public map stopjob(string cookie, string jobid) { resttemplate resttemplate = new resttemplate(); // 创建请求头 httpheaders headers = new httpheaders(); headers.add("cookie", cookie); multivaluemap<string, string> parammap = new linkedmultivaluemap<>(); parammap.add("id", jobid); // 创建 httpentity 实例,包含请求头和参数 httpentity<multivaluemap<string, string>> entity = new httpentity<>(parammap, headers); // 发送 post 请求 responseentity<string> response = resttemplate.postforentity("http://192.168.1.xxx:8080/xxl-job-admin//jobinfo/stop", entity, string.class); // 解析响应为 hashmap try { return new objectmapper().readvalue(response.getbody(), hashmap.class); } catch (jsonprocessingexception e) { e.printstacktrace(); } return null; } @override public list<map<string, object>> getjobgrouplist(string cookie) { // 调用 feign 客户端获取执行器列表 map<string, object> response = client.getjobgroups(cookie, 0, 100); // 从返回结果中获取执行器数据列表 return (list<map<string, object>>) response.get("data"); } @override public map getjoblist(integer jobgroup, string cookie) { resttemplate resttemplate = new resttemplate(); // 创建请求头 httpheaders headers = new httpheaders(); headers.add("cookie", cookie); multivaluemap<string, string> parameters = new linkedmultivaluemap<string, string>(); parameters.add("jobgroup", "33"); // 表示全部 parameters.add("triggerstatus","-1"); // 创建 httpentity 实例,包含请求头和参数 httpentity<multivaluemap<string, string>> entity = new httpentity<>(parameters, headers); // 发送 post 请求 responseentity<string> response = resttemplate.postforentity("http://192.168.1.xxx:8080/xxl-job-admin/jobinfo/pagelist", entity, string.class); // 解析响应为 hashmap try { return new objectmapper().readvalue(response.getbody(), hashmap.class); } catch (jsonprocessingexception e) { e.printstacktrace(); } return null; } @override public map getjoblogs(string cookie, string jobid) { resttemplate resttemplate = new resttemplate(); // 创建请求头 httpheaders headers = new httpheaders(); headers.add("cookie", cookie); // 构建查询参数 multivaluemap<string, string> params = new linkedmultivaluemap<string, string>(); //执行器id(必传) params.add("jobgroup", "33"); //任务状态(必传) params.add("logstatus", "-1"); // 任务id params.add("jobid", jobid); // 当前页码 params.add("pagenum", "1"); // 每页大小 params.add("pagesize", "10"); // 调用 feign 客户端的查询日志接口 // return client.getjoblogs(cookie, params); // 创建 httpentity 实例,包含请求头和参数 httpentity<multivaluemap<string, string>> entity = new httpentity<>(params, headers); // 发送 post 请求 responseentity<string> response = resttemplate.postforentity("http://192.168.1.xxx:8080/xxl-job-admin//joblog/pagelist", entity, string.class); // 解析响应为 hashmap try { return new objectmapper().readvalue(response.getbody(), hashmap.class); } catch (jsonprocessingexception e) { e.printstacktrace(); } return null; } }
feign 客户端:xxljobfeignclient.java
@feignclient(name = "xxljobclient", url = "http://192.168.1.xxx:8080/xxl-job-admin") public interface xxljobfeignclient { /** * 登录接口,必须先调用获取 cookie 才能访问其它接口 */ @postmapping(value = "/login", consumes = mediatype.application_form_urlencoded_value) response login(@requestheader("content-type") string contenttype, @requestparam("username") string username, @requestparam("password") string password); /** * 新建任务接口 */ @postmapping("/jobinfo/add") resultmodel addjob(@requestheader("cookie") string cookie, @requestbody map<string, object> jobinfo); /** * 更新任务接口 */ @postmapping("/jobinfo/update") resultmodel updatejob(@requestheader("cookie") string cookie, @requestbody map<string, object> jobinfo); /** * 删除任务接口 */ @postmapping("/jobinfo/remove") resultmodel removejob(@requestheader("cookie") string cookie, @requestparam("id") integer jobid); /** * 启动任务接口 */ @postmapping("/jobinfo/start") resultmodel startjob(@requestheader("cookie") string cookie, @requestparam("id") integer jobid); /** * 暂停任务接口 */ @postmapping("/jobinfo/stop") resultmodel stopjob(@requestheader("cookie") string cookie, @requestparam("id") integer jobid); /** * 查执行器列表接口 * @param cookie * @param start * @param length * @return */ @getmapping("/jobgroup/pagelist") map<string, object> getjobgroups(@requestheader("cookie") string cookie, @requestparam("start") int start, @requestparam("length") int length); /** * 获取任务列表 * @param cookie 登录时获得的 cookie * @param params 请求参数 * @return 任务列表 */ @postmapping("/jobinfo/pagelist") resultmodel getjoblist(@requestheader("cookie") string cookie, @requestparam map<string, object> params); /** * 查询日志 * @param cookie * @param params * @return */ @postmapping("/joblog/pagelist") resultmodel getjoblogs(@requestheader("cookie") string cookie, @requestbody multivaluemap<string, string> params); }
以上就是springboot集成xxl-job实现任务管理全流程的详细内容,更多关于springboot xxl-job任务管理的资料请关注代码网其它相关文章!
发表评论