xxl-job对外接口(新增、编辑、删除、挂起任务)

1.前言

由于xxl-job提供了图形化界面添加任务,所有针对业务系统如果是固定时间需要调度任务时,则可以用通过这种图形化界面方式添加,但是有些业务系统需要根据自己的业务去创建任务,这样图形化的添加方式就不满足使用了,所以需要提供对外接口供业务系统调用,例如新增,编辑,删除,挂起。下面就是操作过程。

2.编写对外接口

  1. 由于xxl-job-admin调用中心里面的接口都需要登录后携带cookie访问,所以需要业务系统先模拟登陆(掉登陆接口)获取到cookie值,然后再调用新增,编辑,删除,挂起接口的时候携带上cookie访问。具体操作如下:

2.编写对外接口

package com.xxl.job.admin.rest;

import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.thread.JobScheduleHelper;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.service.LoginService;
import com.xxl.job.admin.service.XxlJobService;
import com.xxl.job.core.biz.model.ReturnT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.util.Date;

/**
 * @Description TODO
 * @Author jiuwei
 * @Date Created in 下午8:13 2020/2/15
 * @Version 1.0
 */
@RestController
@RequestMapping("/api/jobinfo")
public class XxlJobAdminRestController {

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

    @Autowired
    private XxlJobService xxlJobService;

    @Autowired
    private LoginService loginService;

    @RequestMapping(value = "/save",method = RequestMethod.POST)
    public ReturnT<String> add(@RequestBody(required = true)XxlJobInfo jobInfo) throws Exception {

        // next trigger time (5s后生效,避开预读周期)
        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<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_never_fire"));
            }
            nextTriggerTime = nextValidTime.getTime();
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
            return new ReturnT<String>(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<String> delete(int id) {
       return xxlJobService.remove(id);
    }

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

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

    @RequestMapping(value="login", method=RequestMethod.GET)
    @PermissionLimit(limit=false)
    public ReturnT<String> 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<String> result= loginService.login(request, response, userName, password, ifRem);
        return result;
    }
}

3.编写HttpClient工具类

package com.xxl.job.executor.util;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import net.sf.json.JSONObject;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;

import java.io.IOException;

/**
 * @Description TODO
 * @Author jiuwei
 * @Date Created in 下午8:13 2020/2/15
 * @Version 1.0
 */
public class ApiUtil {

	public static Logger logger =  LoggerFactory.getLogger(ApiUtil.class);

	private static String cookie="";

	/**
	 * 新增/编辑任务
	 * @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);
		RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8");
		post.setRequestEntity(requestEntity);
		httpClient.executeMethod(post);
		JSONObject result = new JSONObject();
		result = getJsonObject(post, result);
		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 get, JSONObject result) throws IOException {
		if (get.getStatusCode() == 200) {
			String responseBodyAsString = get.getResponseBodyAsString();
			result = JSONObject.fromObject(responseBodyAsString);
		} else {
			try {
				result = JSONObject.fromObject(get.getResponseBodyAsString());
			} catch (Exception e) {
				result.put("error", get.getResponseBodyAsString());
			}
		}
		return result;
	}


    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;
    }

}

4:编写测试接口

package com.xxl.job.executor.rest;

import com.xxl.job.executor.util.ApiUtil;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import response.ResponseData;

import java.io.IOException;

/**
 * @Description TODO
 * @Author jiuwei
 * @Date Created in 下午8:13 2020/2/15
 * @Version 1.0
 */
@RestController
@RequestMapping("/taskDemo")
public class JobInfoRestResource {


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

	/**
	 * 添加任务
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/add",method = RequestMethod.GET)
	public ResponseData add() throws IOException {
		JSONObject requestInfo = new JSONObject();
		requestInfo.put("jobGroup",1);
		requestInfo.put("jobDesc","我是任务");
		requestInfo.put("executorRouteStrategy","FIRST");
		requestInfo.put("cronGen_display","0 0/1 * * * ?");
		requestInfo.put("jobCron","0 0/1 * * * ?");
		requestInfo.put("glueType","BEAN");
		requestInfo.put("executorHandler","demoJobHandler");
		requestInfo.put("executorBlockStrategy","SERIAL_EXECUTION");
		requestInfo.put("executorTimeout",0);
		requestInfo.put("executorFailRetryCount",1);
		requestInfo.put("author","admin");
		requestInfo.put("alarmEmail","xxx@qq.com");
		requestInfo.put("executorParam","att");
		requestInfo.put("glueRemark","GLUE代码初始化");
		JSONObject response=ApiUtil.addJob(adminAddresses,requestInfo);
        if(response.containsKey("code")&&200==response.getInt("code")){
            return ResponseData.success();
        }else{
            return ResponseData.error("调用api接口失败!");
        }

	}

    /**
     * 删除任务
     * @param id
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/delete",method = RequestMethod.GET)
    public ResponseData delete(int id) throws IOException {
        JSONObject response=ApiUtil.deleteJob(adminAddresses,id);
        if(response.containsKey("code")&&200==response.getInt("code")){
            return ResponseData.success();
        }else{
            return ResponseData.error("调用api接口失败!");
        }

    }

    /**
     * 开始任务
     * @param id
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/start",method = RequestMethod.GET)
    public ResponseData start(int id) throws IOException {
        JSONObject response=ApiUtil.startJob(adminAddresses,id);
        if(response.containsKey("code")&&200==response.getInt("code")){
            return ResponseData.success();
        }else{
            return ResponseData.error("调用api接口失败!");
        }

    }

    /**
     * 挂起任务
     * @param id
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/stop",method = RequestMethod.GET)
    public ResponseData stop(int id) throws IOException {
        JSONObject response=ApiUtil.stopJob(adminAddresses,id);
        if(response.containsKey("code")&&200==response.getInt("code")){
            return ResponseData.success();
        }else{
            return ResponseData.error("调用api接口失败!");
        }

    }

    /**
     * 登陆
     * @param userName
     * @param password
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public ResponseData login(String userName,String password) throws IOException {
        String cookie=ApiUtil.login(adminAddresses,userName,password);
        if(StringUtils.isNotBlank(cookie)){
            return ResponseData.success(cookie);
        }else{
            return ResponseData.error("调用api接口失败!");
        }

    }


	
}

5.封装返回实体类

package response;

/**
 * 请求失败的返回
 *
 */
public class ErrorResponseData<T> extends ResponseData<T> {
	/**
	 * 异常的具体类名称
	 */
	private String exceptionClazz;

