Преглед изворни кода

调度信息迁移至DB中

xueli.xue пре 10 година
родитељ
комит
7dfed8e62e

+ 72 - 8
xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java Прегледај датотеку

@@ -7,6 +7,7 @@ import java.util.Map;
7 7
 import java.util.Map.Entry;
8 8
 import java.util.Set;
9 9
 
10
+import javax.annotation.Resource;
10 11
 import javax.servlet.http.HttpServletRequest;
11 12
 
12 13
 import org.apache.commons.lang.StringUtils;
@@ -16,11 +17,15 @@ import org.quartz.SchedulerException;
16 17
 import org.springframework.stereotype.Controller;
17 18
 import org.springframework.ui.Model;
18 19
 import org.springframework.web.bind.annotation.RequestMapping;
20
+import org.springframework.web.bind.annotation.RequestParam;
19 21
 import org.springframework.web.bind.annotation.ResponseBody;
20 22
 
21 23
 import com.xxl.job.client.handler.HandlerRepository;
24
+import com.xxl.job.client.util.JacksonUtil;
22 25
 import com.xxl.job.core.model.ReturnT;
26
+import com.xxl.job.core.model.XxlJobInfo;
23 27
 import com.xxl.job.core.util.DynamicSchedulerUtil;
28
+import com.xxl.job.dao.IXxlJobInfoDao;
24 29
 import com.xxl.job.service.job.HttpJobBean;
25 30
 
26 31
 /**
@@ -31,19 +36,47 @@ import com.xxl.job.service.job.HttpJobBean;
31 36
 @RequestMapping("/job")
32 37
 public class JobController {
33 38
 	
39
+	@Resource
40
+	private IXxlJobInfoDao xxlJobInfoDao;
41
+	
34 42
 	@RequestMapping
35 43
 	public String index(Model model) {
36
-		List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList();
37
-		model.addAttribute("jobList", jobList);
44
+		//List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList();
45
+		//model.addAttribute("jobList", jobList);
38 46
 		return "job/index";
39 47
 	}
40 48
 	
49
+	@RequestMapping("/pageList")
50
+	@ResponseBody
51
+	public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,  
52
+			@RequestParam(required = false, defaultValue = "10") int length,
53
+			String jobName, String filterTime) {
54
+		
55
+		// page list
56
+		List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobName, null, null);
57
+		int list_count = xxlJobInfoDao.pageListCount(start, length, jobName, null, null);
58
+		
59
+		// fill job info
60
+		if (list!=null && list.size()>0) {
61
+			for (XxlJobInfo jobInfo : list) {
62
+				DynamicSchedulerUtil.fillJobInfo(jobInfo);
63
+			}
64
+		}
65
+		
66
+		// package result
67
+		Map<String, Object> maps = new HashMap<String, Object>();
68
+	    maps.put("recordsTotal", list_count);		// 总记录数
69
+	    maps.put("recordsFiltered", list_count);	// 过滤后的总记录数
70
+	    maps.put("data", list);  					// 分页列表
71
+		return maps;
72
+	}
73
+	
41 74
 	@RequestMapping("/add")
42 75
 	@ResponseBody
43 76
 	public ReturnT<String> add(HttpServletRequest request) {
44 77
 		String triggerKeyName = null;
45 78
 		String cronExpression = null;
46
-		Map<String, Object> jobData = new HashMap<String, Object>();
79
+		Map<String, String> jobData = new HashMap<String, String>();
47 80
 		
48 81
 		try {
49 82
 			request.setCharacterEncoding("utf-8");
@@ -58,7 +91,7 @@ public class JobController {
58 91
 			} else if (param.getKey().equals("cronExpression")) {
59 92
 				cronExpression = param.getValue()[0];
60 93
 			} else {
61
-				jobData.put(param.getKey(), param.getValue().length>0?param.getValue()[0]:param.getValue());
94
+				jobData.put(param.getKey(), (String) (param.getValue().length>0?param.getValue()[0]:param.getValue()));
62 95
 			}
63 96
 		}
64 97
 		
@@ -90,10 +123,19 @@ public class JobController {
90 123
 		Class<? extends Job> jobClass = HttpJobBean.class;
91 124
 		
92 125
 		try {
93
-			boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, jobData);
126
+			// add job 2 quartz
127
+			boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, null);
94 128
 			if (!result) {
95 129
 				return new ReturnT<String>(500, "任务ID重复,请更换确认");
96 130
 			}
131
+			// Backup to the database
132
+			XxlJobInfo jobInfo = new XxlJobInfo();
133
+			jobInfo.setJobName(triggerKeyName);
134
+			jobInfo.setJobCron(cronExpression);
135
+			jobInfo.setJobClass(jobClass.getName());
136
+			jobInfo.setJobData(JacksonUtil.writeValueAsString(jobData));
137
+			xxlJobInfoDao.save(jobInfo);
138
+			
97 139
 			return ReturnT.SUCCESS;
98 140
 		} catch (SchedulerException e) {
99 141
 			e.printStackTrace();
@@ -117,6 +159,13 @@ public class JobController {
117 159
 		}
118 160
 		try {
119 161
 			DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression);
162
+			
163
+			// update
164
+			XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName);
165
+			if (jobInfo!=null) {
166
+				jobInfo.setJobCron(cronExpression);
167
+				xxlJobInfoDao.update(jobInfo);
168
+			}
120 169
 			return ReturnT.SUCCESS;
121 170
 		} catch (SchedulerException e) {
122 171
 			e.printStackTrace();
@@ -128,12 +177,15 @@ public class JobController {
128 177
 	@ResponseBody
129 178
 	public ReturnT<String> remove(String triggerKeyName) {
130 179
 		try {
131
-			DynamicSchedulerUtil.removeJob(triggerKeyName);
132
-			return ReturnT.SUCCESS;
180
+			if (triggerKeyName!=null) {
181
+				DynamicSchedulerUtil.removeJob(triggerKeyName);
182
+				xxlJobInfoDao.delete(triggerKeyName);
183
+				return ReturnT.SUCCESS;
184
+			}
133 185
 		} catch (SchedulerException e) {
134 186
 			e.printStackTrace();
135
-			return ReturnT.FAIL;
136 187
 		}
188
+		return ReturnT.FAIL;
137 189
 	}
138 190
 	
139 191
 	@RequestMapping("/pause")
@@ -141,6 +193,12 @@ public class JobController {
141 193
 	public ReturnT<String> pause(String triggerKeyName) {
142 194
 		try {
143 195
 			DynamicSchedulerUtil.pauseJob(triggerKeyName);
196
+			// update
197
+			XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName);
198
+			if (jobInfo!=null) {
199
+				jobInfo.setJobStatus("PAUSED");
200
+				xxlJobInfoDao.update(jobInfo);
201
+			}
144 202
 			return ReturnT.SUCCESS;
145 203
 		} catch (SchedulerException e) {
146 204
 			e.printStackTrace();
@@ -153,6 +211,12 @@ public class JobController {
153 211
 	public ReturnT<String> resume(String triggerKeyName) {
154 212
 		try {
155 213
 			DynamicSchedulerUtil.resumeJob(triggerKeyName);
214
+			// update
215
+			XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName);
216
+			if (jobInfo!=null) {
217
+				jobInfo.setJobStatus("NORMAL");
218
+				xxlJobInfoDao.update(jobInfo);
219
+			}
156 220
 			return ReturnT.SUCCESS;
157 221
 		} catch (SchedulerException e) {
158 222
 			e.printStackTrace();

+ 77 - 0
xxl-job-admin/src/main/java/com/xxl/job/core/model/XxlJobInfo.java Прегледај датотеку

@@ -0,0 +1,77 @@
1
+package com.xxl.job.core.model;
2
+
3
+import java.util.Date;
4
+
5
+/**
6
+ * xxl-job info
7
+ * @author xuxueli  2016-1-12 18:25:49
8
+ */
9
+public class XxlJobInfo {
10
+	
11
+	private int id;
12
+	// job info
13
+	private String jobName;
14
+	private String jobCron;		// base on quartz
15
+	private String jobClass;	// base on quartz
16
+	private String jobStatus;	// base on quartz
17
+	private String jobData;		// base on db, Map-JSON-String
18
+	private Date addTime;
19
+	private Date updateTime;
20
+	
21
+	public int getId() {
22
+		return id;
23
+	}
24
+	public void setId(int id) {
25
+		this.id = id;
26
+	}
27
+	public String getJobName() {
28
+		return jobName;
29
+	}
30
+	public void setJobName(String jobName) {
31
+		this.jobName = jobName;
32
+	}
33
+	public String getJobCron() {
34
+		return jobCron;
35
+	}
36
+	public void setJobCron(String jobCron) {
37
+		this.jobCron = jobCron;
38
+	}
39
+	public String getJobClass() {
40
+		return jobClass;
41
+	}
42
+	public void setJobClass(String jobClass) {
43
+		this.jobClass = jobClass;
44
+	}
45
+	public String getJobStatus() {
46
+		return jobStatus;
47
+	}
48
+	public void setJobStatus(String jobStatus) {
49
+		this.jobStatus = jobStatus;
50
+	}
51
+	public String getJobData() {
52
+		return jobData;
53
+	}
54
+	public void setJobData(String jobData) {
55
+		this.jobData = jobData;
56
+	}
57
+	public Date getAddTime() {
58
+		return addTime;
59
+	}
60
+	public void setAddTime(Date addTime) {
61
+		this.addTime = addTime;
62
+	}
63
+	public Date getUpdateTime() {
64
+		return updateTime;
65
+	}
66
+	public void setUpdateTime(Date updateTime) {
67
+		this.updateTime = updateTime;
68
+	}
69
+	
70
+	@Override
71
+	public String toString() {
72
+		return "XxlJobInfo [id=" + id + ", jobName=" + jobName + ", jobCron=" + jobCron + ", jobClass=" + jobClass
73
+				+ ", jobStatus=" + jobStatus + ", jobData=" + jobData + ", addTime=" + addTime + ", updateTime="
74
+				+ updateTime + "]";
75
+	}
76
+	
77
+}

