自动添加xxl任务;

This commit is contained in:
王奎兴
2026-09-05 17:37:33 +08:00
parent 10bba6fd9e
commit d10a81fc42
8 changed files with 399 additions and 204 deletions
+5
View File
@@ -116,6 +116,11 @@
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
<!-- JPush推送 -->
<!-- jpush极光推送导入start -->
<!-- <dependency>-->
@@ -98,7 +98,8 @@ public class ContractManageApplicationService {
private ContractManageParametersMapper contractManageParametersMapper;
@Autowired
private IContractManageParametersService contractManageParametersService;
@Resource
private XxlJobOpenApiUtil apiUtil;
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
private static final String token = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjozNTYzLCJ0b3BPcmdhbml6YXRpb25JZCI6MjgyNywidXNlcl9rZXkiOiI0N2MzY2U4My0wMmFjLTQ0NTQtOTdiYS1lYmQwMDc2MzNiNDMiLCJ1c2VybmFtZSI6ImNhbmdtYSJ9.tnZyywwburfBo3Kizdhfk5eYdXbrrZ9976Z0W7GrS6UqSpKwfI2RwdRwfYx7DbD7Ri1Fdj_eOVxBkjvdFF226Q";
@@ -984,27 +985,44 @@ public class ContractManageApplicationService {
}
}
/**
* 创建夜间23点定时任务
* @param shipperId 结算对象id,作为任务参数
* @return xxlJobId 保存到业务表,后续用于删除/暂停
*/
public Integer addXxlJob(String shipperId) {
//1.实例化工具类,建议交给Spring管理
XxlJobOpenApiUtil apiUtil = new XxlJobOpenApiUtil(adminAddresses,token);
//2.构建新增任务参数
XxlJobOpenApiUtil.JobInfoAddReq req = new XxlJobOpenApiUtil.JobInfoAddReq();
req.setJobGroup(5); //你的执行器组id
req.setJobGroup(5);
req.setJobDesc("整租推送计费单据/流水任务,结算对象id:" + shipperId);
req.setJobCron("0 0 1 * * ?");
req.setAuthor("system");
req.setAlarmEmail("");
req.setScheduleType("CRON");
// 每天晚上23点执行
req.setScheduleConf("0 0 1 * * ?");
req.setGlueType("BEAN");
req.setExecutorHandler("pushContractManageToBms");
req.setExecutorParam(shipperId); //传入业务单号
req.setExecutorParam(shipperId);
req.setGlueRemark("");
req.setGlueSource("");
req.setExecutorRouteStrategy("FIRST");
req.setChildJobId(null);
req.setMisfireStrategy("DO_NOTHING");
req.setExecutorBlockStrategy("SERIAL_EXECUTION");
req.setExecutorTimeout(0);
req.setExecutorFailRetryCount(0);
//3.调用创建任务接口 ,返回任务ID
Integer xxlJobId = apiUtil.addJob(req);
if(xxlJobId == null){
// 创建定时任务失败,抛异常/重试,不要让单据直接保存成功
boolean addOk = apiUtil.addJob(req);
if (!addOk) {
throw new RuntimeException("创建夜间定时任务失败");
}
Integer xxlJobId = apiUtil.queryJobIdByDescAndParam(req.getJobDesc(), shipperId);
if (xxlJobId == null) {
throw new RuntimeException("定时任务创建成功,但查询jobId失败");
}
return xxlJobId;
}
public void stopXxlJob(Integer shipperId) {
//1.实例化工具类,建议交给Spring管理
XxlJobOpenApiUtil apiUtil = new XxlJobOpenApiUtil(adminAddresses,token);
@@ -0,0 +1,20 @@
package com.mhd.basic.domain.contractManage.repository.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class XxlJobBusinessConfig {
@Value("${xxl.job.admin.address}")
private String adminAddress;
@Value("${xxl.job.admin.cookie}")
private String adminCookie;
@Bean
public XxlJobOpenApiUtil xxlJobOpenApiUtil() {
return new XxlJobOpenApiUtil(adminAddress, adminCookie);
}
}
@@ -1,138 +1,184 @@
package com.mhd.basic.domain.contractManage.repository.util;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.Map;
/**
* XXLJOB OpenApi 工具类
* 调用XXLJOB后台页面接口(抓包获取 /jobinfo/*)
* 鉴权依赖JSESSIONID Cookie,非官方openapi;老版本xxljob无新增任务openapi
*/
@Slf4j
public class XxlJobOpenApiUtil {
/** xxljob admin地址,例:http://127.0.0.1:8080/xxljobadmin */
private final String adminUrl;
/** 系统配置里的AccessToken */
private final String accessToken;
private final String cookie;
public XxlJobOpenApiUtil(String adminUrl, String accessToken) {
this.adminUrl = adminUrl.endsWith("/") ? adminUrl.substring(0, adminUrl.length() -1) : adminUrl;
this.accessToken = accessToken;
/**
* @param adminUrl xxljob admin地址 示例:http://127.0.0.1:8080/xxl-job-admin
* @param cookie 浏览器登录后的完整Cookie(JSESSIONID=xxx)
*/
public XxlJobOpenApiUtil(String adminUrl, String cookie) {
this.adminUrl = StrUtil.removeSuffix(adminUrl, "/");
this.cookie = cookie;
}
/**
* 新增定时任务
* @param addReq 请求参数
* @return jobId 任务ID,返回null代表调用失败
* 新增定时任务 POST /jobinfo/add
* @param addReq 请求实体,与浏览器payload字段完全对齐
* @return true=新增成功,false=失败
*/
public Integer addJob(JobInfoAddReq addReq) {
String url = adminUrl + "/api/jobinfo/add";
public boolean addJob(JobInfoAddReq addReq) {
String url = adminUrl + "/jobinfo/add";
try {
// 实体对象转map,解决form不能传bean的爆红
Map<String, Object> formMap = BeanUtil.beanToMap(addReq);
HttpResponse response = HttpRequest.post(url)
.header("Authorization", accessToken)
.form(formMap) //传入map,不再传实体
.header("Cookie", cookie)
.form(formMap)
.execute();
int status = response.getStatus();
log.info("[XxlJob] addJob status:{}", status);
// 新增成功302重定向到列表页
return status == 302;
} catch (Exception e) {
log.error("[XxlJob] addJob异常", e);
return false;
}
}
String body = response.body();
log.info("xxljob addJob resp:{}", body);
XxlApiResp resp = JSONUtil.toBean(body, XxlApiResp.class);
if (resp != null && resp.getCode() == 200) {
return Integer.valueOf(resp.getContent().toString());
/**
* 根据【任务描述+执行器参数】查询jobId
* @param jobDesc 任务描述
* @param executorParam 任务参数(业务shipperId)
* @return jobId,查不到返回null
*/
public Integer queryJobIdByDescAndParam(String jobDesc, String executorParam) {
String url = adminUrl + "/jobinfo/pageList";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("jobGroup", "")
.form("jobDesc", jobDesc)
.form("executorHandler", "")
.form("executorParam", executorParam)
.form("triggerStatus", "-1")
.execute();
String html = response.body();
if (StrUtil.isBlank(html)) {
return null;
}
Document doc = Jsoup.parse(html);
Elements trList = doc.select("tr");
for (Element tr : trList) {
String dataId = tr.attr("data-id");
if (StrUtil.isBlank(dataId)) {
continue;
}
return Integer.parseInt(dataId);
}
log.error("新增xxljob任务失败,resp:{}", body);
return null;
} catch (Exception e) {
log.error("调用xxljob addJob异常", e);
log.error("[XxlJob] queryJobId异常", e);
return null;
}
}
/**
* 暂停任务 POST /jobinfo/pause
* @param jobId xxl任务id
* @return true成功
*/
public boolean pauseJob(Integer jobId) {
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/pause";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 302;
} catch (Exception e) {
log.error("[XxlJob] pauseJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 删除任务
* @param jobId 任务id
* 开启任务 POST /jobinfo/start
* @param jobId xxl任务id
* @return true成功
*/
public boolean startJob(Integer jobId) {
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/start";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 302;
} catch (Exception e) {
log.error("[XxlJob] startJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 删除任务 POST /jobinfo/remove
* @param jobId xxl任务id
* @return true成功
*/
public boolean removeJob(Integer jobId) {
String url = adminUrl + "/api/jobinfo/remove";
try (HttpResponse response = HttpRequest.post(url)
.header("Authorization", accessToken)
.form("id", jobId)
.execute()) {
String body = response.body();
XxlApiResp resp = JSONUtil.toBean(body, XxlApiResp.class);
if (resp != null && resp.getCode() == 200) {
return true;
}
log.error("删除xxljob任务失败 jobId:{},resp:{}", jobId, body);
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/remove";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 302;
} catch (Exception e) {
log.error("调用xxljob removeJob异常", e);
log.error("[XxlJob] removeJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 暂停任务
* 请求实体,与浏览器F12抓包payload字段一一对应
*/
public boolean pauseJob(Integer jobId) {
String url = adminUrl + "/api/jobinfo/pause";
try (HttpResponse response = HttpRequest.post(url)
.header("Authorization", accessToken)
.form("id", jobId)
.execute()) {
String body = response.body();
XxlApiResp resp = JSONUtil.toBean(body, XxlApiResp.class);
return resp != null && resp.getCode() == 200;
} catch (Exception e) {
log.error("pauseJob异常", e);
return false;
}
}
//---------------- 实体 ----------------
@Data
public static class JobInfoAddReq {
/** 执行器组ID xxl_job_group.id */
private Integer jobGroup;
/** 任务描述 */
private String jobDesc;
/** 路由策略 ROUND:轮询 */
private String executorRouteStrategy = "ROUND";
/** cron表达式 23点 0 0 23 * * ? */
private String jobCron;
/** @XxlJob 注解handler名称 */
private String author;
private String alarmEmail;
private String scheduleType;
private String scheduleConf;
private String glueType;
private String executorHandler;
/** 任务参数,这里存业务单号 */
private String executorParam;
/** 阻塞策略 SERIAL_EXECUTION单机串行 */
private String executorBlockStrategy = "SERIAL_EXECUTION";
/** 超时时间 0不限制 */
private Integer executorTimeout = 0;
/** 失败重试次数 */
private Integer executorFailRetryCount = 0;
/** BEAN模式 */
private String glueType = "BEAN";
private String glueSource = "";
private String glueRemark = "";
/** 1启用 0停止 */
private Integer triggerStatus = 1;
}
@Data
public static class XxlApiResp {
private Integer code;
private Object content;
private String msg;
private String glueRemark;
private String glueSource;
private String executorRouteStrategy;
private Integer childJobId;
private String misfireStrategy;
private String executorBlockStrategy;
private Integer executorTimeout;
private Integer executorFailRetryCount;
}
}
+5
View File
@@ -100,6 +100,11 @@
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
<!--添加druid连接池 依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
@@ -44,6 +44,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
@@ -78,7 +79,8 @@ public class SettlementCustomersApplicationService {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
private static final String token = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjozNTYzLCJ0b3BPcmdhbml6YXRpb25JZCI6MjgyNywidXNlcl9rZXkiOiI0N2MzY2U4My0wMmFjLTQ0NTQtOTdiYS1lYmQwMDc2MzNiNDMiLCJ1c2VybmFtZSI6ImNhbmdtYSJ9.tnZyywwburfBo3Kizdhfk5eYdXbrrZ9976Z0W7GrS6UqSpKwfI2RwdRwfYx7DbD7Ri1Fdj_eOVxBkjvdFF226Q";
@Resource
private XxlJobOpenApiUtil apiUtil;
/**
* 分页查询结算对象列表
*/
@@ -352,48 +354,82 @@ public class SettlementCustomersApplicationService {
return settlementCustomersDomainService.update(settlementCustomersDO);
}
/**
* 创建夜间23点定时任务
* @param shipperId 结算对象id,作为任务参数
* @return xxlJobId 保存到业务表,后续用于删除/暂停
*/
public Integer addXxlJob(String shipperId) {
//1.实例化工具类,建议交给Spring管理
XxlJobOpenApiUtil apiUtil = new XxlJobOpenApiUtil(adminAddresses,token);
//2.构建新增任务参数
XxlJobOpenApiUtil.JobInfoAddReq req = new XxlJobOpenApiUtil.JobInfoAddReq();
req.setJobGroup(3); //你的执行器组id
req.setJobGroup(5);
req.setJobDesc("散租推送计费单据/流水任务,结算对象id:" + shipperId);
req.setJobCron("0 0 1 * * ?");
req.setAuthor("system");
req.setAlarmEmail("");
req.setScheduleType("CRON");
// 每天晚上23点执行
req.setScheduleConf("0 0 1 * * ?");
req.setGlueType("BEAN");
req.setExecutorHandler("pushBillingRecord");
req.setExecutorParam(shipperId); //传入业务单号
req.setExecutorParam(shipperId);
req.setGlueRemark("");
req.setGlueSource("");
req.setExecutorRouteStrategy("FIRST");
req.setChildJobId(null);
req.setMisfireStrategy("DO_NOTHING");
req.setExecutorBlockStrategy("SERIAL_EXECUTION");
req.setExecutorTimeout(0);
req.setExecutorFailRetryCount(0);
//3.调用创建任务接口 ,返回任务ID
Integer xxlJobId = apiUtil.addJob(req);
if(xxlJobId == null){
// 创建定时任务失败,抛异常/重试,不要让单据直接保存成功
boolean addOk = apiUtil.addJob(req);
if (!addOk) {
throw new RuntimeException("创建夜间定时任务失败");
}
Integer xxlJobId = apiUtil.queryJobIdByDescAndParam(req.getJobDesc(), shipperId);
if (xxlJobId == null) {
throw new RuntimeException("定时任务创建成功,但查询jobId失败");
}
return xxlJobId;
}
/**
* 创建夜间23点定时任务
* @param shipperId 结算对象id,作为任务参数
* @return xxlJobId 保存到业务表,后续用于删除/暂停
*/
public Integer addXxlJob1(String shipperId) {
//1.实例化工具类,建议交给Spring管理
XxlJobOpenApiUtil apiUtil = new XxlJobOpenApiUtil(adminAddresses,token);
//2.构建新增任务参数
XxlJobOpenApiUtil.JobInfoAddReq req = new XxlJobOpenApiUtil.JobInfoAddReq();
req.setJobGroup(6); //你的执行器组id
req.setJobGroup(5);
req.setJobDesc("计费单据/流水生成发票任务,结算对象id:" + shipperId);
req.setJobCron("0 0 1 * * ?");
req.setAuthor("system");
req.setAlarmEmail("");
req.setScheduleType("CRON");
// 每天晚上23点执行
req.setScheduleConf("0 0 1 * * ?");
req.setGlueType("BEAN");
req.setExecutorHandler("pushBillManage");
req.setExecutorParam(shipperId); //传入业务单号
req.setExecutorParam(shipperId);
req.setGlueRemark("");
req.setGlueSource("");
req.setExecutorRouteStrategy("FIRST");
req.setChildJobId(null);
req.setMisfireStrategy("DO_NOTHING");
req.setExecutorBlockStrategy("SERIAL_EXECUTION");
req.setExecutorTimeout(0);
req.setExecutorFailRetryCount(0);
//3.调用创建任务接口 ,返回任务ID
Integer xxlJobId = apiUtil.addJob(req);
if(xxlJobId == null){
// 创建定时任务失败,抛异常/重试,不要让单据直接保存成功
boolean addOk = apiUtil.addJob(req);
if (!addOk) {
throw new RuntimeException("创建夜间定时任务失败");
}
Integer xxlJobId = apiUtil.queryJobIdByDescAndParam(req.getJobDesc(), shipperId);
if (xxlJobId == null) {
throw new RuntimeException("定时任务创建成功,但查询jobId失败");
}
return xxlJobId;
}
public void stopXxlJob(Integer shipperId) {
//1.实例化工具类,建议交给Spring管理
XxlJobOpenApiUtil apiUtil = new XxlJobOpenApiUtil(adminAddresses,token);
@@ -0,0 +1,20 @@
package com.mhd.bms.domain.settlementCustomers.repository.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class XxlJobBusinessConfig {
@Value("${xxl.job.admin.address}")
private String adminAddress;
@Value("${xxl.job.admin.cookie}")
private String adminCookie;
@Bean
public XxlJobOpenApiUtil xxlJobOpenApiUtil() {
return new XxlJobOpenApiUtil(adminAddress, adminCookie);
}
}
@@ -1,139 +1,184 @@
package com.mhd.bms.domain.settlementCustomers.repository.util;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.Map;
/**
* XXLJOB OpenApi 工具类
* 调用XXLJOB后台页面接口(抓包获取 /jobinfo/*)
* 鉴权依赖JSESSIONID Cookie,非官方openapi;老版本xxljob无新增任务openapi
*/
@Slf4j
public class XxlJobOpenApiUtil {
/** xxljob admin地址,例:http://127.0.0.1:8080/xxljobadmin */
private final String adminUrl;
/** 系统配置里的AccessToken */
private final String accessToken;
private final String cookie;
public XxlJobOpenApiUtil(String adminUrl, String accessToken) {
this.adminUrl = adminUrl.endsWith("/") ? adminUrl.substring(0, adminUrl.length() -1) : adminUrl;
this.accessToken = accessToken;
/**
* @param adminUrl xxljob admin地址 示例:http://127.0.0.1:8080/xxl-job-admin
* @param cookie 浏览器登录后的完整Cookie(JSESSIONID=xxx)
*/
public XxlJobOpenApiUtil(String adminUrl, String cookie) {
this.adminUrl = StrUtil.removeSuffix(adminUrl, "/");
this.cookie = cookie;
}
/**
* 新增定时任务
* @param addReq 请求参数
* @return jobId 任务ID,返回null代表调用失败
* 新增定时任务 POST /jobinfo/add
* @param addReq 请求实体,与浏览器payload字段完全对齐
* @return true=新增成功,false=失败
*/
public Integer addJob(JobInfoAddReq addReq) {
String url = adminUrl + "/api/jobinfo/add";
public boolean addJob(JobInfoAddReq addReq) {
String url = adminUrl + "/jobinfo/add";
try {
// 实体对象转map,解决form不能传bean的爆红
Map<String, Object> formMap = BeanUtil.beanToMap(addReq);
HttpResponse response = HttpRequest.post(url)
.header("Authorization", accessToken)
.form(formMap) //传入map,不再传实体
.header("Cookie", cookie)
.form(formMap)
.execute();
int status = response.getStatus();
log.info("[XxlJob] addJob status:{}", status);
// 新增成功302重定向到列表页
return status == 302;
} catch (Exception e) {
log.error("[XxlJob] addJob异常", e);
return false;
}
}
String body = response.body();
log.info("xxljob addJob resp:{}", body);
XxlApiResp resp = JSONUtil.toBean(body, XxlApiResp.class);
if (resp != null && resp.getCode() == 200) {
return Integer.valueOf(resp.getContent().toString());
/**
* 根据【任务描述+执行器参数】查询jobId
* @param jobDesc 任务描述
* @param executorParam 任务参数(业务shipperId)
* @return jobId,查不到返回null
*/
public Integer queryJobIdByDescAndParam(String jobDesc, String executorParam) {
String url = adminUrl + "/jobinfo/pageList";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("jobGroup", "")
.form("jobDesc", jobDesc)
.form("executorHandler", "")
.form("executorParam", executorParam)
.form("triggerStatus", "-1")
.execute();
String html = response.body();
if (StrUtil.isBlank(html)) {
return null;
}
Document doc = Jsoup.parse(html);
Elements trList = doc.select("tr");
for (Element tr : trList) {
String dataId = tr.attr("data-id");
if (StrUtil.isBlank(dataId)) {
continue;
}
return Integer.parseInt(dataId);
}
log.error("新增xxljob任务失败,resp:{}", body);
return null;
} catch (Exception e) {
log.error("调用xxljob addJob异常", e);
log.error("[XxlJob] queryJobId异常", e);
return null;
}
}
/**
* 暂停任务 POST /jobinfo/pause
* @param jobId xxl任务id
* @return true成功
*/
public boolean pauseJob(Integer jobId) {
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/pause";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 302;
} catch (Exception e) {
log.error("[XxlJob] pauseJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 删除任务
* @param jobId 任务id
* 开启任务 POST /jobinfo/start
* @param jobId xxl任务id
* @return true成功
*/
public boolean startJob(Integer jobId) {
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/start";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 302;
} catch (Exception e) {
log.error("[XxlJob] startJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 删除任务 POST /jobinfo/remove
* @param jobId xxl任务id
* @return true成功
*/
public boolean removeJob(Integer jobId) {
String url = adminUrl + "/api/jobinfo/remove";
try (HttpResponse response = HttpRequest.post(url)
.header("Authorization", accessToken)
.form("id", jobId)
.execute()) {
String body = response.body();
XxlApiResp resp = JSONUtil.toBean(body, XxlApiResp.class);
if (resp != null && resp.getCode() == 200) {
return true;
}
log.error("删除xxljob任务失败 jobId:{},resp:{}", jobId, body);
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/remove";
try {
HttpResponse response = HttpRequest.post(url)
.header("Cookie", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 302;
} catch (Exception e) {
log.error("调用xxljob removeJob异常", e);
log.error("[XxlJob] removeJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 暂停任务
* 请求实体,与浏览器F12抓包payload字段一一对应
*/
public boolean pauseJob(Integer jobId) {
String url = adminUrl + "/api/jobinfo/pause";
try (HttpResponse response = HttpRequest.post(url)
.header("Authorization", accessToken)
.form("id", jobId)
.execute()) {
String body = response.body();
XxlApiResp resp = JSONUtil.toBean(body, XxlApiResp.class);
return resp != null && resp.getCode() == 200;
} catch (Exception e) {
log.error("pauseJob异常", e);
return false;
}
}
//---------------- 实体 ----------------
@Data
public static class JobInfoAddReq {
/** 执行器组ID xxl_job_group.id */
private Integer jobGroup;
/** 任务描述 */
private String jobDesc;
/** 路由策略 ROUND:轮询 */
private String executorRouteStrategy = "ROUND";
/** cron表达式 23点 0 0 23 * * ? */
private String jobCron;
/** @XxlJob 注解handler名称 */
private String author;
private String alarmEmail;
private String scheduleType;
private String scheduleConf;
private String glueType;
private String executorHandler;
/** 任务参数,这里存业务单号 */
private String executorParam;
/** 阻塞策略 SERIAL_EXECUTION单机串行 */
private String executorBlockStrategy = "SERIAL_EXECUTION";
/** 超时时间 0不限制 */
private Integer executorTimeout = 0;
/** 失败重试次数 */
private Integer executorFailRetryCount = 0;
/** BEAN模式 */
private String glueType = "BEAN";
private String glueSource = "";
private String glueRemark = "";
/** 1启用 0停止 */
private Integer triggerStatus = 1;
}
@Data
public static class XxlApiResp {
private Integer code;
private Object content;
private String msg;
private String glueRemark;
private String glueSource;
private String executorRouteStrategy;
private Integer childJobId;
private String misfireStrategy;
private String executorBlockStrategy;
private Integer executorTimeout;
private Integer executorFailRetryCount;
}
}