xueli.xue преди 9 години
родител
ревизия
87ce15368e
променени са 25 файла, в които са добавени 822 реда и са изтрити 413 реда
  1. 3 0
      README.md
  2. 1 0
      xxl-job-admin/.gitignore
  3. 1 0
      xxl-job-admin/.settings/org.eclipse.core.resources.prefs
  4. 0 149
      xxl-job-admin/src/main/java/com/xxl/job/controller/IndexController.java
  5. 166 0
      xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java
  6. 40 0
      xxl-job-admin/src/main/java/com/xxl/job/controller/JobLogController.java
  7. 48 24
      xxl-job-admin/src/main/java/com/xxl/job/core/model/XxlJobLog.java
  8. 95 0
      xxl-job-admin/src/main/java/com/xxl/job/core/model/mapper/XxlJobLogMapper.xml
  9. 14 2
      xxl-job-admin/src/main/java/com/xxl/job/core/util/DynamicSchedulerUtil.java
  10. 61 0
      xxl-job-admin/src/main/java/com/xxl/job/core/util/PropertiesUtil.java
  11. 22 0
      xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java
  12. 58 0
      xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java
  13. 0 11
      xxl-job-admin/src/main/java/com/xxl/job/service/ITriggerService.java
  14. 0 21
      xxl-job-admin/src/main/java/com/xxl/job/service/impl/TriggerServiceImpl.java
  15. 36 93
      xxl-job-admin/src/main/java/com/xxl/job/service/job/HttpJobBean.java
  16. 1 1
      xxl-job-admin/src/main/resources/applicationcontext-base.xml
  17. 1 1
      xxl-job-admin/src/main/resources/applicationcontext-database.xml
  18. 0 32
      xxl-job-admin/src/main/resources/applicationcontext-trigger-local.xml
  19. 1 0
      xxl-job-admin/src/main/resources/config.properties
  20. 67 0
      xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobLogTest.java
  21. 60 37
      xxl-job-client/src/main/java/com/xxl/job/client/handler/HandlerRepository.java
  22. 0 11
      xxl-job-client/src/main/java/com/xxl/job/client/handler/IJobHandler.java
  23. 1 3
      xxl-job-client/src/main/java/com/xxl/job/client/netcom/http/XxlJobServlet.java
  24. 53 28
      xxl-job-client/src/main/java/com/xxl/job/client/util/HttpUtil.java
  25. 93 0
      xxl-job-client/src/main/java/com/xxl/job/client/util/JacksonUtil.java

+ 3 - 0
README.md

@@ -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顺序删除
+	

+ 1 - 0
xxl-job-admin/.gitignore

@@ -1 +1,2 @@
 /target/
+/.settings/

+ 1 - 0
xxl-job-admin/.settings/org.eclipse.core.resources.prefs

@@ -1,2 +1,3 @@
 eclipse.preferences.version=1
 encoding//src/main/java=UTF8
+encoding//src/test/java=UTF8

+ 0 - 149
xxl-job-admin/src/main/java/com/xxl/job/controller/IndexController.java

@@ -1,27 +1,13 @@
 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;
-		}
-	}
-	
 }

+ 166 - 0
xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java

@@ -0,0 +1,166 @@
+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;
+		}
+	}
+	
+}

+ 40 - 0
xxl-job-admin/src/main/java/com/xxl/job/controller/JobLogController.java

@@ -0,0 +1,40 @@
+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;
+	}
+	
+}

+ 48 - 24
xxl-job-admin/src/main/java/com/xxl/job/core/model/XxlJobLog.java

@@ -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 + "]";
 	}
 	
 }

+ 95 - 0
xxl-job-admin/src/main/java/com/xxl/job/core/model/mapper/XxlJobLogMapper.xml

@@ -0,0 +1,95 @@
+<?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>

+ 14 - 2
xxl-job-admin/src/main/java/com/xxl/job/core/util/DynamicSchedulerUtil.java

@@ -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

+ 61 - 0
xxl-job-admin/src/main/java/com/xxl/job/core/util/PropertiesUtil.java

@@ -0,0 +1,61 @@
+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"));
+	}
+
+}

+ 22 - 0
xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java

@@ -0,0 +1,22 @@
+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);
+	
+}

+ 58 - 0
xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java

@@ -0,0 +1,58 @@
+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);
+	}
+	
+}

+ 0 - 11
xxl-job-admin/src/main/java/com/xxl/job/service/ITriggerService.java

@@ -1,11 +0,0 @@
-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();
-	
-}

+ 0 - 21
xxl-job-admin/src/main/java/com/xxl/job/service/impl/TriggerServiceImpl.java

@@ -1,21 +0,0 @@
-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.");
-	}
-	
-}

+ 36 - 93
xxl-job-admin/src/main/java/com/xxl/job/service/job/HttpJobBean.java

@@ -1,26 +1,11 @@
 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);
-		}
-	}
+    }
+	
 }

+ 1 - 1
xxl-job-admin/src/main/resources/applicationcontext-base.xml

@@ -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/" />

+ 1 - 1
xxl-job-admin/src/main/resources/applicationcontext-database.xml

@@ -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 -->

+ 0 - 32
xxl-job-admin/src/main/resources/applicationcontext-trigger-local.xml

@@ -1,32 +0,0 @@
-<?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>

+ 1 - 0
xxl-job-admin/src/main/resources/config.properties

@@ -0,0 +1 @@
+triggerLogUrl=http://localhost:8080/xxl-job-admin/joblog/save

+ 67 - 0
xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobLogTest.java

@@ -0,0 +1,67 @@
+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);
+	}
+	
+}

+ 60 - 37
xxl-job-client/src/main/java/com/xxl/job/client/handler/HandlerRepository.java

@@ -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

+ 0 - 11
xxl-job-client/src/main/java/com/xxl/job/client/handler/IJobHandler.java

@@ -32,15 +32,4 @@ public abstract class IJobHandler extends HandlerRepository{
 		NOT_FOUND;
 	}
 	
-	public enum JobTriggerStatus{
-		/**
-		 * trigger success
-		 */
-		SUCCESS, 
-		/**
-		 * trigger fail
-		 */
-		FAIL;
-	}
-	
 }

+ 1 - 3
xxl-job-client/src/main/java/com/xxl/job/client/netcom/http/XxlJobServlet.java

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

+ 53 - 28
xxl-job-client/src/main/java/com/xxl/job/client/util/HttpUtil.java

@@ -1,59 +1,84 @@
 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;
 	}
-
 }

+ 93 - 0
xxl-job-client/src/main/java/com/xxl/job/client/util/JacksonUtil.java

@@ -0,0 +1,93 @@
+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();
+		}
+	}
+}