一、前言
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任务管理的资料请关注代码网其它相关文章!
发表评论