+ 36 - 2
xxl-job-admin/src/main/java/com/xxl/job/core/util/DynamicSchedulerUtil.java Прегледај датотеку

@@ -23,11 +23,14 @@ import org.quartz.Trigger.TriggerState;
23 23
 import org.quartz.TriggerBuilder;
24 24
 import org.quartz.TriggerKey;
25 25
 import org.quartz.impl.matchers.GroupMatcher;
26
+import org.quartz.impl.triggers.CronTriggerImpl;
26 27
 import org.slf4j.Logger;
27 28
 import org.slf4j.LoggerFactory;
28 29
 import org.springframework.beans.factory.InitializingBean;
29 30
 import org.springframework.util.Assert;
30 31
 
32
+import com.xxl.job.core.model.XxlJobInfo;
33
+import com.xxl.job.dao.IXxlJobInfoDao;
31 34
 import com.xxl.job.dao.IXxlJobLogDao;
32 35
 
33 36
 /**
@@ -43,8 +46,11 @@ public final class DynamicSchedulerUtil implements InitializingBean {
43 46
     public void setXxlJobLogDao(IXxlJobLogDao xxlJobLogDao) {
44 47
 		DynamicSchedulerUtil.xxlJobLogDao = xxlJobLogDao;
45 48
 	}
46
-    public static IXxlJobLogDao getXxlJobLogDao() {
47
-		return xxlJobLogDao;
49
+    // xxlJobInfoDao
50
+    public static IXxlJobInfoDao xxlJobInfoDao;
51
+    @Resource
52
+    public void setXxlJobInfoDao(IXxlJobInfoDao xxlJobInfoDao) {
53
+		DynamicSchedulerUtil.xxlJobInfoDao = xxlJobInfoDao;
48 54
 	}
49 55
     
50 56
     // Scheduler
@@ -90,6 +96,34 @@ public final class DynamicSchedulerUtil implements InitializingBean {
90 96
 		}
91 97
 		return jobList;
92 98
 	}
99
+	
100
+	// fill job info
101
+	public static void fillJobInfo(XxlJobInfo jobInfo) {
102
+		// TriggerKey : name + group
103
+        TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getJobName(), Scheduler.DEFAULT_GROUP);
104
+        JobKey jobKey = new JobKey(jobInfo.getJobName(), Scheduler.DEFAULT_GROUP);
105
+        try {
106
+			Trigger trigger = scheduler.getTrigger(triggerKey);
107
+			JobDetail jobDetail = scheduler.getJobDetail(jobKey);
108
+			TriggerState triggerState = scheduler.getTriggerState(triggerKey);
109
+			
110
+			// parse params
111
+			if (trigger!=null && trigger instanceof CronTriggerImpl) {
112
+				String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
113
+				jobInfo.setJobCron(cronExpression);
114
+			}
115
+			if (jobDetail!=null) {
116
+				String jobClass = jobDetail.getJobClass().getName();
117
+				jobInfo.setJobClass(jobClass);
118
+			}
119
+			if (triggerState!=null) {
120
+				jobInfo.setJobStatus(triggerState.name());
121
+			}
122
+			
123
+		} catch (SchedulerException e) {
124
+			e.printStackTrace();
125
+		}
126
+	}
93 127
 
94 128
 	// addJob 新增
95 129
     public static boolean addJob(String triggerKeyName, String cronExpression, Class<? extends Job> jobClass, Map<String, Object> jobData) throws SchedulerException {

+ 25 - 0
xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobInfoDao.java Прегледај датотеку

@@ -0,0 +1,25 @@
1
+package com.xxl.job.dao;
2
+
3
+import java.util.Date;
4
+import java.util.List;
5
+
6
+import com.xxl.job.core.model.XxlJobInfo;
7
+
8
+/**
9
+ * job info
10
+ * @author xuxueli 2016-1-12 18:03:45
11
+ */
12
+public interface IXxlJobInfoDao {
13
+
14
+	public List<XxlJobInfo> pageList(int offset, int pagesize, String jobName, Date addTimeStart, Date addTimeEnd);
15
+	public int pageListCount(int offset, int pagesize, String jobName, Date addTimeStart, Date addTimeEnd);
16
+	
17
+	public int save(XxlJobInfo info);
18
+	
19
+	public XxlJobInfo load(String jobName);
20
+	
21
+	public int update(XxlJobInfo item);
22
+	
23
+	public int delete(String jobName);
24
+	
25
+}

