跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Springboot整合xxljob,自定义添加、修改、删除、停止、启动任务方式

目录

一、模拟登录方式

二、注解方式

三、访问者调用

1、创建实体

2、创建一个工具类

四、测试

总结

本次自定义方式分为两种:

一种是模拟登录,另一种是使用注解的方式

一、模拟登录方式

修改xxl-job-admin工程,在controller里面添加一个MyApiController,在里面添加自定义的增删等方法@RestController@RequestMapping("/api/myjobinfo") public class MyApiController {

private static Logger logger = LoggerFactory.getLogger(MyDynamicApiController.class);

@Autowired private XxlJobService xxlJobService;

@Autowired private LoginService loginService;

@RequestMapping(value = "/pageList",method = RequestMethod.POST) public Map pageList(@RequestBody XxlJobQuery xxlJobQuery) {return xxlJobService.pageList(xxlJobQuery.getStart(),xxlJobQuery.getLength(),xxlJobQuery.getJobGroup(),xxlJobQuery.getTriggerStatus(),xxlJobQuery.getJobDesc(),xxlJobQuery.getExecutorHandler(),xxlJobQuery.getAuthor());}

@PostMapping("/save") public ReturnT add(@RequestBody(required = true)XxlJobInfo jobInfo) {

long nextTriggerTime = 0;try {Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));if (nextValidTime == null) {return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_never_fire"));}nextTriggerTime = nextValidTime.getTime();} catch (ParseException e) {logger.error(e.getMessage(), e);return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid")+" | "+ e.getMessage());}

jobInfo.setTriggerStatus(1);jobInfo.setTriggerLastTime(0);jobInfo.setTriggerNextTime(nextTriggerTime);

jobInfo.setUpdateTime(new Date());

if(jobInfo.getId()==0){return xxlJobService.add(jobInfo);}else{return xxlJobService.update(jobInfo);}}

@RequestMapping(value = "/delete",method = RequestMethod.GET) public ReturnT delete(int id) {return xxlJobService.remove(id);}

@RequestMapping(value = "/start",method = RequestMethod.GET) public ReturnT start(int id) {return xxlJobService.start(id);}

@RequestMapping(value = "/stop",method = RequestMethod.GET) public ReturnT stop(int id) {return xxlJobService.stop(id);}

@RequestMapping(value="login", method=RequestMethod.GET)@PermissionLimit(limit=false) public ReturnT loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember){boolean ifRem = (ifRemember!=null && ifRemember.trim().length()>0 && "on".equals(ifRemember))?true:false;ReturnT result= loginService.login(request, response, userName, password, ifRem);return result;}}此方式优点:除了登录接口为,其他接口都需要校验缺点:调用接口前需要登录,比较繁琐

二、注解方式

在项目中,有一个JobInfoController类,,这个类就是处理各种新增任务,修改任务,触发任务;但这些接口都是后台管理页面使用的,要想调用就必须要先登录,也就是方式一,然而xxl-job已经为我们提供了一个注解,通过这个注解的配置可以跳过登录进行访问,这个注解就是@PermissionLimit(limit = false),将limit设置为false即可,默认是true,也就是需要做登录验证。我们可以在自己定义的Controller上使用这个注解。

@RestController@RequestMapping("/api/myjobinfo") public class MyApiController {

@RequestMapping("/add")@ResponseBody@PermissionLimit(limit = false) public ReturnT addJobInfo(@RequestBody XxlJobInfo jobInfo) {return xxlJobService.add(jobInfo);}

@RequestMapping("/update")@ResponseBody@PermissionLimit(limit = false) public ReturnT updateJobCron(@RequestBody XxlJobInfo jobInfo) {return xxlJobService.updateCron(jobInfo);}

@RequestMapping("/remove")@ResponseBody@PermissionLimit(limit = false) public ReturnT removeJob(@RequestBody XxlJobInfo jobInfo) {return xxlJobService.remove(jobInfo.getId());}

@RequestMapping("/pauseJob")@ResponseBody@PermissionLimit(limit = false) public ReturnT pauseJob(@RequestBody XxlJobInfo jobInfo) {return xxlJobService.stop(jobInfo.getId());}

@RequestMapping("/start")@ResponseBody@PermissionLimit(limit = false) public ReturnT startJob(@RequestBody XxlJobInfo jobInfo) {return xxlJobService.start(jobInfo.getId());}

@RequestMapping("/stop")@ResponseBody public ReturnT pause(int id) {return xxlJobService.stop(id);}

@RequestMapping("/addAndStart")@ResponseBody@PermissionLimit(limit = false) public ReturnT addAndStart(@RequestBody XxlJobInfo jobInfo) {ReturnT result = xxlJobService.add(jobInfo);int id = Integer.valueOf(result.getContent());xxlJobService.start(id);return result;}

}该方式的优点:无需登录可以直接调用接口缺点:接口全部暴露有一定的风险将admin项目编译打包后放入服务器,客户端就可以开始调用了....

