提交 87ce1536 编写于 作者: X xueli.xue

记录调度日志

上级 abf21f18
......@@ -27,3 +27,6 @@ git.osc地址:http://git.oschina.net/xuxueli0323/xxl-job
Tips:如果您追求一个简单调度服务,这里也提供了一个简洁分支[xxl-job-simple],它针对旧版调度框架做了细微完善;
# 其他说明
清楚僵尸任务:qrtz_cron_triggers、qrtz_triggers、qrtz_job_details顺序删除
\ No newline at end of file
eclipse.preferences.version=1
encoding//src/main/java=UTF8
encoding//src/test/java=UTF8
package com.xxl.job.controller;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.quartz.CronExpression;
import org.quartz.Job;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xxl.job.client.handler.HandlerRepository;
import com.xxl.job.core.model.ReturnT;
import com.xxl.job.core.util.DynamicSchedulerUtil;
import com.xxl.job.service.job.HttpJobBean;
/**
* index controller
......@@ -30,7 +16,6 @@ import com.xxl.job.service.job.HttpJobBean;
@Controller
public class IndexController {
@RequestMapping("")
public String index(Model model) {
List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList();
......@@ -43,138 +28,4 @@ public class IndexController {
return "job/help";
}
@RequestMapping("/job/add")
@ResponseBody
public ReturnT<String> add(HttpServletRequest request) {
String triggerKeyName = null;
String cronExpression = null;
Map<String, Object> jobData = new HashMap<String, Object>();
try {
request.setCharacterEncoding("utf-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
@SuppressWarnings("unchecked")
Set<Map.Entry<String, String[]>> paramSet = request.getParameterMap().entrySet();
for (Entry<String, String[]> param : paramSet) {
if (param.getKey().equals("triggerKeyName")) {
triggerKeyName = param.getValue()[0];
} else if (param.getKey().equals("cronExpression")) {
cronExpression = param.getValue()[0];
} else {
jobData.put(param.getKey(), param.getValue().length>0?param.getValue()[0]:param.getValue());
}
}
// triggerKeyName
if (StringUtils.isBlank(triggerKeyName)) {
return new ReturnT<String>(500, "请输入“任务key”");
}
// cronExpression
if (StringUtils.isBlank(cronExpression)) {
return new ReturnT<String>(500, "请输入“任务corn”");
}
if (!CronExpression.isValidExpression(cronExpression)) {
return new ReturnT<String>(500, "“任务corn”不合法");
}
// jobData
if (jobData.get(DynamicSchedulerUtil.job_desc)==null || jobData.get(DynamicSchedulerUtil.job_desc).toString().trim().length()==0) {
return new ReturnT<String>(500, "请输入“任务描述”");
}
if (jobData.get(DynamicSchedulerUtil.job_url)==null || jobData.get(DynamicSchedulerUtil.job_url).toString().trim().length()==0) {
return new ReturnT<String>(500, "请输入“任务URL”");
}
if (jobData.get(HandlerRepository.handleName)==null || jobData.get(HandlerRepository.handleName).toString().trim().length()==0) {
return new ReturnT<String>(500, "请输入“任务handler”");
}
// jobClass
Class<? extends Job> jobClass = HttpJobBean.class;
try {
boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, jobData);
if (!result) {
return new ReturnT<String>(500, "任务ID重复,请更换确认");
}
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
}
return ReturnT.FAIL;
}
@RequestMapping("/job/reschedule")
@ResponseBody
public ReturnT<String> reschedule(String triggerKeyName, String cronExpression) {
// triggerKeyName
if (StringUtils.isBlank(triggerKeyName)) {
return new ReturnT<String>(500, "请输入“任务key”");
}
// cronExpression
if (StringUtils.isBlank(cronExpression)) {
return new ReturnT<String>(500, "请输入“任务corn”");
}
if (!CronExpression.isValidExpression(cronExpression)) {
return new ReturnT<String>(500, "“任务corn”不合法");
}
try {
DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
}
return ReturnT.FAIL;
}
@RequestMapping("/job/remove")
@ResponseBody
public ReturnT<String> remove(String triggerKeyName) {
try {
DynamicSchedulerUtil.removeJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
@RequestMapping("/job/pause")
@ResponseBody
public ReturnT<String> pause(String triggerKeyName) {
try {
DynamicSchedulerUtil.pauseJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
@RequestMapping("/job/resume")
@ResponseBody
public ReturnT<String> resume(String triggerKeyName) {
try {
DynamicSchedulerUtil.resumeJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
@RequestMapping("/job/trigger")
@ResponseBody
public ReturnT<String> triggerJob(String triggerKeyName) {
try {
DynamicSchedulerUtil.triggerJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
}
package com.xxl.job.controller;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.quartz.CronExpression;
import org.quartz.Job;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xxl.job.client.handler.HandlerRepository;
import com.xxl.job.core.model.ReturnT;
import com.xxl.job.core.util.DynamicSchedulerUtil;
import com.xxl.job.service.job.HttpJobBean;
/**
* index controller
* @author xuxueli 2015-12-19 16:13:16
*/
@Controller
@RequestMapping("/job")
public class JobController {
@RequestMapping("/add")
@ResponseBody
public ReturnT<String> add(HttpServletRequest request) {
String triggerKeyName = null;
String cronExpression = null;
Map<String, Object> jobData = new HashMap<String, Object>();
try {
request.setCharacterEncoding("utf-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
@SuppressWarnings("unchecked")
Set<Map.Entry<String, String[]>> paramSet = request.getParameterMap().entrySet();
for (Entry<String, String[]> param : paramSet) {
if (param.getKey().equals("triggerKeyName")) {
triggerKeyName = param.getValue()[0];
} else if (param.getKey().equals("cronExpression")) {
cronExpression = param.getValue()[0];
} else {
jobData.put(param.getKey(), param.getValue().length>0?param.getValue()[0]:param.getValue());
}
}
// triggerKeyName
if (StringUtils.isBlank(triggerKeyName)) {
return new ReturnT<String>(500, "请输入“任务key”");
}
// cronExpression
if (StringUtils.isBlank(cronExpression)) {
return new ReturnT<String>(500, "请输入“任务corn”");
}
if (!CronExpression.isValidExpression(cronExpression)) {
return new ReturnT<String>(500, "“任务corn”不合法");
}
// jobData
if (jobData.get(HandlerRepository.job_desc)==null || jobData.get(HandlerRepository.job_desc).toString().trim().length()==0) {
return new ReturnT<String>(500, "请输入“任务描述”");
}
if (jobData.get(HandlerRepository.job_url)==null || jobData.get(HandlerRepository.job_url).toString().trim().length()==0) {
return new ReturnT<String>(500, "请输入“任务URL”");
}
if (jobData.get(HandlerRepository.handleName)==null || jobData.get(HandlerRepository.handleName).toString().trim().length()==0) {
return new ReturnT<String>(500, "请输入“任务handler”");
}
// jobClass
Class<? extends Job> jobClass = HttpJobBean.class;
try {
boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, jobData);
if (!result) {
return new ReturnT<String>(500, "任务ID重复,请更换确认");
}
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
}
return ReturnT.FAIL;
}
@RequestMapping("/reschedule")
@ResponseBody
public ReturnT<String> reschedule(String triggerKeyName, String cronExpression) {
// triggerKeyName
if (StringUtils.isBlank(triggerKeyName)) {
return new ReturnT<String>(500, "请输入“任务key”");
}
// cronExpression
if (StringUtils.isBlank(cronExpression)) {
return new ReturnT<String>(500, "请输入“任务corn”");
}
if (!CronExpression.isValidExpression(cronExpression)) {
return new ReturnT<String>(500, "“任务corn”不合法");
}
try {
DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
}
return ReturnT.FAIL;
}
@RequestMapping("/remove")
@ResponseBody
public ReturnT<String> remove(String triggerKeyName) {
try {
DynamicSchedulerUtil.removeJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
@RequestMapping("/pause")
@ResponseBody
public ReturnT<String> pause(String triggerKeyName) {
try {
DynamicSchedulerUtil.pauseJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
@RequestMapping("/resume")
@ResponseBody
public ReturnT<String> resume(String triggerKeyName) {
try {
DynamicSchedulerUtil.resumeJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
@RequestMapping("/trigger")
@ResponseBody
public ReturnT<String> triggerJob(String triggerKeyName) {
try {
DynamicSchedulerUtil.triggerJob(triggerKeyName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
}
}
package com.xxl.job.controller;
import java.util.Date;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xxl.job.core.model.ReturnT;
import com.xxl.job.core.model.XxlJobLog;
import com.xxl.job.dao.IXxlJobLogDao;
/**
* index controller
* @author xuxueli 2015-12-19 16:13:16
*/
@Controller
@RequestMapping("/joblog")
public class JobLogController {
@Resource
public IXxlJobLogDao xxlJobLogDao;
@RequestMapping("/save")
@ResponseBody
public ReturnT<String> triggerLog(int triggerLogId, String status, String msg) {
XxlJobLog log = xxlJobLogDao.load(triggerLogId);
if (log!=null) {
log.setHandleTime(new Date());
log.setHandleStatus(status);
log.setHandleMsg(msg);
xxlJobLogDao.updateHandleInfo(log);
return ReturnT.SUCCESS;
}
return ReturnT.FAIL;
}
}
......@@ -8,28 +8,52 @@ import java.util.Date;
*/
public class XxlJobLog {
private String jobTriggerUuid;
private String jobHandleName;
private int id;
// job info
private String jobName;
private String jobCron;
private String jobClass;
private String jobData;
// trigger info
private Date triggerTime;
private String triggerStatus;
private String triggerDetailLog;
private String triggerMsg;
// handle info
private Date handleTime;
private String handleStatus;
private String handleDetailLog;
private String handleMsg;
public String getJobTriggerUuid() {
return jobTriggerUuid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobCron() {
return jobCron;
}
public void setJobCron(String jobCron) {
this.jobCron = jobCron;
}
public String getJobClass() {
return jobClass;
}
public void setJobTriggerUuid(String jobTriggerUuid) {
this.jobTriggerUuid = jobTriggerUuid;
public void setJobClass(String jobClass) {
this.jobClass = jobClass;
}
public String getJobHandleName() {
return jobHandleName;
public String getJobData() {
return jobData;
}
public void setJobHandleName(String jobHandleName) {
this.jobHandleName = jobHandleName;
public void setJobData(String jobData) {
this.jobData = jobData;
}
public Date getTriggerTime() {
return triggerTime;
......@@ -43,11 +67,11 @@ public class XxlJobLog {
public void setTriggerStatus(String triggerStatus) {
this.triggerStatus = triggerStatus;
}
public String getTriggerDetailLog() {
return triggerDetailLog;
public String getTriggerMsg() {
return triggerMsg;
}
public void setTriggerDetailLog(String triggerDetailLog) {
this.triggerDetailLog = triggerDetailLog;
public void setTriggerMsg(String triggerMsg) {
this.triggerMsg = triggerMsg;
}
public Date getHandleTime() {
return handleTime;
......@@ -61,19 +85,19 @@ public class XxlJobLog {
public void setHandleStatus(String handleStatus) {
this.handleStatus = handleStatus;
}
public String getHandleDetailLog() {
return handleDetailLog;
public String getHandleMsg() {
return handleMsg;
}
public void setHandleDetailLog(String handleDetailLog) {
this.handleDetailLog = handleDetailLog;
public void setHandleMsg(String handleMsg) {
this.handleMsg = handleMsg;
}
@Override
public String toString() {
return "XxlJobLog [jobTriggerUuid=" + jobTriggerUuid + ", jobHandleName=" + jobHandleName
+ ", triggerTime=" + triggerTime + ", triggerStatus=" + triggerStatus + ", triggerDetailLog="
+ triggerDetailLog + ", handleTime=" + handleTime + ", handleStatus=" + handleStatus
+ ", handleDetailLog=" + handleDetailLog + "]";
return "XxlJobLog [id=" + id + ", jobName=" + jobName + ", jobCron=" + jobCron + ", jobClass=" + jobClass
+ ", jobData=" + jobData + ", triggerTime=" + triggerTime + ", triggerStatus=" + triggerStatus
+ ", triggerMsg=" + triggerMsg + ", handleTime=" + handleTime + ", handleStatus=" + handleStatus
+ ", handleMsg=" + handleMsg + "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="XxlJobLogMapper">
<resultMap id="XxlJobLog" type="com.xxl.job.core.model.XxlJobLog" >
<result column="id" property="id" />
<result column="job_name" property="jobName" />
<result column="job_cron" property="jobCron" />
<result column="job_class" property="jobClass" />
<result column="job_data" property="jobData" />
<result column="trigger_time" property="triggerTime" />
<result column="trigger_status" property="triggerStatus" />
<result column="trigger_msg" property="triggerMsg" />
<result column="handle_time" property="handleTime" />
<result column="handle_status" property="handleStatus" />
<result column="handle_msg" property="handleMsg" />
</resultMap>
<sql id="Base_Column_List">
t.id,
t.job_name,
t.job_cron,
t.job_class,
t.job_data,
t.trigger_time,
t.trigger_status,
t.trigger_msg,
t.handle_time,
t.handle_status,
t.handle_msg
</sql>
<insert id="save" parameterType="com.xxl.job.core.model.XxlJobLog" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO `qrtz_trigger_log` (
`job_name`,
`job_cron`,
`job_class`,
`job_data`
) VALUES (
#{jobName},
#{jobCron},
#{jobClass},
#{jobData}
);
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
<select id="load" parameterType="java.lang.Integer" resultMap="XxlJobLog">
SELECT <include refid="Base_Column_List" />
FROM qrtz_trigger_log AS t
WHERE t.id = #{id}
</select>
<update id="updateTriggerInfo">
UPDATE `qrtz_trigger_log`
SET
`trigger_time`= #{triggerTime},
`trigger_status`= #{triggerStatus},
`trigger_msg`= #{triggerMsg}
WHERE `id`= #{id}
</update>
<update id="updateHandleInfo">
UPDATE `qrtz_trigger_log`
SET
`handle_time`= #{handleTime},
`handle_status`= #{handleStatus},
`handle_msg`= #{handleMsg}
WHERE `id`= #{id}
</update>
<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobLog">
SELECT <include refid="Base_Column_List" />
FROM qrtz_trigger_log AS t
<if test="jobName != null and jobName!=''">
WHERE t.job_name = #{jobName}
</if>
LIMIT #{offset}, #{pagesize}
</select>
<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
SELECT count(1)
FROM qrtz_trigger_log AS t
<if test="jobName != null and jobName!=''">
WHERE t.job_name = #{jobName}
</if>
</select>
</mapper>
\ No newline at end of file
......@@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
......@@ -26,6 +28,8 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import com.xxl.job.dao.IXxlJobLogDao;
/**
* base quartz scheduler util
* @author xuxueli 2015-12-19 16:13:53
......@@ -33,6 +37,16 @@ import org.springframework.util.Assert;
public final class DynamicSchedulerUtil implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(DynamicSchedulerUtil.class);
// xxlJobLogDao
public static IXxlJobLogDao xxlJobLogDao;
@Resource
public void setXxlJobLogDao(IXxlJobLogDao xxlJobLogDao) {
DynamicSchedulerUtil.xxlJobLogDao = xxlJobLogDao;
}
public static IXxlJobLogDao getXxlJobLogDao() {
return xxlJobLogDao;
}
// Scheduler
private static Scheduler scheduler;
public static void setScheduler(Scheduler scheduler) {
......@@ -77,8 +91,6 @@ public final class DynamicSchedulerUtil implements InitializingBean {
return jobList;
}
public static final String job_desc = "job_desc";
public static final String job_url = "job_url";
// addJob 新增
public static boolean addJob(String triggerKeyName, String cronExpression, Class<? extends Job> jobClass, Map<String, Object> jobData) throws SchedulerException {
// TriggerKey : name + group
......
package com.xxl.job.core.util;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* properties util
* @author xuxueli 2015-8-28 10:35:53
*/
public class PropertiesUtil {
private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
private static final String file_name = "config.properties";
/**
* load properties
* @param propertyFileName
* @param ifClassPath
* @return
*/
public static Properties loadProperties(String propertyFileName) {
Properties prop = new Properties();
InputStreamReader in = null;
try {
URL url = null;
ClassLoader loder = Thread.currentThread().getContextClassLoader();
url = loder.getResource(propertyFileName);
in = new InputStreamReader(new FileInputStream(url.getPath()), "UTF-8");
prop.load(in);
} catch (IOException e) {
logger.error("load {} error!", propertyFileName);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
logger.error("close {} error!", propertyFileName);
}
}
}
return prop;
}
public static String getString(String key) {
Properties prop = loadProperties(file_name);
if (prop!=null) {
return prop.getProperty(key);
}
return null;
}
public static void main(String[] args) {
System.out.println(getString("triggerLogUrl"));
}
}
package com.xxl.job.dao;
import java.util.List;
import com.xxl.job.core.model.XxlJobLog;
public interface IXxlJobLogDao {
public int save(XxlJobLog xxlJobLog);
public XxlJobLog load(int id);
public int updateTriggerInfo(XxlJobLog xxlJobLog);
public int updateHandleInfo(XxlJobLog xxlJobLog);
public List<XxlJobLog> pageList(int offset, int pagesize,String jobName);
public int pageListCount(int offset, int pagesize,String jobName);
}
package com.xxl.job.dao.impl;
import java.util.HashMap;
import java.util.List;
import javax.annotation.Resource;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import com.xxl.job.core.model.XxlJobLog;
import com.xxl.job.dao.IXxlJobLogDao;
@Repository
public class XxlJobLogDaoImpl implements IXxlJobLogDao {
@Resource
public SqlSessionTemplate sqlSessionTemplate;
@Override
public int save(XxlJobLog xxlJobLog) {
return sqlSessionTemplate.insert("XxlJobLogMapper.save", xxlJobLog);
}
@Override
public XxlJobLog load(int id) {
return sqlSessionTemplate.selectOne("XxlJobLogMapper.load", id);
}
@Override
public int updateTriggerInfo(XxlJobLog xxlJobLog) {
return sqlSessionTemplate.update("XxlJobLogMapper.updateTriggerInfo", xxlJobLog);
}
@Override
public int updateHandleInfo(XxlJobLog xxlJobLog) {
return sqlSessionTemplate.update("XxlJobLogMapper.updateHandleInfo", xxlJobLog);
}
@Override
public List<XxlJobLog> pageList(int offset, int pagesize, String jobName) {
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("offset", offset);
params.put("pagesize", pagesize);
params.put("jobName", jobName);
return sqlSessionTemplate.selectList("XxlJobLogMapper.pageList", params);
}
@Override
public int pageListCount(int offset, int pagesize, String jobName) {
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("offset", offset);
params.put("pagesize", pagesize);
params.put("jobName", jobName);
return sqlSessionTemplate.selectOne("XxlJobLogMapper.pageListCount", params);
}
}
package com.xxl.job.service;
/**
* local trigger, only exists in local jvm
* @author xuxueli 2015-12-17 17:29:23
*/
public interface ITriggerService {
public void beat();
}
package com.xxl.job.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.xxl.job.service.ITriggerService;
/**
* local trigger, only exists in local jvm
* @author xuxueli 2015-12-17 17:31:24
*/
@Service("triggerService")
public class TriggerServiceImpl implements ITriggerService {
private static transient Logger logger = LoggerFactory.getLogger(TriggerServiceImpl.class);
public void beat() {
logger.info(">>>>>>>>>>> xxl-job beat success.");
}
}
package com.xxl.job.service.job;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
......@@ -28,9 +13,11 @@ import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
import com.xxl.job.client.handler.HandlerRepository;
import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
import com.xxl.job.client.util.HttpUtil;
import com.xxl.job.client.util.JacksonUtil;
import com.xxl.job.core.model.XxlJobLog;
import com.xxl.job.core.util.DynamicSchedulerUtil;
import com.xxl.job.core.util.PropertiesUtil;
/**
* http job bean
......@@ -43,11 +30,9 @@ public class HttpJobBean extends QuartzJobBean {
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
String triggerKey = context.getTrigger().getKey().getName();
String triggerGroup = context.getTrigger().getKey().getGroup();
Map<String, Object> jobDataMap = context.getMergedJobDataMap().getWrappedMap();
String triggerKey = context.getTrigger().getJobKey().getName();
// jobDataMap 2 params
Map<String, Object> jobDataMap = context.getMergedJobDataMap().getWrappedMap();
Map<String, String> params = new HashMap<String, String>();
if (jobDataMap!=null && jobDataMap.size()>0) {
for (Entry<String, Object> item : jobDataMap.entrySet()) {
......@@ -55,83 +40,41 @@ public class HttpJobBean extends QuartzJobBean {
}
}
String job_url = params.get(DynamicSchedulerUtil.job_url);
triggerPost(job_url, params);
logger.info(">>>>>>>>>>> xxl-job run :jobId:{}, group:{}, jobDataMap:{}",
new Object[]{triggerKey, triggerGroup, jobDataMap});
}
public static void triggerPost(String reqURL, Map<String, String> params){
// save log
XxlJobLog jobLog = new XxlJobLog();
jobLog.setJobTriggerUuid(UUID.randomUUID().toString());
jobLog.setJobHandleName(params.get(HandlerRepository.handleName));
jobLog.setTriggerTime(new Date());
logger.info(">>>>>>>>>>> xxl-job trigger start :jobLog:{}", jobLog);
jobLog.setJobName(triggerKey);
jobLog.setJobCron(null);
jobLog.setJobClass(HttpJobBean.class.getName());
jobLog.setJobData(JacksonUtil.writeValueAsString(params));
DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
// post
String responseContent = null;
HttpPost httpPost = new HttpPost(reqURL);
CloseableHttpClient httpClient = HttpClients.createDefault();
try{
if (params != null && !params.isEmpty()) {
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
for(Map.Entry<String,String> entry : params.entrySet()){
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
}
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
httpPost.setConfig(requestConfig);
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (null != entity) {
responseContent = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
}
logger.info(">>>>>>>>>>> xxl-job trigger ing :jobLog:{}, response:{}, responseContent:{}", jobLog, response, responseContent);
} catch (Exception e) {
e.printStackTrace();
StringWriter out = new StringWriter();
e.printStackTrace(new PrintWriter(out));
responseContent = out.toString();
} finally{
httpPost.releaseConnection();
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
// update trigger status
if (responseContent!=null && responseContent.equals(JobTriggerStatus.SUCCESS.name())) {
jobLog.setTriggerStatus(JobTriggerStatus.SUCCESS.name());
} else {
jobLog.setTriggerStatus(JobTriggerStatus.FAIL.name());
}
jobLog.setTriggerDetailLog(responseContent);
if (jobLog.getTriggerDetailLog()!=null && jobLog.getTriggerDetailLog().length()>1000) {
jobLog.setTriggerDetailLog(jobLog.getTriggerDetailLog().substring(0, 1000));
// trigger request
params.put(HandlerRepository.triggerLogId, String.valueOf(jobLog.getId()));
params.put(HandlerRepository.triggerLogUrl, PropertiesUtil.getString(HandlerRepository.triggerLogUrl));
String[] postResp = HttpUtil.post(params.get(HandlerRepository.job_url), params);
logger.info(">>>>>>>>>>> xxl-job trigger http response, jobLog.id:{}, jobLog:{}", jobLog.getId(), jobLog);
// parse trigger response
String responseMsg = postResp[0];
String exceptionMsg = postResp[1];
jobLog.setTriggerTime(new Date());
jobLog.setTriggerStatus(HttpUtil.FAIL);
jobLog.setTriggerMsg(exceptionMsg);
if (StringUtils.isNotBlank(responseMsg)) {
@SuppressWarnings("unchecked")
Map<String, String> responseMap = JacksonUtil.readValue(responseMsg, Map.class);
if (responseMap!=null && StringUtils.isNotBlank(responseMap.get(HttpUtil.status))) {
jobLog.setTriggerStatus(responseMap.get(HttpUtil.status));
jobLog.setTriggerMsg(responseMap.get(HttpUtil.msg));
}
logger.info(">>>>>>>>>>> xxl-job trigger end :jobLog:{}", jobLog);
}
}
public static void main(String[] args) {
String url = "http://localhost:8080/xxl-job-client-demo/xxlJobServlet";
// update trigger info
DynamicSchedulerUtil.xxlJobLogDao.updateTriggerInfo(jobLog);
logger.info(">>>>>>>>>>> xxl-job trigger end, jobLog.id:{}, jobLog:{}", jobLog.getId(), jobLog);
for (int i = 0; i < 3; i++) {
Map<String, String> params = new HashMap<String, String>();
params.put(HandlerRepository.handleName, "com.xxl.job.service.handler.DemoJobHandler");
params.put(HandlerRepository.triggerUuid, i+"");
params.put("key", i+"");
triggerPost(url, params);
}
}
}
}
\ No newline at end of file
......@@ -10,7 +10,7 @@
http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config />
<context:component-scan base-package="com.xxl.job.service" />
<context:component-scan base-package="com.xxl.job.service, com.xxl.job.dao" />
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/template/" />
......
......@@ -31,7 +31,7 @@
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:com/xxl/core/model/mapper/*.xml"/>
<property name="mapperLocations" value="classpath*:com/xxl/job/core/model/mapper/*.xml"/>
</bean>
<!-- scope must be "prototype" when junit -->
......
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="beatJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="triggerService" />
<property name="targetMethod" value="beat" />
<property name="concurrent" value="false" />
</bean>
<bean id="beatTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="beatJobDetail" />
<property name="cronExpression" value="0/10 * * * * ? *" />
</bean>
<!-- 进程-调度器 -->
<bean name="jvmQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!-- <ref bean="beatTrigger" /> -->
</list>
</property>
</bean>
</beans>
triggerLogUrl=http://localhost:8080/xxl-job-admin/joblog/save
\ No newline at end of file
package com.xxl.job.dao.impl;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.xxl.job.client.handler.IJobHandler;
import com.xxl.job.client.util.HttpUtil;
import com.xxl.job.core.model.XxlJobLog;
import com.xxl.job.dao.IXxlJobLogDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:applicationcontext-*.xml")
public class XxlJobLogTest {
@Resource
private IXxlJobLogDao xxlJobLogDao;
@Test
public void save_load(){
XxlJobLog xxlJobLog = new XxlJobLog();
xxlJobLog.setJobName("job_name");
xxlJobLog.setJobCron("jobCron");
xxlJobLog.setJobClass("jobClass");
xxlJobLog.setJobData("jobData");
int count = xxlJobLogDao.save(xxlJobLog);
System.out.println(count);
System.out.println(xxlJobLog.getId());
XxlJobLog item = xxlJobLogDao.load(xxlJobLog.getId());
System.out.println(item);
}
@Test
public void updateTriggerInfo(){
XxlJobLog xxlJobLog = xxlJobLogDao.load(29);
xxlJobLog.setTriggerTime(new Date());
xxlJobLog.setTriggerStatus(HttpUtil.SUCCESS);
xxlJobLog.setTriggerMsg("trigger msg");
xxlJobLogDao.updateTriggerInfo(xxlJobLog);
}
@Test
public void updateHandleInfo(){
XxlJobLog xxlJobLog = xxlJobLogDao.load(29);
xxlJobLog.setHandleTime(new Date());
xxlJobLog.setHandleStatus(IJobHandler.JobHandleStatus.SUCCESS.name());
xxlJobLog.setHandleMsg("handle msg");
xxlJobLogDao.updateHandleInfo(xxlJobLog);
}
@Test
public void pageList(){
List<XxlJobLog> list = xxlJobLogDao.pageList(0, 20, null);
int list_count = xxlJobLogDao.pageListCount(0, 20, null);
System.out.println(list);
System.out.println(list_count);
}
}
......@@ -2,6 +2,7 @@ package com.xxl.job.client.handler;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
......@@ -11,7 +12,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.xxl.job.client.handler.IJobHandler.JobHandleStatus;
import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
import com.xxl.job.client.util.HttpUtil;
import com.xxl.job.client.util.JacksonUtil;
/**
......@@ -21,8 +23,11 @@ import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
public class HandlerRepository {
private static Logger logger = LoggerFactory.getLogger(HandlerRepository.class);
public static final String triggerUuid = "triggerUuid";
public static final String job_desc = "job_desc";
public static final String job_url = "job_url";
public static final String handleName = "handleName";
public static final String triggerLogId = "triggerLogId";
public static final String triggerLogUrl = "triggerLogUrl";
// handler class map
private static ConcurrentHashMap<String, IJobHandler> handlerClassMap = new ConcurrentHashMap<String, IJobHandler>();
......@@ -57,23 +62,36 @@ public class HandlerRepository {
public void run() {
while (isValid) {
LinkedBlockingQueue<Map<String, String>> handlerDateQueue = handlerDataQueueMap.get(_handleName);
Map<String, String> handlerDate = handlerDateQueue.poll();
if (handlerDate!=null) {
JobHandleStatus jobHandleStatus = null;
String jobHandleDetail = null;
Map<String, String> handlerData = handlerDateQueue.poll();
if (handlerData!=null) {
// handle job
JobHandleStatus _status = JobHandleStatus.FAIL;
String _msg = null;
try {
IJobHandler handler = handlerClassMap.get(_handleName);
jobHandleStatus = handler.handle(handlerDate);
_status = handler.handle(handlerData);
} catch (Exception e) {
e.printStackTrace();
jobHandleStatus = JobHandleStatus.FAIL;
_status = JobHandleStatus.FAIL;
StringWriter out = new StringWriter();
e.printStackTrace(new PrintWriter(out));
jobHandleDetail = out.toString();
_msg = out.toString();
}
String _triggerUuid = handlerDate.get(triggerUuid);
logger.info("<<<<<<<<<<< xxl-job thread handle, _triggerUuid:{}, _handleName:{}, jobHandleStatus:{}, jobHandleDetail:{}, thread:{}",
new Object[]{_triggerUuid, _handleName, jobHandleStatus, jobHandleDetail, this});
// callback handler info
String callback_response[] = null;
try {
String _triggerLogUrl = handlerData.get(HandlerRepository.triggerLogUrl);
HashMap<String, String> params = new HashMap<String, String>();
params.put(HandlerRepository.triggerLogId, handlerData.get(HandlerRepository.triggerLogId));
params.put(HttpUtil.status, _status.name());
params.put(HttpUtil.msg, _msg);
callback_response = HttpUtil.post(_triggerLogUrl, params);
} catch (Exception e) {
e.printStackTrace();
}
logger.info("<<<<<<<<<<< xxl-job thread handle, handlerData:{}, callback_status:{}, callback_msg:{}, callback_response:{}, thread:{}",
new Object[]{handlerData, _status, _msg, callback_response, this});
} else {
try {
TimeUnit.SECONDS.sleep(3);
......@@ -86,51 +104,56 @@ public class HandlerRepository {
}
// handler push to queue
public static String pushHandleQueue(String triggerUuid, String handleName, Map<String, String> _param) {
JobTriggerStatus _triggerStatus = JobTriggerStatus.FAIL;
String _triggerDetailLog = null;
public static String pushHandleQueue(Map<String, String> _param) {
// resuolt
String _status = HttpUtil.FAIL;
String _msg = "";
// push data to queue
String _handleName = _param.get(HandlerRepository.handleName);
int _triggerLogId = Integer.valueOf(_param.get(HandlerRepository.triggerLogId));
try {
if (handleName!=null && handleName.trim().length()>0) {
IJobHandler handler = handlerClassMap.get(handleName);
if (_handleName!=null && _handleName.trim().length()>0) {
IJobHandler handler = handlerClassMap.get(_handleName);
if (handler != null) {
// push data to handler queue
LinkedBlockingQueue<Map<String, String>> handlerDateQueue = handlerDataQueueMap.get(handleName);
LinkedBlockingQueue<Map<String, String>> handlerDateQueue = handlerDataQueueMap.get(_handleName);
if (handlerDateQueue == null) {
handlerDateQueue = new LinkedBlockingQueue<Map<String, String>>();
handlerDataQueueMap.put(handleName, handlerDateQueue);
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh handlerDateQueue, handleName:{}, handler:{}, handlerDateQueue:{}",
new Object[]{handleName, handler, handlerDateQueue});
handlerDataQueueMap.put(_handleName, handlerDateQueue);
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh handlerDateQueue, _handleName:{}, handler:{}, handlerDateQueue:{}",
new Object[]{_handleName, handler, handlerDateQueue});
}
handlerDateQueue.offer(_param);
// check handler thread
HandlerThread handlerThreadOld = handlerTreadMap.get(handleName);
HandlerThread handlerThreadOld = handlerTreadMap.get(_handleName);
if (!handlerThreadOld.isAlive()) {
handlerThreadOld.stopThread();
HandlerThread handlerThread = new HandlerThread(handleName);
HandlerThread handlerThread = new HandlerThread(_handleName);
handlerThread.start();
handlerTreadMap.put(handleName, handlerThread);
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh thread, handleName:{}, handler:{}, handlerThread:{}",
new Object[]{handleName, handler, handlerThread});
handlerTreadMap.put(_handleName, handlerThread);
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh thread, _handleName:{}, handler:{}, handlerThread:{}",
new Object[]{_handleName, handler, handlerThread});
}
_triggerStatus = JobTriggerStatus.SUCCESS;
// push to queue
handlerDateQueue.offer(_param);
_status = HttpUtil.SUCCESS;
}
}
} catch (Exception e) {
e.printStackTrace();
_triggerStatus = JobTriggerStatus.FAIL;
StringWriter out = new StringWriter();
e.printStackTrace(new PrintWriter(out));
_triggerDetailLog = out.toString();
_status = HttpUtil.FAIL;
_msg = out.toString();
}
logger.info(">>>>>>>>>>> xxl-job pushHandleQueue, triggerUuid:{}, handleName, _triggerStatus:{}, _triggerDetailLog",
new Object[]{triggerUuid, handleName, _triggerStatus, _triggerDetailLog});
logger.info(">>>>>>>>>>> xxl-job pushHandleQueue, _handleName:{}, _triggerLogId:{}, _param:{}, _status:{}, _msg:{}",
new Object[]{_handleName, _triggerLogId, _param, _status, _msg});
HashMap<String, String> triggerData = new HashMap<String, String>();
triggerData.put(HttpUtil.status, _status);
triggerData.put(HttpUtil.msg, _msg);
return JacksonUtil.writeValueAsString(triggerData);
String responseBody = _triggerStatus.name();
if (JobTriggerStatus.SUCCESS != _triggerStatus) {
responseBody += "#" + _triggerDetailLog;
}
return responseBody;
/**
* trigger-log :
* trigger side : store trigger-info >> trigger request >> update trigger-response-status
......
......@@ -32,15 +32,4 @@ public abstract class IJobHandler extends HandlerRepository{
NOT_FOUND;
}
public enum JobTriggerStatus{
/**
* trigger success
*/
SUCCESS,
/**
* trigger fail
*/
FAIL;
}
}
......@@ -43,10 +43,8 @@ public class XxlJobServlet extends HttpServlet {
}
}
}
String _triggerUuid = _param.get(HandlerRepository.triggerUuid);
String _handleName = _param.get(HandlerRepository.handleName);
String resp = HandlerRepository.pushHandleQueue(_triggerUuid, _handleName, _param);
String resp = HandlerRepository.pushHandleQueue(_param);
response.getWriter().append(resp);
return;
}
......
package com.xxl.job.client.util;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
* http util to send hex data
* http util to send data
* @author xuxueli
* @version 2015-11-28 15:30:59
*/
public class HttpUtil {
public static String sendHex(String reqURL, String queryString) {
String responseContent = null;
if (queryString != null && !queryString.equals("")) {
reqURL = reqURL + "?data=" + queryString;
}
HttpGet httpGet = new HttpGet(reqURL);
// response param
public static final String status = "status";
public static final String msg = "msg";
// response status enum
public static final String SUCCESS = "SUCCESS";
public static final String FAIL = "FAIL";
/**
* http post request
* @param reqURL
* @param params
* @return [0]=responseMsg, [1]=exceptionMsg
*/
public static String[] post(String reqURL, Map<String, String> params){
String responseMsg = null;
String exceptionMsg = null;
// do post
HttpPost httpPost = new HttpPost(reqURL);
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(3000).setConnectTimeout(3000).build();
httpGet.setConfig(requestConfig);
HttpResponse response = httpClient.execute(httpGet);
try{
if (params != null && !params.isEmpty()) {
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
for(Map.Entry<String,String> entry : params.entrySet()){
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
}
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
httpPost.setConfig(requestConfig);
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (null != entity) {
responseContent = EntityUtils.toString(entity, "UTF-8");
responseMsg = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
if (responseContent!=null) {
responseContent = responseContent.trim();
}
}
} catch (ClientProtocolException e) {
} catch (Exception e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpGet.releaseConnection();
StringWriter out = new StringWriter();
e.printStackTrace(new PrintWriter(out));
exceptionMsg = out.toString();
} finally{
httpPost.releaseConnection();
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseContent;
String[] result = new String[2];
result[0] = responseMsg;
result[1] = exceptionMsg;
return result;
}
}
package com.xxl.job.client.util;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
/**
* Jackson util
*
* 1、obj need private and set/get;
* 2、do not support inner class;
*
* @author xuxueli 2015-9-25 18:02:56
*/
public class JacksonUtil {
private final static ObjectMapper objectMapper = new ObjectMapper();
public static ObjectMapper getInstance() {
return objectMapper;
}
/**
* bean、array、List、Map --> json
*
* @param obj
* @return
* @throws Exception
*/
public static String writeValueAsString(Object obj) {
try {
return getInstance().writeValueAsString(obj);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* string --> bean、Map、List(array)
*
* @param jsonStr
* @param clazz
* @return
* @throws Exception
*/
public static <T> T readValue(String jsonStr, Class<T> clazz) {
try {
return getInstance().readValue(jsonStr, clazz);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static <T> T readValueRefer(String jsonStr, Class<T> clazz) {
try {
return getInstance().readValue(jsonStr, new TypeReference<T>() { });
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
try {
Map<String, String> map = new HashMap<String, String>();
map.put("aaa", "111");
map.put("bbb", "222");
String json = writeValueAsString(map);
System.out.println(json);
System.out.println(readValue(json, Map.class));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册