	public ErrorResponseData(String message) {
		super(false, ResponseData.DEFAULT_ERROR_CODE, message, null);
	}

	public ErrorResponseData(Integer code, String message) {
		super(false, code, message, null);
	}

	public ErrorResponseData(Integer code, String message, String exceptionClazz) {
		super(false, code, message, null);
		this.exceptionClazz = exceptionClazz;
	}

	public ErrorResponseData(Integer code, String message, T object) {
		super(false, code, message, object);
	}

	public ErrorResponseData(Integer code, String message, T object, String exceptionClazz) {
		super(false, code, message, object);
		this.exceptionClazz = exceptionClazz;
	}

	public String getExceptionClazz() {
		return exceptionClazz;
	}

	public void setExceptionClazz(String exceptionClazz) {
		this.exceptionClazz = exceptionClazz;
	}

}
package response;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

/**
 * 返回给前台的通用包装
 * 
 */
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class ResponseData<T> {

	public static final String DEFAULT_SUCCESS_MESSAGE = "请求成功";

	public static final String DEFAULT_ERROR_MESSAGE = "网络异常";

	public static final Integer DEFAULT_SUCCESS_CODE = 0;

	public static final Integer DEFAULT_ERROR_CODE = 500;

	/**
	 * 请求是否成功
	 */
	private Boolean success;

	/**
	 * 响应状态码
	 */
	private Integer errcode;

	/**
	 * 响应信息
	 */
	private String errmessage;

	/**
	 * 响应对象
	 */
	private T data;

	public ResponseData() {
	}

	public ResponseData(Boolean success, Integer code, String message, T data) {
		this.success = success;
		this.errcode = code;
		this.errmessage = message;
		this.data = data;
	}

	public static SuccessResponseData<?> success() {
		return new SuccessResponseData<>();
	}

	public static <T> SuccessResponseData<T> success(T object) {
		return new SuccessResponseData<T>(object);
	}

	public static <T> SuccessResponseData<T> success(Integer code, String message, T object) {
		return new SuccessResponseData<T>(code, message, object);
	}

	public static ErrorResponseData<?> error(String message) {
		return new ErrorResponseData<>(message);
	}

	public static ErrorResponseData<?> error(Integer code, String message) {
		return new ErrorResponseData<>(code, message);
	}

	public static <T> ErrorResponseData<T> error(Integer code, String message, T object) {
		return new ErrorResponseData<T>(code, message, object);
	}

	public Boolean getSuccess() {
		return success;
	}

	public void setSuccess(Boolean success) {
		this.success = success;
	}

	public Integer getErrcode() {
		return errcode;
	}

	public void setErrcode(Integer errcode) {
		this.errcode = errcode;
	}

	public String getErrmessage() {
		return errmessage;
	}

	public void setErrmessage(String errmessage) {
		this.errmessage = errmessage;
	}

	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}

}
package response;

/**
 * 请求成功的返回
 *
 */
public class SuccessResponseData<T> extends ResponseData<T> {

	public SuccessResponseData() {
		super(true, DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, null);
	}

	public SuccessResponseData(T object) {
		super(true, DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, object);
	}

	public SuccessResponseData(Integer code, String message, T object) {
		super(true, code, message, object);
	}

}

到此,对外新增/编辑,删除,挂起等接口就已经写好了。

  • 9
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
xxl-job是一个分布式任务调度框架,可以用于实现定时任务的调度和执行。在xxl-job中,定时任务的配置和管理主要涉及到三个部分:xxl-job-admin、执行器组件和定时任务的数据处理。 1. xxl-job-admin是xxl-job的管理后台,可以通过调用com.xxl.job.admin.controller.JobApiController.callback接口来设置定时任务。这个接口可以用于添加、修改、删除定时任务,以及启动、停止定时任务的执行。 2. 执行器组件是用于执行定时任务的组件,其中的配置文件地址为/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java。在这个配置文件中,你可以设置定时任务的一些参数,比如调度线程池大小、任务执行器等。 3. 定时任务的数据处理需要在xxl-job-executor-sample-springboot项目中进行,这是业务代码所在的项目。在这个项目中,你可以使用BEAN模式来设置定时任务。BEAN模式是指通过在类中定义方法并使用@XxlJob注解来标识定时任务,然后在XxlJobConfig.java配置文件中将这个类注册为定时任务。这种方式比较简单,但在官网上没有提供具体的示例。 所以,如果你想使用xxl-job来实现定时任务,你可以先在xxl-job-admin中设置定时任务,然后在执行器组件中配置定时任务的相关参数,最后在xxl-job-executor-sample-springboot项目中使用BEAN模式设置定时任务。这样就能够实现定时任务的调度和执行了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值