三、访问者调用

1、创建实体

@Data public class XxlJobInfo {

private int id; // 主键ID private int jobGroup; // 执行器主键ID private String jobDesc; // 备注private String jobCron;private Date addTime;private Date updateTime;private String author; // 负责人private String alarmEmail; // 报警邮件private String scheduleType; // 调度类型private String scheduleConf; // 调度配置,值含义取决于调度类型private String misfireStrategy; // 调度过期策略private String executorRouteStrategy; // 执行器路由策略private String executorHandler; // 执行器,任务Handler名称private String executorParam; // 执行器,任务参数private String executorBlockStrategy; // 阻塞处理策略private int executorTimeout; // 任务执行超时时间,单位秒private int executorFailRetryCount; // 失败重试次数private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum private String glueSource; // GLUE源代码private String glueRemark; // GLUE备注private Date glueUpdatetime; // GLUE更新时间private String childJobId; // 子任务ID,多个逗号分隔private int triggerStatus; // 调度状态:0-停止,1-运行private long triggerLastTime; // 上次调度时间private long triggerNextTime; // 下次调度时间}

2、创建一个工具类

也可以不创建直接调用public class XxlJobUtil {private static String cookie="";

/*** 查询现有的任务* @param url* @param requestInfo* @return* @throws HttpException* @throws IOException*/ public static JSONObject pageList(String url,JSONObject requestInfo) throws HttpException, IOException {String path = "/api/jobinfo/pageList";String targetUrl = url + path;HttpClient httpClient = new HttpClient();PostMethod post = new PostMethod(targetUrl);post.setRequestHeader("cookie", cookie);RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8");post.setRequestEntity(requestEntity);httpClient.executeMethod(post);JSONObject result = new JSONObject();result = getJsonObject(post, result);System.out.println(result.toJSONString());return result;}

/*** 新增/编辑任务* @param url* @param requestInfo* @return* @throws HttpException* @throws IOException*/ public static JSONObject addJob(String url,JSONObject requestInfo) throws HttpException, IOException {String path = "/api/jobinfo/save";String targetUrl = url + path;HttpClient httpClient = new HttpClient();PostMethod post = new PostMethod(targetUrl);post.setRequestHeader("cookie", cookie);RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8");post.setRequestEntity(requestEntity);httpClient.executeMethod(post);JSONObject result = new JSONObject();result = getJsonObject(post, result);System.out.println(result.toJSONString());return result;}

/*** 删除任务* @param url* @param id* @return* @throws HttpException* @throws IOException*/ public static JSONObject deleteJob(String url,int id) throws HttpException, IOException {String path = "/api/jobinfo/delete?id="+id;return doGet(url,path);}

/*** 开始任务* @param url* @param id* @return* @throws HttpException* @throws IOException*/ public static JSONObject startJob(String url,int id) throws HttpException, IOException {String path = "/api/jobinfo/start?id="+id;return doGet(url,path);}

/*** 停止任务* @param url* @param id* @return* @throws HttpException* @throws IOException*/ public static JSONObject stopJob(String url,int id) throws HttpException, IOException {String path = "/api/jobinfo/stop?id="+id;return doGet(url,path);}

public static JSONObject doGet(String url,String path) throws HttpException, IOException {String targetUrl = url + path;HttpClient httpClient = new HttpClient();HttpMethod get = new GetMethod(targetUrl);get.setRequestHeader("cookie", cookie);httpClient.executeMethod(get);JSONObject result = new JSONObject();result = getJsonObject(get, result);return result;}

private static JSONObject getJsonObject(HttpMethod postMethod, JSONObject result) throws IOException {if (postMethod.getStatusCode() == HttpStatus.SC_OK) {InputStream inputStream = postMethod.getResponseBodyAsStream();BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));StringBuffer stringBuffer = new StringBuffer();String str;while((str = br.readLine()) != null){stringBuffer.append(str);}String response = new String(stringBuffer);br.close();

return (JSONObject) JSONObject.parse(response);} else {return null;}

}

/*** 登录* @param url* @param userName* @param password* @return* @throws HttpException* @throws IOException*/ public static String login(String url, String userName, String password) throws HttpException, IOException {String path = "/api/jobinfo/login?userName="+userName+"&password="+password;String targetUrl = url + path;HttpClient httpClient = new HttpClient();HttpMethod get = new GetMethod((targetUrl));httpClient.executeMethod(get);if (get.getStatusCode() == 200) {Cookie[] cookies = httpClient.getState().getCookies();StringBuffer tmpcookies = new StringBuffer();for (Cookie c : cookies) {tmpcookies.append(c.toString() + ";");}cookie = tmpcookies.toString();} else {try {cookie = "";} catch (Exception e) {cookie="";}}return cookie;}}如果是方式二可以直接调用,无需登录

四、测试

如果是方式二,无需登录,也就不用再请求头里面设置cookie@RestController public class TestController {

@Value("${xxl.job.admin.addresses:''}") private String adminAddresses;

@Value("${xxl.job.admin.login-username:admin}") private String loginUsername;

@Value("${xxl.job.admin.login-pwd:123456}") private String loginPwd;

//登陆private void xxljob_login(){try {XxlJobUtil.login(adminAddresses,loginUsername,loginPwd);} catch (IOException e) {throw new RuntimeException(e);}}

@RequestMapping(value = "/pageList",method = RequestMethod.GET) public Object pageList() throws IOException {// int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author JSONObject test=new JSONObject();test.put("length",10);xxljob_login();

JSONObject response = XxlJobUtil.pageList(adminAddresses, test);return response.get("data");}

@RequestMapping(value = "/add",method = RequestMethod.GET) public Object add() throws IOException {XxlJobInfo xxlJobInfo=new XxlJobInfo();xxlJobInfo.setJobCron("0/1 * * * * ?");xxlJobInfo.setJobGroup(3);xxlJobInfo.setJobDesc("Test XXl-job");xxlJobInfo.setAddTime(new Date());xxlJobInfo.setUpdateTime(new Date());xxlJobInfo.setAuthor("Test");xxlJobInfo.setAlarmEmail("1234567@com");xxlJobInfo.setScheduleType("CRON");xxlJobInfo.setScheduleConf("0/1 * * * * ?");xxlJobInfo.setMisfireStrategy("DO_NOTHING");xxlJobInfo.setExecutorRouteStrategy("FIRST");xxlJobInfo.setExecutorHandler("clockInJobHandler_1");xxlJobInfo.setExecutorParam("att");xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");xxlJobInfo.setExecutorTimeout(0);xxlJobInfo.setExecutorFailRetryCount(1);xxlJobInfo.setGlueType("BEAN");xxlJobInfo.setGlueSource("");xxlJobInfo.setGlueRemark("初始化");xxlJobInfo.setGlueUpdatetime(new Date());JSONObject test = (JSONObject) JSONObject.toJSON(xxlJobInfo);

xxljob_login();JSONObject response = XxlJobUtil.addJob(adminAddresses, test);if (response.containsKey("code") && 200 == (Integer) response.get("code")) {String jobId = response.getString("content");System.out.println("新增成功,jobId:" + jobId);} else {System.out.println("新增失败");}return response;}

@RequestMapping(value = "/stop/{jobId}",method = RequestMethod.GET) public void stop(@PathVariable("jobId") Integer jobId) throws IOException {

xxljob_login();JSONObject response = XxlJobUtil.stopJob(adminAddresses, jobId);if (response.containsKey("code") && 200 == (Integer) response.get("code")) {System.out.println("任务停止成功");} else {System.out.println("任务停止失败");}}

@RequestMapping(value = "/delete/{jobId}",method = RequestMethod.GET) public void delete(@PathVariable("jobId") Integer jobId) throws IOException {

xxljob_login();JSONObject response = XxlJobUtil.deleteJob(adminAddresses, jobId);if (response.containsKey("code") && 200 == (Integer) response.get("code")) {System.out.println("任务移除成功");} else {System.out.println("任务移除失败");}}

@RequestMapping(value = "/start/{jobId}",method = RequestMethod.GET) public void start(@PathVariable("jobId") Integer jobId) throws IOException {

xxljob_login();JSONObject response = XxlJobUtil.startJob(adminAddresses, jobId);if (response.containsKey("code") && 200 == (Integer) response.get("code")) {System.out.println("任务启动成功");} else {System.out.println("任务启动失败");}}

}总结以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:SpringBoot整合XxlJob分布式任务调度平台SpringBoot项目集成xxljob实现全纪录SpringBoot整合XXLJob的实现示例

相关文章