客户端通过RestTemplate发送请求,requestBody是一个复杂数据类型,通过嵌套多层MultiValueMap的方式组合服务端需要的数据类型。

HttpEntity requestBody = generateAddAllRequestBody(strategyJobs);
ResponseEntity<String> responseEntity = this.restTemplate.postForEntity(jobAddAllUrl, requestBody, String.class);
 private HttpEntity generateAddAllRequestBody(List<StrategyJob> strategyJobs) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, MultiValueMap> outerMap = new LinkedMultiValueMap<>();
        for(StrategyJob strategyJob : strategyJobs) {
            MultiValueMap map = new LinkedMultiValueMap();
            map.add("jobGroup",strategyJob.getGroup());
            map.add("jobDesc", strategyJob.getJobDesc());
            map.add("executorRouteStrategy", "FIRST");
            map.add("cronGen_display", strategyJob.getCron());
            map.add("jobCron", strategyJob.getCron());
            map.add("glueType", "BEAN");
            map.add("executorHandler", strategyJob.getExecutorHandler());
            map.add("executorBlockStrategy", "SERIAL_EXECUTION");
            map.add("childJobId", "");
            map.add("executorTimeout", 0);
            map.add("executorFailRetryCount", 0);
            map.add("author", strategyJob.getCreator());
            map.add("alarmEmail", "");
            map.add("executorParam", strategyJob.getStrategyId());
            map.add("glueRemark", "GLUE代码初始化");
            map.add("glueSource", "");
            map.add("triggerStatus", 1);

            if (strategyJob.getId() != null) {
                map.add("id", strategyJob.getId());
            }
            outerMap.add(strategyJob.getKey(), map);
        }
        HttpEntity requestBody = new HttpEntity(outerMap, headers);
        return requestBody;
    }

服务端接收请求的时候,只能解析第一层的key-value值,value中的复杂数据类型无法解析,发生异常,此时需要在服务端增加一个Converter,将默认的String类型转成对应的复杂类型:

package com.xxl.job.admin.core.converter;

import com.alibaba.fastjson.JSON;
import com.xxl.job.admin.core.model.XxlJobInfo;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@Component
public class String2XxlJobInfo implements Converter<String, XxlJobInfo> {

    @Override
    public XxlJobInfo convert(String s) {
        String ss = s.replaceAll("[\\[\\]]", "");
        XxlJobInfo xxlJobInfo = JSON.parseObject(ss, XxlJobInfo.class);
        return xxlJobInfo;
    }
}

服务端的controller方法为:

	@RequestMapping("/addStrategyJobs")
	@ResponseBody
	@PermissionLimit(limit=false)
	public ReturnT<List<String>> addStrategyJobs(StrategyJobInfo strategyJobInfo) {
		return xxlJobService.addStrategyJobs(strategyJobInfo);
	}

其中StrategyJobInfo的代码如:

package com.xxl.job.admin.core.model;

public class StrategyJobInfo {

    XxlJobInfo preApplyJob;
    XxlJobInfo applyJob;
    XxlJobInfo preRestoreJob;
    XxlJobInfo restoreJob;

    public XxlJobInfo getPreApplyJob() {
        return preApplyJob;
    }

    public void setPreApplyJob(XxlJobInfo preApplyJob) {
        this.preApplyJob = preApplyJob;
    }

    public XxlJobInfo getApplyJob() {
        return applyJob;
    }

    public void setApplyJob(XxlJobInfo applyJob) {
        this.applyJob = applyJob;
    }

    public XxlJobInfo getPreRestoreJob() {
        return preRestoreJob;
    }

    public void setPreRestoreJob(XxlJobInfo preRestoreJob) {
        this.preRestoreJob = preRestoreJob;
    }

    public XxlJobInfo getRestoreJob() {
        return restoreJob;
    }

    public void setRestoreJob(XxlJobInfo restoreJob) {
        this.restoreJob = restoreJob;
    }
}