+ 4 - 0
xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java Прегледај датотеку

@@ -6,6 +6,10 @@ import java.util.List;
6 6
 
7 7
 import com.xxl.job.core.model.XxlJobLog;
8 8
 
9
+/**
10
+ * job log
11
+ * @author xuxueli 2016-1-12 18:03:06
12
+ */
9 13
 public interface IXxlJobLogDao {
10 14
 	
11 15
 	public int save(XxlJobLog xxlJobLog);

+ 69 - 0
xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobInfoDaoImpl.java Прегледај датотеку

@@ -0,0 +1,69 @@
1
+package com.xxl.job.dao.impl;
2
+
3
+import java.util.Date;
4
+import java.util.HashMap;
5
+import java.util.List;
6
+
7
+import javax.annotation.Resource;
8
+
9
+import org.mybatis.spring.SqlSessionTemplate;
10
+import org.springframework.stereotype.Repository;
11
+
12
+import com.xxl.job.core.model.XxlJobInfo;
13
+import com.xxl.job.dao.IXxlJobInfoDao;
14
+
15
+/**
16
+ * job info
17
+ * @author xuxueli 2016-1-12 18:03:45
18
+ */
19
+@Repository
20
+public class XxlJobInfoDaoImpl implements IXxlJobInfoDao {
21
+	
22
+	@Resource
23
+	public SqlSessionTemplate sqlSessionTemplate;
24
+
25
+	@Override
26
+	public List<XxlJobInfo> pageList(int offset, int pagesize, String jobName, Date addTimeStart, Date addTimeEnd) {
27
+		HashMap<String, Object> params = new HashMap<String, Object>();
28
+		params.put("offset", offset);
29
+		params.put("pagesize", pagesize);
30
+		params.put("jobName", jobName);
31
+		params.put("addTimeStart", addTimeStart);
32
+		params.put("addTimeEnd", addTimeEnd);
33
+		
34
+		return sqlSessionTemplate.selectList("XxlJobInfoMapper.pageList", params);
35
+	}
36
+
37
+	@Override
38
+	public int pageListCount(int offset, int pagesize, String jobName, Date addTimeStart, Date addTimeEnd) {
39
+		HashMap<String, Object> params = new HashMap<String, Object>();
40
+		params.put("offset", offset);
41
+		params.put("pagesize", pagesize);
42
+		params.put("jobName", jobName);
43
+		params.put("addTimeStart", addTimeStart);
44
+		params.put("addTimeEnd", addTimeEnd);
45
+		
46
+		return sqlSessionTemplate.selectOne("XxlJobInfoMapper.pageListCount", params);
47
+	}
48
+
49
+	@Override
50
+	public int save(XxlJobInfo info) {
51
+		return sqlSessionTemplate.insert("XxlJobInfoMapper.save", info);
52
+	}
53
+
54
+	@Override
55
+	public XxlJobInfo load(String jobName) {
56
+		return sqlSessionTemplate.selectOne("XxlJobInfoMapper.load", jobName);
57
+	}
58
+
59
+	@Override
60
+	public int update(XxlJobInfo item) {
61
+		return sqlSessionTemplate.update("XxlJobInfoMapper.update", item);
62
+	}
63
+
64
+	@Override
65
+	public int delete(String jobName) {
66
+		return sqlSessionTemplate.update("XxlJobInfoMapper.delete", jobName);
67
+	}
68
+	
69
+}

+ 4 - 0
xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java Прегледај датотеку

@@ -12,6 +12,10 @@ import org.springframework.stereotype.Repository;
12 12
 import com.xxl.job.core.model.XxlJobLog;
13 13
 import com.xxl.job.dao.IXxlJobLogDao;
14 14
 
15
+/**
16
+ * job log
17
+ * @author xuxueli 2016-1-12 18:03:06
18
+ */
15 19
 @Repository
16 20
 public class XxlJobLogDaoImpl implements IXxlJobLogDao {
17 21
 	

+ 8 - 10
xxl-job-admin/src/main/java/com/xxl/job/service/job/HttpJobBean.java Прегледај датотеку

@@ -3,7 +3,6 @@ package com.xxl.job.service.job;
3 3
 import java.util.Date;
4 4
 import java.util.HashMap;
5 5
 import java.util.Map;
6
-import java.util.Map.Entry;
7 6
 
8 7
 import org.apache.commons.lang.StringUtils;
9 8
 import org.quartz.JobExecutionContext;
@@ -16,6 +15,7 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
16 15
 import com.xxl.job.client.handler.HandlerRepository;
17 16
 import com.xxl.job.client.util.HttpUtil;
18 17
 import com.xxl.job.client.util.JacksonUtil;
18
+import com.xxl.job.core.model.XxlJobInfo;
19 19
 import com.xxl.job.core.model.XxlJobLog;
20 20
 import com.xxl.job.core.util.DynamicSchedulerUtil;
21 21
 import com.xxl.job.core.util.PropertiesUtil;
@@ -27,18 +27,17 @@ import com.xxl.job.core.util.PropertiesUtil;
27 27
 public class HttpJobBean extends QuartzJobBean {
28 28
 	private static Logger logger = LoggerFactory.getLogger(HttpJobBean.class);
29 29
 
30
+	@SuppressWarnings("unchecked")
30 31
 	@Override
31 32
 	protected void executeInternal(JobExecutionContext context)
32 33
 			throws JobExecutionException {
33
-		
34 34
 		String triggerKey = context.getTrigger().getJobKey().getName();
35
+		
35 36
 		// jobDataMap 2 params
36
-		Map<String, Object> jobDataMap = context.getMergedJobDataMap().getWrappedMap();
37 37
 		Map<String, String> params = new HashMap<String, String>();
38
-		if (jobDataMap!=null && jobDataMap.size()>0) {
39
-			for (Entry<String, Object> item : jobDataMap.entrySet()) {
40
-				params.put(item.getKey(), String.valueOf(item.getValue()));
41
-			}
38
+		XxlJobInfo jobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(triggerKey);
39
+		if (jobInfo!=null && jobInfo.getJobData()!=null) {
40
+			params = JacksonUtil.readValue(jobInfo.getJobData(), Map.class);
42 41
 		}
43 42
 		
44 43
 		// corn
@@ -53,7 +52,7 @@ public class HttpJobBean extends QuartzJobBean {
53 52
 		jobLog.setJobName(triggerKey);
54 53
 		jobLog.setJobCron(cornExp);
55 54
 		jobLog.setJobClass(HttpJobBean.class.getName());
56
-		jobLog.setJobData(JacksonUtil.writeValueAsString(params));
55
+		jobLog.setJobData(jobInfo.getJobData());
57 56
 		DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
58 57
 		logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
59 58
 		
@@ -70,8 +69,7 @@ public class HttpJobBean extends QuartzJobBean {
70 69
 		jobLog.setTriggerTime(new Date());
71 70
 		jobLog.setTriggerStatus(HttpUtil.FAIL);
72 71
 		jobLog.setTriggerMsg("[responseMsg]:"+responseMsg+"<br>[exceptionMsg]:"+exceptionMsg);
73
-		if (StringUtils.isNotBlank(responseMsg)) {
74
-			@SuppressWarnings("unchecked")
72
+		if (StringUtils.isNotBlank(responseMsg) && responseMsg.indexOf("{")>-1 ) {
75 73
 			Map<String, String> responseMap = JacksonUtil.readValue(responseMsg, Map.class);
76 74
 			if (responseMap!=null && StringUtils.isNotBlank(responseMap.get(HttpUtil.status))) {
77 75
 				jobLog.setTriggerStatus(responseMap.get(HttpUtil.status));

+ 1 - 1
xxl-job-admin/src/main/resources/applicationcontext-database.xml Прегледај датотеку

@@ -31,7 +31,7 @@
31 31
 	
32 32
 	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
33 33
 		<property name="dataSource" ref="dataSource" />
34
-		<property name="mapperLocations" value="classpath*:com/xxl/job/core/model/mapper/*.xml"/>
34
+		<property name="mapperLocations" value="classpath*:mybatis-mapper/*.xml"/>
35 35
 	</bean>
36 36
     
37 37
     <!-- scope must be "prototype" when junit -->

+ 102 - 0
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml Прегледај датотеку

@@ -0,0 +1,102 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
3
+	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
4
+<mapper namespace="XxlJobInfoMapper">
5
+	
6
+	<resultMap id="XxlJobInfo" type="com.xxl.job.core.model.XxlJobInfo" >
7
+		<result column="id" property="id" />
8
+	
9
+	    <result column="job_name" property="jobName" />
10
+	    <result column="job_cron" property="jobCron" />
11
+	    <result column="job_class" property="jobClass" />
12
+	    <result column="job_data" property="jobData" />
13
+	    
14
+	    <result column="add_time" property="addTime" />
15
+	    <result column="update_time" property="updateTime" />
16
+	</resultMap>
17
+
18
+	<sql id="Base_Column_List">
19
+		t.id,
20
+		t.job_name,
21
+		t.job_cron,
22
+		t.job_class,
23
+		t.job_data,
24
+		t.add_time,
25
+		t.update_time
26
+	</sql>
27
+	
28
+	<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
29
+		SELECT <include refid="Base_Column_List" />
30
+		FROM xxl_job_qrtz_trigger_info AS t
31
+		<trim prefix="WHERE" prefixOverrides="AND | OR" >
32
+			<if test="jobName != null and jobName!=''">
33
+				AND t.job_name = #{jobName}
34
+			</if>
35
+			<if test="addTimeStart != null">
36
+				AND t.add_time <![CDATA[ > ]]> #{addTimeStart}
37
+			</if>
38
+			<if test="addTimeEnd != null">
39
+				AND t.add_time <![CDATA[ < ]]> #{addTimeEnd}
40
+			</if>
41
+		</trim>
42
+		ORDER BY id DESC
43
+		LIMIT #{offset}, #{pagesize}
44
+	</select>
45
+	
46
+	<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
47
+		SELECT count(1)
48
+		FROM xxl_job_qrtz_trigger_info AS t
49
+		<trim prefix="WHERE" prefixOverrides="AND | OR" >
50
+			<if test="jobName != null and jobName!=''">
51
+				AND t.job_name = #{jobName}
52
+			</if>
53
+			<if test="addTimeStart != null">
54
+				AND t.add_time <![CDATA[ > ]]> #{addTimeStart}
55
+			</if>
56
+			<if test="addTimeEnd != null">
57
+				AND t.add_time <![CDATA[ < ]]> #{addTimeEnd}
58
+			</if>
59
+		</trim>
60
+	</select>
61
+	
62
+	<insert id="save" parameterType="com.xxl.job.core.model.XxlJobInfo" useGeneratedKeys="true" keyProperty="id" >
63
+		INSERT INTO `xxl_job_qrtz_trigger_info` (
64
+			`job_name`, 
65
+			`job_cron`, 
66
+			`job_class`, 
67
+			`job_data`,
68
+			`add_time`,
69
+			`update_time`
70
+		) VALUES (
71
+			#{jobName}, 
72
+			#{jobCron}, 
73
+			#{jobClass}, 
74
+			#{jobData},
75
+			NOW(),
76
+			NOW()
77
+		);
78
+		<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> 
79
+			SELECT LAST_INSERT_ID() 
80
+		</selectKey> 
81
+	</insert>
82
+	
83
+	<select id="load" parameterType="java.lang.String" resultMap="XxlJobInfo">
84
+		SELECT <include refid="Base_Column_List" />
85
+		FROM xxl_job_qrtz_trigger_info AS t
86
+		WHERE t.job_name = #{jobName}
87
+	</select>
88
+	
89
+	<update id="update">
90
+		UPDATE `xxl_job_qrtz_trigger_info` 
91
+		SET `job_cron`= #{jobCron}, 
92
+			`job_data`= #{jobData},
93
+			`update_time`= NOW()
94
+		WHERE `id`= #{id}
95
+	</update>
96
+	
97
+	<delete id="delete" parameterType="java.lang.String">
98
+		delete from xxl_job_qrtz_trigger_info
99
+		where job_name = #{jobName}
100
+	</delete>
101
+	
102
+</mapper>

xxl-job-admin/src/main/java/com/xxl/job/core/model/mapper/XxlJobLogMapper.xml → xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml Прегледај датотеку


+ 0 - 2
xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl Прегледај датотеку

@@ -68,8 +68,6 @@
68 68
 	
69 69
 	<!-- footer -->
70 70
 	<@netCommon.commonFooter />
71
-	<!-- control -->
72
-	<@netCommon.commonControl />
73 71
 </div>
74 72
 <@netCommon.commonScript />
75 73
 </body>

+ 53 - 26
xxl-job-admin/src/main/webapp/WEB-INF/template/job/index.ftl Прегледај датотеку

@@ -28,32 +28,53 @@
28 28
 		
29 29
 		<!-- Main content -->
30 30
 	    <section class="content">
31
+	    
32
+	    	<div class="row">
33
+	            <div class="col-xs-4">
34
+	              	<div class="input-group">
35
+	                	<span class="input-group-addon">
36
+	                  		jobName
37
+	                	</span>
38
+	                	<input type="text" class="form-control" id="jobName" value="${jobName}" autocomplete="on" >
39
+	              	</div>
40
+	            </div>
41
+	            <div class="col-xs-2">
42
+	            	<button class="btn btn-block btn-info" id="searchBtn">搜索</button>
43
+	            </div>
44
+	            <div class="col-xs-2">
45
+	            	<button class="btn btn-block btn-success add" type="button">+新增任务</button>
46
+	            </div>
47
+          	</div>
48
+	    	
31 49
 			<div class="row">
32 50
 				<div class="col-xs-12">
33 51
 					<div class="box">
34 52
 			            <div class="box-header">
35 53
 			            	<h3 class="box-title">调度列表</h3>
36
-			            	<button class="btn btn-info btn-xs add" type="button">+新增任务</button>
37 54
 			            </div>
38 55
 			            <div class="box-body">
39 56
 			              	<table id="job_list" class="table table-bordered table-striped">
40 57
 				                <thead>
41 58
 					            	<tr>
42
-					                	<th>调度key</th>
43
-					                  	<th>cron</th>
44
-					                  	<!--<th>类路径</th>-->
59
+					            		<th>id</th>
60
+					                	<th>任务Key</th>
61
+					                  	<th>任务Cron</th>
62
+					                  	<th>任务Class</th>
63
+					                  	<th>状态Status</th>
45 64
 					                  	<th>参数</th>
46
-					                  	<th>状态</th>
65
+					                  	<th>addTime</th>
66
+					                  	<th>updateTime</th>
47 67
 					                  	<th>操作</th>
48 68
 					                </tr>
49 69
 				                </thead>
50 70
 				                <tbody>
71
+				                	<#--
51 72
 			                		<#if jobList?exists && jobList?size gt 0>
52 73
 									<#list jobList as item>
53 74
 									<tr>
54 75
 					            		<td>${item['TriggerKey'].name}</td>
55 76
 					                  	<td>${item['Trigger'].cronExpression}</td>
56
-					                  	<!--<td>${item['JobDetail'].jobClass}</td>-->
77
+					                  	<td>${item['JobDetail'].jobClass}</td>
57 78
 					                  	<td>
58 79
 					                  		<#assign jobDataMap = item['JobDetail'].jobDataMap />
59 80
 					                  		<#if jobDataMap?exists && jobDataMap?keys?size gt 0>
@@ -89,17 +110,10 @@
89 110
 					                </tr>
90 111
 									</#list>
91 112
 									</#if>
113
+									
114
+									-->
92 115
 				                </tbody>
93
-				                <tfoot>
94
-					            	<tr>
95
-					                  	<th>调度key</th>
96
-					                  	<th>cron</th>
97
-					                  	<!--<th>类路径</th>-->
98
-					                  	<th>参数</th>
99
-					                  	<th>状态</th>
100
-					                  	<th>操作</th>
101
-					                </tr>
102
-				                </tfoot>
116
+				                <tfoot></tfoot>
103 117
 							</table>
104 118
 						</div>
105 119
 					</div>
@@ -110,8 +124,6 @@
110 124
 	
111 125
 	<!-- footer -->
112 126
 	<@netCommon.commonFooter />
113
-	<!-- control -->
114
-	<@netCommon.commonControl />
115 127
 </div>
116 128
 
117 129
 <!-- job新增.模态框 -->
@@ -129,19 +141,19 @@
129 141
 					</div>
130 142
 					<div class="form-group">
131 143
 						<label for="lastname" class="col-sm-3 control-label">任务Corn</label>
132
-						<div class="col-sm-9"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn[允许修改]" maxlength="100" ></div>
144
+						<div class="col-sm-9"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div>
133 145
 					</div>
134 146
 					<div class="form-group">
135 147
 						<label for="lastname" class="col-sm-3 control-label">任务描述</label>
136
-						<div class="col-sm-9"><input type="text" class="form-control" name="job_desc" placeholder="请输入任务描述[不支持修改]" maxlength="200" ></div>
148
+						<div class="col-sm-9"><input type="text" class="form-control" name="job_desc" placeholder="请输入任务描述" maxlength="200" ></div>
137 149
 					</div>
138 150
 					<div class="form-group">
139 151
 						<label for="lastname" class="col-sm-3 control-label">任务URL</label>
140
-						<div class="col-sm-9"><input type="text" class="form-control" name="job_url" placeholder="请输入任务URL[不支持修改]" maxlength="200" ></div>
152
+						<div class="col-sm-9"><input type="text" class="form-control" name="job_url" placeholder="请输入任务URL" maxlength="200" ></div>
141 153
 					</div>
142 154
 					<div class="form-group">
143 155
 						<label for="lastname" class="col-sm-3 control-label">任务handler</label>
144
-						<div class="col-sm-9"><input type="text" class="form-control" name="handleName" placeholder="请输入任务handler[不支持修改]" maxlength="200" ></div>
156
+						<div class="col-sm-9"><input type="text" class="form-control" name="handleName" placeholder="请输入任务handler" maxlength="200" ></div>
145 157
 					</div>
146 158
 					<div class="form-group">
147 159
 						<div class="col-sm-offset-3 col-sm-9">
@@ -166,12 +178,24 @@
166 178
          	<div class="modal-body">
167 179
 				<form class="form-horizontal form" role="form" >
168 180
 					<div class="form-group">
169
-						<label for="firstname" class="col-sm-2 control-label">任务Key</label>
170
-						<div class="col-sm-10"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" readonly ></div>
181
+						<label for="firstname" class="col-sm-3 control-label">任务Key</label>
182
+						<div class="col-sm-9"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" readonly ></div>
183
+					</div>
184
+					<div class="form-group">
185
+						<label for="lastname" class="col-sm-3 control-label">任务Corn</label>
186
+						<div class="col-sm-9"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div>
171 187
 					</div>
172 188
 					<div class="form-group">
173
-						<label for="lastname" class="col-sm-2 control-label">任务Corn</label>
174
-						<div class="col-sm-10"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div>
189
+						<label for="lastname" class="col-sm-3 control-label">任务描述</label>
190
+						<div class="col-sm-9"><input type="text" class="form-control" name="job_desc" placeholder="请输入任务描述" maxlength="200" ></div>
191
+					</div>
192
+					<div class="form-group">
193
+						<label for="lastname" class="col-sm-3 control-label">任务URL</label>
194
+						<div class="col-sm-9"><input type="text" class="form-control" name="job_url" placeholder="请输入任务URL" maxlength="200" ></div>
195
+					</div>
196
+					<div class="form-group">
197
+						<label for="lastname" class="col-sm-3 control-label">任务handler</label>
198
+						<div class="col-sm-9"><input type="text" class="form-control" name="handleName" placeholder="请输入任务handler" maxlength="200" ></div>
175 199
 					</div>
176 200
 					<div class="form-group">
177 201
 						<div class="col-sm-offset-2 col-sm-10">
@@ -191,6 +215,9 @@
191 215
 <script src="${request.contextPath}/static/adminlte/plugins/datatables/jquery.dataTables.min.js"></script>
192 216
 <script src="${request.contextPath}/static/adminlte/plugins/datatables/dataTables.bootstrap.min.js"></script>
193 217
 <script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
218
+<!-- daterangepicker -->
219
+<script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/moment.min.js"></script>
220
+<script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/daterangepicker.js"></script>
194 221
 <script>var base_url = '${request.contextPath}';</script>
195 222
 <script src="${request.contextPath}/static/js/job.index.1.js"></script>
196 223
 </body>

+ 0 - 2
xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/index.ftl Прегледај датотеку

@@ -84,8 +84,6 @@
84 84
 	
85 85
 	<!-- footer -->
86 86
 	<@netCommon.commonFooter />
87
-	<!-- control -->
88
-	<@netCommon.commonControl />
89 87
 </div>
90 88
 
91 89
 <@netCommon.commonScript />

+ 109 - 9
xxl-job-admin/src/main/webapp/static/js/job.index.1.js Прегледај датотеку

@@ -1,6 +1,75 @@
1 1
 $(function() {
2 2
 	// init date tables
3
-	$("#job_list").DataTable({
3
+	var jobTable = $("#job_list").dataTable({
4
+		"deferRender": true,
5
+		"processing" : true, 
6
+	    "serverSide": true,
7
+		"ajax": {
8
+			url: base_url + "/job/pageList",
9
+	        data : function ( d ) {
10
+                d.jobName = $('#jobName').val()
11
+            }
12
+	    },
13
+	    //"scrollX": true,	// X轴滚动条,取消自适应
14
+	    "columns": [
15
+	                { "data": 'id', "bSortable": false, "visible" : false},
16
+	                { "data": 'jobName', "bSortable": false},
17
+	                { "data": 'jobCron', "bSortable": false, "visible" : true},
18
+	                { "data": 'jobClass', "bSortable": false, "visible" : false},
19
+	                { "data": 'jobStatus', "bSortable": false, "visible" : true},
20
+	                { "data": 'jobData', "bSortable": false, "visible" : true},
21
+	                { 
22
+	                	"data": 'addTime', 
23
+	                	"bSortable": false, 
24
+	                	"render": function ( data, type, row ) {
25
+	                		return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
26
+	                	}
27
+	                },
28
+	                { 
29
+	                	"data": 'updateTime', 
30
+	                	"bSortable": false, 
31
+	                	"render": function ( data, type, row ) {
32
+	                		return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
33
+	                	}
34
+	                },
35
+	                { "data": '操作' , "bSortable": false,
36
+	                	"render": function ( data, type, row ) {
37
+	                		return function(){
38
+	                			// status
39
+	                			var pause_resume = "";
40
+	                			if ('NORMAL' == row.jobStatus) {
41
+	                				pause_resume = '<button class="btn btn-info btn-xs job_operate" type="job_pause" type="button">暂停</button>  ';
42
+								} else if ('PAUSED' == row.jobStatus){
43
+									pause_resume = '<button class="btn btn-info btn-xs job_operate" type="job_resume" type="button">恢复</button>  ';
44
+								}
45
+	                			// log url
46
+	                			var logUrl = base_url +'/joblog?jobName='+ row.jobName;
47
+	                			
48
+	                			// job data
49
+	                			var jobDataMap = eval('(' + row.jobData + ')');
50
+	                			
51
+	                			var html = '<p jobName="'+ row.jobName +'" '+
52
+	                							' cronExpression="'+ row.jobCron +'" '+
53
+	                							' job_desc="'+jobDataMap.job_desc +'" '+
54
+	                							' job_url="'+ jobDataMap.job_url +'" '+
55
+	                							' handleName="'+ jobDataMap.handleName +'" '+
56
+	                							'>'+
57
+	                					pause_resume +
58
+										'<button class="btn btn-info btn-xs job_operate" type="job_trigger" type="button">执行</button>  '+
59
+										'<button class="btn btn-info btn-xs update" type="button">更新corn</button>  '+
60
+									  	'<button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button>  '+
61
+									  	'<button class="btn btn-warning btn-xs" type="job_del" type="button" '+
62
+									  		'onclick="javascript:window.open(\'' + logUrl + '\')" >查看日志</button>'+
63
+									'</p>';
64
+									
65
+	                			
66
+	                			return html;
67
+	                		};
68
+	                	}
69
+	                }
70
+	            ],
71
+	    "searching": false,
72
+	    "ordering": true,
4 73
 		"language" : {
5 74
 			"sProcessing" : "处理中...",
6 75
 			"sLengthMenu" : "每页 _MENU_ 条记录",
@@ -27,8 +96,13 @@ $(function() {
27 96
 		}
28 97
 	});
29 98
 	
99
+	// 搜索按钮
100
+	$('#searchBtn').on('click', function(){
101
+		jobTable.fnDraw();
102
+	});
103
+	
30 104
 	// job operate
31
-	$(".job_operate").click(function() {
105
+	$("#job_list").on('click', '.job_operate',function() {
32 106
 		var typeName;
33 107
 		var url;
34 108
 		var type = $(this).attr("type");
@@ -48,22 +122,21 @@ $(function() {
48 122
 			return;
49 123
 		}
50 124
 		
51
-		var name = $(this).parent('p').attr("name");
52
-		var group = $(this).parent('p').attr("group");
125
+		var name = $(this).parent('p').attr("jobName");
53 126
 		
54 127
 		ComConfirm.show("确认" + typeName + "?", function(){
55 128
 			$.ajax({
56 129
 				type : 'POST',
57 130
 				url : url,
58 131
 				data : {
59
-					"triggerKeyName" :	name,
60
-					"group"			 :	group
132
+					"triggerKeyName" :	name
61 133
 				},
62 134
 				dataType : "json",
63 135
 				success : function(data){
64 136
 					if (data.code == 200) {
65 137
 						ComAlert.show(1, typeName + "成功", function(){
66
-							window.location.reload();
138
+							//window.location.reload();
139
+							jobTable.fnDraw();
67 140
 						});
68 141
 					} else {
69 142
 						ComAlert.show(1, typeName + "失败");
@@ -215,9 +288,12 @@ $(function() {
215 288
 	});
216 289
 	
217 290
 	// 更新
218
-	$(".update").click(function(){
219
-		$("#updateModal .form input[name='triggerKeyName']").val($(this).parent('p').attr("name"));
291
+	$("#job_list").on('click', '.update',function() {
292
+		$("#updateModal .form input[name='triggerKeyName']").val($(this).parent('p').attr("jobName"));
220 293
 		$("#updateModal .form input[name='cronExpression']").val($(this).parent('p').attr("cronExpression"));
294
+		$("#updateModal .form input[name='job_desc']").val($(this).parent('p').attr("job_desc"));
295
+		$("#updateModal .form input[name='job_url']").val($(this).parent('p').attr("job_url"));
296
+		$("#updateModal .form input[name='handleName']").val($(this).parent('p').attr("handleName"));
221 297
 		$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
222 298
 	});
223 299
 	var updateModalValidate = $("#updateModal .form").validate({
@@ -233,6 +309,18 @@ $(function() {
233 309
             cronExpression : {  
234 310
             	required : true ,
235 311
                 maxlength: 100
312
+            },  
313
+            job_desc : {  
314
+            	required : true ,
315
+                maxlength: 200
316
+            },
317
+            job_url : {
318
+            	required : true ,
319
+                maxlength: 200
320
+            },
321
+            handleName : {
322
+            	required : true ,
323
+                maxlength: 200
236 324
             }
237 325
         }, 
238 326
         messages : {  
@@ -244,6 +332,18 @@ $(function() {
244 332
             cronExpression : {
245 333
             	required :"请输入“任务Corn”."  ,
246 334
                 maxlength:"“任务Corn”不应超过100位"
335
+            },  
336
+            job_desc : {
337
+            	required :"请输入“任务描述”."  ,
338
+                maxlength:"“任务描述”长度不应超过200位"
339
+            },  
340
+            job_url : {
341
+            	required :"请输入“任务URL”."  ,
342
+                maxlength:"“任务URL”长度不应超过200位"
343
+            },
344
+            handleName : {
345
+            	required : "请输入“任务handler”."  ,
346
+                maxlength: "“任务handler”长度不应超过200位"
247 347
             }
248 348
         }, 
249 349
 		highlight : function(element) {  

+ 4 - 4
xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js Прегледај датотеку

@@ -29,7 +29,7 @@ $(function() {
29 29
 	                { "data": 'triggerStatus', "bSortable": false},
30 30
 	                { "data": 'triggerMsg',"bSortable": false,
31 31
 	                	"render": function ( data, type, row ) {
32
-	                		return data?'<a class="logTips" title="'+ data +'">调度日志</a>':"无";
32
+	                		return data?'<a class="logTips" href="javascript:;" >调度日志<span style="display:none;">'+ data +'</span></a>':"无";
33 33
 	                	}
34 34
 	                },
35 35
 	                { 
@@ -42,7 +42,7 @@ $(function() {
42 42
 	                { "data": 'handleStatus',"bSortable": false},
43 43
 	                { "data": 'handleMsg' , "bSortable": false,
44 44
 	                	"render": function ( data, type, row ) {
45
-	                		return data?'<a class="logTips" title="'+ data +'">执行日志</a>':"无";
45
+	                		return data?'<a class="logTips" href="javascript:;" >执行日志<span style="display:none;">'+ data +'</span></a>':"无";
46 46
 	                	}
47 47
 	                }
48 48
 	            ],
@@ -76,8 +76,8 @@ $(function() {
76 76
 	
77 77
 	// 日志弹框提示
78 78
 	$('#joblog_list').on('click', '.logTips', function(){
79
-		var title = $(this).attr('title');
80
-		ComAlertTec.show(title);
79
+		var msg = $(this).find('span').html();
80
+		ComAlertTec.show(msg);
81 81
 	});
82 82
 	
83 83
 	// 过滤时间

+ 55 - 0
xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobInfoTest.java Прегледај датотеку

@@ -0,0 +1,55 @@
1
+package com.xxl.job.dao.impl;
2
+
3
+import java.util.List;
4
+
5
+import javax.annotation.Resource;
6
+
7
+import org.junit.Test;
8
+import org.junit.runner.RunWith;
9
+import org.springframework.test.context.ContextConfiguration;
10
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11
+
12
+import com.xxl.job.core.model.XxlJobInfo;
13
+import com.xxl.job.dao.IXxlJobInfoDao;
14
+
15
+@RunWith(SpringJUnit4ClassRunner.class)
16
+@ContextConfiguration(locations = "classpath*:applicationcontext-*.xml")
17
+public class XxlJobInfoTest {
18
+	
19
+	@Resource
20
+	private IXxlJobInfoDao xxlJobInfoDao;
21
+	
22
+	@Test
23
+	public void pageList(){
24
+		List<XxlJobInfo> list = xxlJobInfoDao.pageList(0, 20, null, null, null);
25
+		int list_count = xxlJobInfoDao.pageListCount(0, 20, null, null, null);
26
+		
27
+		System.out.println(list);
28
+		System.out.println(list_count);
29
+	}
30
+	
31
+	@Test
32
+	public void save_load(){
33
+		XxlJobInfo info = new XxlJobInfo();
34
+		info.setJobName("job_name");
35
+		info.setJobCron("jobCron");
36
+		info.setJobClass("jobClass");
37
+		info.setJobData("jobData");
38
+		int count = xxlJobInfoDao.save(info);
39
+		System.out.println(count);
40
+		System.out.println(info.getId());
41
+		
42
+		XxlJobInfo item = xxlJobInfoDao.load(info.getId());
43
+		System.out.println(item);
44
+	}
45
+	
46
+	@Test
47
+	public void update(){
48
+		XxlJobInfo item = xxlJobInfoDao.load(2);
49
+		
50
+		item.setJobCron("jobCron2");
51
+		item.setJobData("jobData2");
52
+		xxlJobInfoDao.update(item);
53
+	}
54
+	
55
+}

+ 3 - 0
xxl-job-client/src/main/java/com/xxl/job/client/util/HttpUtil.java Прегледај датотеку

@@ -64,6 +64,9 @@ public class HttpUtil {
64 64
 				responseMsg = EntityUtils.toString(entity, "UTF-8");
65 65
 				EntityUtils.consume(entity);
66 66
 			}
67
+			if (response.getStatusLine().getStatusCode() != 200) {
68
+				exceptionMsg = "response.getStatusLine().getStatusCode() = " + response.getStatusLine().getStatusCode();
69
+			}
67 70
 		} catch (Exception e) {
68 71
 			e.printStackTrace();
69 72
 			StringWriter out = new StringWriter();