XxlJobInfo的代码如:

package com.xxl.job.admin.core.model;

import java.util.Date;

/**
 * xxl-job info
 *
 * @author xuxueli  2016-1-12 18:25:49
 */
public class XxlJobInfo {

	private int id;				// 主键ID

	private int jobGroup;		// 执行器主键ID
	private String jobCron;		// 任务执行CRON表达式
	private String jobDesc;

	private Date addTime;
	private Date updateTime;

	private String author;		// 负责人
	private String alarmEmail;	// 报警邮件

	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;	// 下次调度时间


	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getJobGroup() {
		return jobGroup;
	}

	public void setJobGroup(int jobGroup) {
		this.jobGroup = jobGroup;
	}

	public String getJobCron() {
		return jobCron;
	}

	public void setJobCron(String jobCron) {
		this.jobCron = jobCron;
	}

	public String getJobDesc() {
		return jobDesc;
	}

	public void setJobDesc(String jobDesc) {
		this.jobDesc = jobDesc;
	}

	public Date getAddTime() {
		return addTime;
	}

	public void setAddTime(Date addTime) {
		this.addTime = addTime;
	}

	public Date getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getAlarmEmail() {
		return alarmEmail;
	}

	public void setAlarmEmail(String alarmEmail) {
		this.alarmEmail = alarmEmail;
	}

	public String getExecutorRouteStrategy() {
		return executorRouteStrategy;
	}

	public void setExecutorRouteStrategy(String executorRouteStrategy) {
		this.executorRouteStrategy = executorRouteStrategy;
	}

	public String getExecutorHandler() {
		return executorHandler;
	}

	public void setExecutorHandler(String executorHandler) {
		this.executorHandler = executorHandler;
	}

	public String getExecutorParam() {
		return executorParam;
	}

	public void setExecutorParam(String executorParam) {
		this.executorParam = executorParam;
	}

	public String getExecutorBlockStrategy() {
		return executorBlockStrategy;
	}

	public void setExecutorBlockStrategy(String executorBlockStrategy) {
		this.executorBlockStrategy = executorBlockStrategy;
	}

	public int getExecutorTimeout() {
		return executorTimeout;
	}

	public void setExecutorTimeout(int executorTimeout) {
		this.executorTimeout = executorTimeout;
	}

	public int getExecutorFailRetryCount() {
		return executorFailRetryCount;
	}

	public void setExecutorFailRetryCount(int executorFailRetryCount) {
		this.executorFailRetryCount = executorFailRetryCount;
	}

	public String getGlueType() {
		return glueType;
	}

	public void setGlueType(String glueType) {
		this.glueType = glueType;
	}

	public String getGlueSource() {
		return glueSource;
	}

	public void setGlueSource(String glueSource) {
		this.glueSource = glueSource;
	}

	public String getGlueRemark() {
		return glueRemark;
	}

	public void setGlueRemark(String glueRemark) {
		this.glueRemark = glueRemark;
	}

	public Date getGlueUpdatetime() {
		return glueUpdatetime;
	}

	public void setGlueUpdatetime(Date glueUpdatetime) {
		this.glueUpdatetime = glueUpdatetime;
	}

	public String getChildJobId() {
		return childJobId;
	}

	public void setChildJobId(String childJobId) {
		this.childJobId = childJobId;
	}

	public int getTriggerStatus() {
		return triggerStatus;
	}

	public void setTriggerStatus(int triggerStatus) {
		this.triggerStatus = triggerStatus;
	}

	public long getTriggerLastTime() {
		return triggerLastTime;
	}

	public void setTriggerLastTime(long triggerLastTime) {
		this.triggerLastTime = triggerLastTime;
	}

	public long getTriggerNextTime() {
		return triggerNextTime;
	}

	public void setTriggerNextTime(long triggerNextTime) {
		this.triggerNextTime = triggerNextTime;
	}
}

参考

11-08 19:12