javaspring task 定时任务务怎么测试

Java&定时器的使用:每天定时执行任务
import java.util.C
import java.util.D
import java.util.T
import java.util.TimerT
public class TestTimer {
& & static int count =
& & public static void
showTimer() {
& TimerTask task = new TimerTask() {
& & & public
void run() {
& & System.out.println("时间=" +
new Date() + " 执行了" + count + "次"); // 1次
& //设置执行时间
& Calendar calendar =
Calendar.getInstance();
& int year = calendar.get(Calendar.YEAR);
& int month = calendar.get(Calendar.MONTH);
& int day =
calendar.get(Calendar.DAY_OF_MONTH);//每天
& //定制每天的21:09:00执行,
& calendar.set(year, month, day, 21, 9, 00);
& Date date = calendar.getTime();
& Timer timer = new Timer();
& System.out.println(date);
& int period = 2 * 1000;
& //每天的date时刻执行task,每隔2秒重复执行
& timer.schedule(task, date, period);
& //每天的date时刻执行task, 仅执行一次
& //timer.schedule(task, date);
& & public static void
main(String[] args) {
& showTimer();
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。12:48 提问
Java Task定时任务插入出错
定时任务中的一个插入语句,之前一直没问题,就在今天凌晨出现了问题,错误信息如下:
org.springframework.dao.DataIntegrityViolationException: StatementC SQL [ INSERT INTO tmp_offtake_yesterday_in
SELECT v.id store_id,si.sku sku_id,si.in_number in_num,si.create_time,si.create_user_id
FROM t_bo_sku_in si
LEFT JOIN v_sr v ON si.create_user_id=v.sr_id
WHERE si.create_time BETWEEN DATE_FORMAT(DATE_ADD(CURDATE(),INTERVAL -1 DAY),'%Y-%m-%d 02:00:00') AND DATE_FORMAT(CURDATE(),'%Y-%m-%d 01:59:59'); ]; Data truncation: Truncated incorrect DOUBLE value: 'U'; nested exception is com.mysql.jdbc.MysqlDataTruncation: Data truncation: Truncated incorrect DOUBLE value: 'U'
这个语句直接在mysql中执行是没问题的。有哪个大神知道原因,拜谢!!
按赞数排序
你把数据库所有属性设置为
:允许为空 试试
其他相关推荐博客分类:
代码清单:
==============================SQL====================================
计划任务表
==============================定时任务模块类====================================
计划管理DAO接口 CmsSchedulerDao.java
计划管理DAO接口实现类 CmsSchedulerDaoImpl.java
计划任务管理服务接口 CmsSchedulerMng.java
计划任务管理服务接口实现类 CmsSchedulerMngImpl.java
定时任务管理接口 SchedulerTaskManageSvc.java
定时任务管理接口实现类 SchedulerTaskManageSvcImpl.java
定时任务接口 SchedulerTaskSvc.java
定时任务抽象实现类 AbstractSchedulerTaskSvc.java
定时任务接口-采集器实现类-多线程版 SchedulerAcquisitionSvcImpl.java
定时服务关联任务bean SchedulerTaskBean.java
计划任务Controller CmsSchedulerAct.java
持久对象基类 BaseCmsScheduler.java
持久对象 CmsScheduler.java
HBM文件 CmsScheduler.hbm.xml
==============================定时任务模块相关互助类====================================
计划框架-任务调度 Scheduler.java
计划框架-时间生成器接口 ScheduleIterator.java
计划任务抽象类 SchedulerTask.java
计划框架-时间生成器接口实现类 SimpleScheduleIterator.java
时间计划参数bean ScheduleParamBean.java
HTML解析工具类接口 ParseHtmlTool.java
HTML解析工具,HtmlParser实现类 HtmlParserImpl.java
采集参数封装bean ParamBean.java
队列 Queue.java
URL队列 UrlQueue.java
接下来是XML配置
==============================定时任务模块XML配置====================================
&bean id="cmsSchedulerDao" class="com.jeecms.cms.dao.assist.impl.CmsSchedulerDaoImpl"/&
manage配置
&bean id="cmsSchedulerMng" class="com.jeecms.cms.manager.assist.impl.CmsSchedulerMngImpl"/&
SERVICE配置
&bean id="schedulerAcquisitionSvc" class="com.jeecms.cms.service.scheduler.SchedulerAcquisitionSvcImpl"/&
&bean id="schedulerTaskManageSvc" class="com.jeecms.cms.service.scheduler.SchedulerTaskManageSvcImpl"/&
接下来是messages_zh_CN.properties 添加了常量
==============================messages_zh_CN.properties====================================
messages_zh_CN.properties
接下来是模板
==============================模板====================================
generate_left.html 有修改
scheduler/add.html
scheduler/edit.html
scheduler/list.html
具体代码如下:
==============================SQL====================================
1:计划任务表
MySQL Data Transfer
Source Host: localhost
Source Database: jeecms
Target Host: localhost
Target Database: jeecms
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for jc_scheduler
-- ----------------------------
CREATE TABLE `jc_scheduler` (
`scheduler_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '任务主键',
`site_id` int(11) DEFAULT NULL,
`associate_id` int(11) DEFAULT NULL COMMENT '相关ID',
`module_type` varchar(100) DEFAULT NULL COMMENT '模块类型',
`name` varchar(100) DEFAULT NULL COMMENT '任务名称',
`start_time` datetime DEFAULT NULL COMMENT '开始时间',
`end_time` datetime DEFAULT NULL COMMENT '结束时间',
`status` int(1) NOT NULL DEFAULT '0' COMMENT '当前状态(0:静止;1:采集)',
`expression` varchar(50) NOT NULL COMMENT '计划表达式',
PRIMARY KEY (`scheduler_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `jc_scheduler` VALUES ('4', '1', '1', 'schedulerAcquisitionSvc', '测试', ' 18:02:30', ' 18:04:00', '0', '*,*,*,*,3,0');
INSERT INTO `jc_scheduler` VALUES ('8', '1', '5', 'schedulerAcquisitionSvc', '测试采集java', ' 10:25:15', ' 10:27:04', '0', '*,*,*,*,26,0');
INSERT INTO `jc_scheduler` VALUES ('9', '1', '1', 'schedulerAcquisitionSvc', '测试采集新闻', ' 10:37:58', ' 10:38:11', '0', '*,*,*,*,38,0');
==============================定时任务模块类====================================
计划管理DAO接口 CmsSchedulerDao.java
package com.jeecms.cms.dao.
import java.util.L
import com.jeecms.cms.entity.assist.CmsS
import mon.hibernate3.U
* 计划管理DAO接口
* @author javacoo
public interface CmsSchedulerDao {
public List&CmsScheduler& getList();
public List&CmsScheduler& getListBy(CmsScheduler bean);
public CmsScheduler findById(Integer id);
public CmsScheduler save(CmsScheduler bean);
public CmsScheduler updateByUpdater(Updater&CmsScheduler& updater);
public CmsScheduler deleteById(Integer id);
计划管理DAO接口实现类 CmsSchedulerDaoImpl.java
package com.jeecms.cms.dao.assist.
import java.util.L
import mons.lang.StringU
import org.springframework.stereotype.R
import com.jeecms.cms.dao.assist.CmsSchedulerD
import com.jeecms.cms.entity.assist.CmsS
import mon.hibernate3.F
import mon.hibernate3.HibernateBaseD
@Repository
public class CmsSchedulerDaoImpl extends
HibernateBaseDao&CmsScheduler, Integer& implements CmsSchedulerDao {
@SuppressWarnings("unchecked")
public List&CmsScheduler& getList() {
Finder f = Finder.create("from CmsScheduler bean order by bean.id asc");
return find(f);
@SuppressWarnings("unchecked")
public List&CmsScheduler& getListBy(CmsScheduler bean) {
Finder f = Finder.create("from CmsScheduler bean");
if(StringUtils.isNotEmpty(bean.getModuleType()) && bean.getSite().getId() != null) {
f.append(" where bean.moduleType=:moduleType and bean.site.id=:siteId");
f.setParam("moduleType", bean.getModuleType());
f.setParam("siteId", bean.getSite().getId());
f.append(" order by bean.id asc");
return find(f);
public CmsScheduler findById(Integer id) {
CmsScheduler entity = get(id);
public CmsScheduler save(CmsScheduler bean) {
getSession().save(bean);
public CmsScheduler deleteById(Integer id) {
CmsScheduler entity = super.get(id);
if (entity != null) {
getSession().delete(entity);
protected Class&CmsScheduler& getEntityClass() {
return CmsScheduler.
计划任务管理服务接口 CmsSchedulerMng.java
package com.jeecms.cms.manager.
import java.util.L
import com.jeecms.cms.entity.assist.CmsS
* 计划任务管理服务接口
* @author javacoo
* @version 1.0
public interface CmsSchedulerMng {
* 取得所有计划任务
* @return 所有计划任务
List&CmsScheduler& getList();
* 取得指定站点,指定模块所有计划任务
* @param bean 计划任务bean
* @return 所有计划任务
List&CmsScheduler& getListBy(CmsScheduler bean);
* 根据ID取得计划任务
* @param id
* @return 计划任务
CmsScheduler findById(Integer id);
* 停止指定的计划任务
* @param id
void stop(Integer id);
* 开始指定的计划任务
* @param id
CmsScheduler start(Integer id);
* 停止指定的计划任务
* @param id
void end(Integer id);
* 保存计划任务
* @param bean
CmsScheduler save(CmsScheduler bean);
* 更新计划任务
* @param bean
CmsScheduler update(CmsScheduler bean);
* 删除计划任务
* @param bean
CmsScheduler deleteById(Integer id);
* 批量删除计划任务
* @param bean
CmsScheduler[] deleteByIds(Integer[] ids);
计划任务管理服务接口实现类 CmsSchedulerMngImpl.java
package com.jeecms.cms.manager.assist.
import java.util.D
import java.util.L
import org.springframework.beans.factory.annotation.A
import org.springframework.stereotype.S
import org.springframework.transaction.annotation.T
import com.jeecms.cms.dao.assist.CmsSchedulerD
import com.jeecms.cms.entity.assist.CmsA
import com.jeecms.cms.entity.assist.CmsS
import com.jeecms.cms.manager.assist.CmsSchedulerM
import mon.hibernate3.U
* 计划任务管理服务接口实现类
* @author javacoo
* @version 1.0
@Transactional
public class CmsSchedulerMngImpl implements CmsSchedulerMng{
@Transactional(readOnly = true)
public List&CmsScheduler& getList() {
return dao.getList();
@Transactional(readOnly = true)
public List&CmsScheduler& getListBy(CmsScheduler bean) {
return dao.getListBy(bean);
@Transactional(readOnly = true)
public CmsScheduler findById(Integer id) {
CmsScheduler entity = dao.findById(id);
public void stop(Integer id) {
CmsScheduler acqu = findById(id);
if (acqu == null) {
if (acqu.getStatus() == CmsScheduler.START) {
acqu.setStatus(CmsScheduler.STOP);
public CmsScheduler start(Integer id) {
CmsScheduler scheduler = findById(id);
if (scheduler == null) {
scheduler.setStatus(CmsAcquisition.START);
scheduler.setStartTime(new Date());
scheduler.setEndTime(null);
public void end(Integer id) {
CmsScheduler scheduler = findById(id);
if (scheduler == null) {
scheduler.setStatus(CmsAcquisition.STOP);
scheduler.setEndTime(new Date());
public CmsScheduler save(CmsScheduler bean) {
bean.init();
dao.save(bean);
public CmsScheduler update(CmsScheduler bean) {
Updater&CmsScheduler& updater = new Updater&CmsScheduler&(bean);
bean = dao.updateByUpdater(updater);
public CmsScheduler deleteById(Integer id) {
CmsScheduler bean = dao.deleteById(id);
public CmsScheduler[] deleteByIds(Integer[] ids) {
CmsScheduler[] beans = new CmsScheduler[ids.length];
for (int i = 0, len = ids. i & i++) {
beans[i] = deleteById(ids[i]);
private CmsSchedulerD
@Autowired
public void setDao(CmsSchedulerDao dao) {
this.dao =
定时任务管理接口 SchedulerTaskManageSvc.java
package com.jeecms.cms.service.
import java.util.L
import com.jeecms.cms.entity.assist.CmsS
* 定时任务管理接口
* @author javacoo
public interface SchedulerTaskManageSvc {
* 开始计划任务
* @param scheduler 任务对象
* @return true/false
boolean start(CmsScheduler scheduler);
* 结束计划任务
* @param scheduler 任务对象
* @return true/false
boolean stop(CmsScheduler scheduler);
* 取得关联任务map
* @param scheduler 任务对象
* @return 关联任务map
List&SchedulerTaskBean& associateTaskList(CmsScheduler scheduler);
定时任务管理接口实现类 SchedulerTaskManageSvcImpl.java
package com.jeecms.cms.service.
import java.util.L
import java.util.M
import java.util.concurrent.ConcurrentHashM
import mons.lang.StringU
import org.springframework.beans.factory.annotation.A
import org.springframework.stereotype.S
import com.jeecms.cms.entity.assist.CmsS
import mon.scheduling.core.S
import mon.scheduling.core.SchedulerT
import mon.scheduling.impl.ScheduleParamB
import mon.scheduling.impl.SimpleScheduleI
* 定时任务管理服务接口实现类
* @author javacoo
public class SchedulerTaskManageSvcImpl implements SchedulerTaskManageSvc {
/**任务管理对象MAP*/
private static Map&Integer,TaskManage& taskManageMap = new ConcurrentHashMap&Integer, TaskManage&();
/**定时任务服务对象MAP*/
@Autowired
private Map&String,SchedulerTaskSvc& schedulerTaskSvcM
* 任务管理对象
* @author javacoo
private class TaskManage{
/**任务调度*/
private final Scheduler scheduler = new Scheduler();
/**任务参数bean*/
private ScheduleParamBean scheduleParamB
/**定时任务*/
private final SchedulerTaskSvc schedulerTaskS
private CmsScheduler cmsS
public TaskManage(SchedulerTaskSvc schedulerSvc,CmsScheduler cmsScheduler){
this.schedulerTaskSvc = schedulerS
this.cmsScheduler = cmsS
* 解析计划表达式
private boolean parseSchedulerParam(){
scheduleParamBean = new ScheduleParamBean();
System.out.println("计划表达式:"+cmsScheduler.getExpression());
String schedulerParamStr = cmsScheduler.getExpression();
if(StringUtils.isNotEmpty(schedulerParamStr) && schedulerParamStr.contains(",")){
String[] strAarr = schedulerParamStr.split(",");
if(strAarr.length == 6){
if(StringUtils.isNumeric(strAarr[0])){
scheduleParamBean.setWeekOfMonth(Integer.valueOf(strAarr[0]));
if(StringUtils.isNumeric(strAarr[1])){
scheduleParamBean.setDayOfWeek(Integer.valueOf(strAarr[1]));
if(StringUtils.isNumeric(strAarr[2])){
scheduleParamBean.setDayOfMonth(Integer.valueOf(strAarr[2]));
if(StringUtils.isNumeric(strAarr[3])){
scheduleParamBean.setHourOfDay(Integer.valueOf(strAarr[3]));
if(StringUtils.isNumeric(strAarr[4])){
scheduleParamBean.setMinute(Integer.valueOf(strAarr[4]));
if(StringUtils.isNumeric(strAarr[5])){
scheduleParamBean.setSecond(Integer.valueOf(strAarr[5]));
public void start() {
if(parseSchedulerParam()){
scheduler.schedule(new SchedulerTask() {
public void run() {
processer();
private void processer() {
System.out.println("============开始执行计划任务=================");
schedulerTaskSvc.start(cmsScheduler);
}, new SimpleScheduleIterator(scheduleParamBean));
public void cancel() {
schedulerTaskSvc.stop(cmsScheduler);
scheduler.cancel();
* 开始执行计划
* @param scheduler 计划对象
public boolean start(CmsScheduler scheduler) {
SchedulerTaskSvc schedulerSvc = getSchedulerTaskSvcByModuleType(scheduler.getModuleType());
TaskManage taskManage = new TaskManage(schedulerSvc,scheduler);
taskManage.start();
taskManageMap.put(scheduler.getId(), taskManage);
* 停止执行计划
* @param scheduler 计划对象
public boolean stop(CmsScheduler scheduler) {
TaskManage taskManage = taskManageMap.get(scheduler.getId());
taskManage.cancel();
* 取得计划关联的任务对象集合
* @param scheduler 计划对象
public List&SchedulerTaskBean& associateTaskList(CmsScheduler scheduler) {
SchedulerTaskSvc schedulerSvc = getSchedulerTaskSvcByModuleType(scheduler.getModuleType());
return schedulerSvc.associateTaskList(scheduler);
* 根据模块的类型,取得定时任务服务对象
* @param moduleType 模块类型
private SchedulerTaskSvc getSchedulerTaskSvcByModuleType(String moduleType){
return schedulerTaskSvcMap.get(moduleType);
定时任务接口 SchedulerTaskSvc.java
package com.jeecms.cms.service.
import java.util.L
import com.jeecms.cms.entity.assist.CmsS
* 定时任务接口
* @author javacoo
public interface SchedulerTaskSvc {
* 开始计划任务
* @param cmsScheduler 任务对象
* @return true/false
boolean start(CmsScheduler cmsScheduler);
* 结束计划任务
* @param cmsScheduler 任务对象
* @return true/false
boolean stop(CmsScheduler cmsScheduler);
* 取得关联任务map
* @param cmsScheduler 任务对象
* @return 关联任务map
List&SchedulerTaskBean& associateTaskList(CmsScheduler cmsScheduler);
定时任务抽象实现类 AbstractSchedulerTaskSvc.java
package com.jeecms.cms.service.
import java.util.L
import com.jeecms.cms.entity.assist.CmsS
* 定时任务抽象实现类
* @author javacoo
public abstract class AbstractSchedulerTaskSvc implements SchedulerTaskSvc{
* 开始计划任务
* @return true/false
public boolean start(CmsScheduler scheduler){
return execute(scheduler);
* 开始计划任务
* @return true/false
public boolean stop(CmsScheduler scheduler){
* 取得关联任务map
* @return 关联任务map
public List&SchedulerTaskBean& associateTaskList(CmsScheduler scheduler){
protected abstract boolean execute(CmsScheduler scheduler);
定时任务接口-采集器实现类-多线程版 SchedulerAcquisitionSvcImpl.java
package com.jeecms.cms.service.
import java.io.IOE
import java.net.URI;
import java.net.URISyntaxE
import java.util.ArrayL
import java.util.HashM
import java.util.L
import java.util.M
import java.util.concurrent.CountDownL
import java.util.concurrent.ExecutorS
import java.util.concurrent.E
import mons.lang.StringU
import org.apache.http.HttpE
import org.apache.http.HttpH
import org.apache.http.HttpR
import org.apache.http.StatusL
import org.apache.http.client.ClientProtocolE
import org.apache.http.client.HttpC
import org.apache.http.client.HttpResponseE
import org.apache.http.client.ResponseH
import org.apache.http.client.methods.HttpG
import org.apache.http.conn.params.ConnRoutePN
import org.apache.http.impl.client.DefaultHttpC
import org.apache.http.util.EntityU
import org.slf4j.L
import org.slf4j.LoggerF
import org.springframework.beans.factory.annotation.A
import org.springframework.stereotype.S
import com.jeecms.cms.entity.assist.CmsA
import com.jeecms.cms.entity.main.C
import com.jeecms.cms.manager.assist.CmsAcquisitionM
import mon.crawler.UrlQ
import mon.crawler.util.HtmlParserI
import mon.crawler.util.ParseHtmlT
* 计划任务接口-采集器实现类-多线程版
* @author javacoo
* @version 1.0
public class SchedulerAcquisitionSvcImpl extends AbstractSchedulerTaskSvc {
private Logger log = LoggerFactory.getLogger(SchedulerAcquisitionSvcImpl.class);
/**开启线程数*/
private static int THREAD_NUM = 2;
/**每个线程休眠毫秒数*/
private static int SLEEP_TIME = 100;
/**连接集合标志*/
private static String LINK_KEY = "linkKey";
/**标题集合标志*/
private static String TITLE_KEY = "titleKey";
/**采集管理对象*/
private CmsAcquisitionMng cmsAcquisitionM
/**存放HttpClient的ThreadLocal对象*/
private static ThreadLocal&HttpClient& httpClientThreadLocal = new ThreadLocal&HttpClient&();
/**存放ParseHtmlTool的ThreadLocal对象*/
private static ThreadLocal&ParseHtmlTool& parseHtmlToolThreadLocal = new ThreadLocal&ParseHtmlTool&();
/**存放UrlQueue的ThreadLocal对象*/
private static ThreadLocal&UrlQueue& urlQueueThreadLocal = new ThreadLocal&UrlQueue&();
/**存放计划UrlQueue的ThreadLocal对象*/
private static ThreadLocal&UrlQueue& planUrlQueueThreadLocal = new ThreadLocal&UrlQueue&();
@Autowired
public void setCmsAcquisitionMng(CmsAcquisitionMng cmsAcquisitionMng) {
this.cmsAcquisitionMng = cmsAcquisitionM
protected boolean execute(CmsScheduler scheduler) {
CmsAcquisition acqu = cmsAcquisitionMng.findById(scheduler.getAssociateId());
if (acqu == null) {
System.out.println("===============开始执行采集任务");
new Thread(new MainThreadProcesser(this,acqu)).start();
* 取得关联任务map
* @return 关联任务map
public List&SchedulerTaskBean& associateTaskList(CmsScheduler scheduler){
List&CmsAcquisition& list = cmsAcquisitionMng.getList(scheduler.getSite().getId());
List&SchedulerTaskBean& resultList = new ArrayList&SchedulerTaskBean&();
SchedulerTaskBean schedulerTaskBean =
for(CmsAcquisition acquisition : list){
schedulerTaskBean = new SchedulerTaskBean();
schedulerTaskBean.setId(acquisition.getId());
schedulerTaskBean.setName(acquisition.getName());
resultList.add(schedulerTaskBean);
return resultL
* 主线程处理类
* @author javacoo
private class MainThreadProcesser implements Runnable {
private CmsA
private SchedulerTaskSvc schedulerAcquisitionS
public MainThreadProcesser(SchedulerTaskSvc schedulerAcquisitionSvc,CmsAcquisition acqu) {
this.acqu =
this.schedulerAcquisitionSvc = schedulerAcquisitionS
Object threadLock = new Object();
public void run() {
long tStart = System.currentTimeMillis();
System.out.println("主线程:"+Thread.currentThread().getName() + "开始...");
CountDownLatch latch = new CountDownLatch(THREAD_NUM);
ExecutorService exec = Executors.newCachedThreadPool();
getHttpClient().getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,new HttpHost("128.160.64.5", 1235));
CharsetHandler handler = new CharsetHandler(acqu.getPageEncoding());
//取得当前任务所有计划
getAllPlans(acqu,getPlanUrlQueue());
//开启一线程执行抓取计划下URL
Thread thread = new Thread(new FetchUrlThread(schedulerAcquisitionSvc,latch,getHttpClient(),getPlanUrlQueue(),getUrlQueue(),getParseHtmlTool(acqu),handler,threadLock));
exec.execute(thread);
//开启指定数目线程执行采集内容
for(int i=0;i&THREAD_NUM;i++){
thread = new Thread(new FetchContentThread(schedulerAcquisitionSvc,acqu,latch,getHttpClient(),getUrlQueue(),getParseHtmlTool(acqu),handler,threadLock));
exec.execute(thread);
latch.await();
exec.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
httpClientThreadLocal.get().getConnectionManager().shutdown();
httpClientThreadLocal.remove();
parseHtmlToolThreadLocal.remove();
urlQueueThreadLocal.remove();
planUrlQueueThreadLocal.remove();
long tEnd = System.currentTimeMillis();
System.out.println("主线程:"+Thread.currentThread().getName() + "结束...");
System.out.println("主线程:"+Thread.currentThread().getName() + "总共用时:" + (tEnd - tStart) + "ms");
* 采集URL线程
* @author javacoo
private class FetchUrlThread implements Runnable{
private SchedulerTaskSvc acquisitionS
private CountDownL
private UrlQueue urlQ
private UrlQueue planUrlQ
private HttpClient httpC
private ParseHtmlTool parseHtmlT
private CharsetH
private Object threadL
public FetchUrlThread(SchedulerTaskSvc acquisitionSvc,CountDownLatch latch,HttpClient httpClient,UrlQueue planUrlQueue,UrlQueue urlQueue,ParseHtmlTool parseHtmlTool,CharsetHandler handler,Object threadLock){
this.acquisitionSvc = acquisitionS
this.latch =
this.urlQueue = urlQ
this.planUrlQueue = planUrlQ
this.httpClient = httpC
this.parseHtmlTool = parseHtmlT
this.handler =
this.threadLock = threadL
public void run() {
System.out.println("======================采集URL子线程:"+Thread.currentThread().getName() + "开始...");
Map&String,String& urlMap =
while(!urlAndTitleMapIsEmpty(planUrlQueue)) {
urlMap = getUrlAndTitleMap(planUrlQueue);
getAllUrls(httpClient,parseHtmlTool,handler,urlQueue,urlMap);
Thread.sleep(SLEEP_TIME);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
System.out.println("======================采集URL子线程:"+Thread.currentThread().getName() + "结束.");
//通知采集内容线程开始执行
synchronized(threadLock) {
threadLock.notifyAll();
latch.countDown();
* 采集内容线程
* @author javacoo
private class FetchContentThread implements Runnable {
private SchedulerTaskSvc acquisitionS
private CmsA
private CountDownL
private UrlQueue urlQ
private HttpClient httpC
private ParseHtmlTool parseHtmlT
private CharsetH
private Object threadL
public FetchContentThread(SchedulerTaskSvc acquisitionSvc,CmsAcquisition acqu,CountDownLatch latch,HttpClient httpClient,UrlQueue urlQueue,ParseHtmlTool parseHtmlTool,CharsetHandler handler,Object threadLock) {
this.acquisitionSvc = acquisitionS
this.acqu =
this.latch =
this.urlQueue = urlQ
this.httpClient = httpC
this.parseHtmlTool = parseHtmlT
this.handler =
this.threadLock = threadL
public void run() {
System.out.println("======================采集内容子线程:"+Thread.currentThread().getName() + "开始...");
//等待采集URL线程执行完毕
synchronized(threadLock) {
threadLock.wait();
Map&String,String& urlMap =
while(!urlAndTitleMapIsEmpty(urlQueue)) {
urlMap = getUrlAndTitleMap(urlQueue);
saveContent(acqu,httpClient,parseHtmlTool,handler,urlMap);
Thread.sleep(SLEEP_TIME);
} catch (Exception e) {
e.printStackTrace();
log.warn(null, e);
} finally {
System.out.println("======================采集内容子线程:"+Thread.currentThread().getName() + "结束.");
("Acquisition#{} complete", acqu.getId());
latch.countDown();
* 取得当前主线程的HttpClient对象
* @return 当前主线程的HttpClient对象
private static HttpClient getHttpClient(){
if(httpClientThreadLocal.get() == null){
HttpClient client = new DefaultHttpClient();
httpClientThreadLocal.set(client);
return httpClientThreadLocal.get();
* 取得当前主线程的UrlQueue对象
* @return 当前主线程的UrlQueue对象
private static UrlQueue getUrlQueue(){
if(urlQueueThreadLocal.get() == null){
UrlQueue urlQueue = new UrlQueue();
urlQueueThreadLocal.set(urlQueue);
return urlQ
return urlQueueThreadLocal.get();
* 取得当前主线程的计划UrlQueue对象
* @return 当前主线程的计划UrlQueue对象
private static UrlQueue getPlanUrlQueue(){
if(planUrlQueueThreadLocal.get() == null){
UrlQueue urlQueue = new UrlQueue();
planUrlQueueThreadLocal.set(urlQueue);
return urlQ
return planUrlQueueThreadLocal.get();
* 取得当前主线程的ParseHtmlTool对象
* @param acqu 采集参数对象
* @return 当前主线程的ParseHtmlTool对象
private static ParseHtmlTool getParseHtmlTool(CmsAcquisition acqu){
if(parseHtmlToolThreadLocal.get() == null){
ParseHtmlTool parseHtmlTool = new HtmlParserImpl(acqu);
parseHtmlToolThreadLocal.set(parseHtmlTool);
return parseHtmlT
return parseHtmlToolThreadLocal.get();
* 连接和标题map对象入队列
* @param map 连接和标题map对象
private synchronized void addUrlAndTitleMap(Map&String,String& map,UrlQueue urlQueue){
System.out.println("====线程:"+Thread.currentThread().getName() + ",添加
urlQueue:"+urlQueue);
urlQueue.addUnVisitedUrl(map);
* 连接和标题map对象出队列
* @param urlQueue 当前线程的队列
* @return 连接和标题map对象
private synchronized Map&String,String& getUrlAndTitleMap(UrlQueue urlQueue){
System.out.println("====线程:"+Thread.currentThread().getName() + ",取得 urlQueue:"+urlQueue);
return urlQueue.unVisitedUrlDeQueue();
判断当前对象是否为空
* @param urlQueue 当前线程的队列
* @return true/flase
private synchronized boolean urlAndTitleMapIsEmpty(UrlQueue urlQueue){
System.out.println("====线程:"+Thread.currentThread().getName() + ",判断 urlQueue:"+urlQueue);
return urlQueue.isEmpty();
* 取得当前线程下所有计划,并加入队列
* @param acqu 采集参数对象
* @param urlQueue 队列
* @throws URISyntaxException
* @throws IOException
* @throws ClientProtocolException
private void getAllPlans(CmsAcquisition acqu,UrlQueue urlQueue){
String[] plans = acqu.getAllPlans();
Map&String,String& planMap = new HashMap&String,String&();
for (int i = plans.length - 1; i &= 0; i--) {
planMap.put(LINK_KEY, plans[i]);
planMap.put(TITLE_KEY, acqu.getName());
addUrlAndTitleMap(planMap,urlQueue);
System.out.println("=======当前线程:"+Thread.currentThread().getName() + "计划URL连接数:"+urlQueue.getUnVisitedUrlNum());
* 取得当前线程下所有计划的连接,并加入队列
* @param acqu 采集参数对象
* @param handler 字符集对象
* @param urlQueue 队列
* @throws URISyntaxException
* @throws IOException
* @throws ClientProtocolException
private void getAllUrls(HttpClient httpClient,ParseHtmlTool parseHtmlTool,CharsetHandler handler,UrlQueue urlQueue,Map&String,String& map) throws URISyntaxException, ClientProtocolException, IOException{
HttpGet httpGet = new HttpGet(new URI(map.get(LINK_KEY).trim()));
String html = httpClient.execute(httpGet, handler);
for(Map&String,String& planMap : parseHtmlTool.getUrlAndTitleMap(html)){
addUrlAndTitleMap(planMap,urlQueue);
System.out.println("=======当前线程:"+Thread.currentThread().getName() + "URL连接数:"+urlQueue.getUnVisitedUrlNum());
* 保存内容
* @param acqu 请求参数对象
* @param httpClient httpClient对象
* @param parseHtmlTool parseHtmlTool对象
* @param handler CharsetHandler对象
* @param map 连接和标题map对象
* @return Content
private synchronized Content saveContent(CmsAcquisition acqu,HttpClient httpClient,ParseHtmlTool parseHtmlTool,CharsetHandler handler,Map&String,String& map) {
HttpGet httpGet =
if(map.get(LINK_KEY).contains("http://")){
httpGet = new HttpGet(new URI(map.get(LINK_KEY).trim()));
httpGet = new HttpGet(new URI("http://localhost/v7/"+map.get(LINK_KEY).trim()));
String html = httpClient.execute(httpGet, handler);
System.out.println("=============================子线程:"+Thread.currentThread().getName() + "执行");
String txt = parseHtmlTool.getHtml(html);
//return cmsAcquisitionMng.saveContent(map.get(TITLE_KEY), txt,acqu.getId());
} catch (Exception e) {
log.warn(null, e);
e.printStackTrace();
* 字符集帮助类
* @author Administrator
private class CharsetHandler implements ResponseHandler&String& {
public CharsetHandler(String charset) {
this.charset =
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() &= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
HttpEntity entity = response.getEntity();
if (entity != null) {
if (!StringUtils.isBlank(charset)) {
return EntityUtils.toString(entity, charset);
return EntityUtils.toString(entity);
定时服务关联任务bean SchedulerTaskBean.java
package com.jeecms.cms.service.
* 定时服务关联任务bean
* @author javacoo
public class SchedulerTaskBean {
/**任务主键*/
/**任务名称*/
public Integer getId() {
public void setId(Integer id) {
public String getName() {
public void setName(String name) {
this.name =
计划任务Controller CmsSchedulerAct.java
package com.jeecms.cms.action.admin.
import java.util.L
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import org.slf4j.L
import org.slf4j.LoggerF
import org.springframework.beans.factory.annotation.A
import org.springframework.stereotype.C
import org.springframework.ui.ModelM
import org.springframework.web.bind.annotation.RequestM
import com.jeecms.cms.entity.assist.CmsA
import com.jeecms.cms.entity.assist.CmsS
import com.jeecms.cms.entity.main.CmsS
import com.jeecms.cms.manager.assist.CmsSchedulerM
import com.jeecms.cms.manager.main.CmsLogM
import com.jeecms.cms.service.scheduler.SchedulerTaskManageS
import com.jeecms.cms.service.scheduler.SchedulerTaskB
import com.jeecms.cms.web.CmsU
import com.jeecms.cms.web.WebE
* 计划任务Controller
* @author javacoo
@Controller
public class CmsSchedulerAct {
private static final Logger log = LoggerFactory
.getLogger(CmsSchedulerAct.class);
/**日志服务*/
@Autowired
private CmsLogMng cmsLogM
/**计划管理服务*/
@Autowired
private CmsSchedulerM
/**计划任务管理服务*/
@Autowired
private SchedulerTaskManageSvc schedulerTaskManageS
@RequestMapping("/scheduler/v_list.do")
public String list(HttpServletRequest request, ModelMap model) {
List&CmsScheduler& list = manager.getList();
model.addAttribute("list", list);
return "scheduler/list";
@RequestMapping("/scheduler/v_listBy.do")
public String listBy(String moduleType,HttpServletRequest request, ModelMap model) {
CmsSite site = CmsUtils.getSite(request);
CmsScheduler scheduler = new CmsScheduler();
scheduler.setModuleType(moduleType);
scheduler.setSite(site);
List&CmsScheduler& list = manager.getListBy(scheduler);
model.addAttribute("list", list);
model.addAttribute("moduleType", moduleType);
return "scheduler/list";
@RequestMapping("/scheduler/v_add.do")
public String add(String moduleType,HttpServletRequest request, ModelMap model) {
CmsSite site = CmsUtils.getSite(request);
CmsScheduler scheduler = new CmsScheduler();
scheduler.setModuleType(moduleType);
scheduler.setSite(site);
List&SchedulerTaskBean& schedulerTaskList = schedulerTaskManageSvc.associateTaskList(scheduler);
model.addAttribute("schedulerTaskList", schedulerTaskList);
model.addAttribute("moduleType", moduleType);
return "scheduler/add";
@RequestMapping("/scheduler/v_edit.do")
public String edit(Integer id, HttpServletRequest request, ModelMap model) {
WebErrors errors = validateEdit(id, request);
if (errors.hasErrors()) {
return errors.showErrorPage(model);
CmsSite site = CmsUtils.getSite(request);
CmsScheduler scheduler = manager.findById(id);
scheduler.setSite(site);
List&SchedulerTaskBean& schedulerTaskList = schedulerTaskManageSvc.associateTaskList(scheduler);
model.addAttribute("schedulerTaskList", schedulerTaskList);
model.addAttribute("cmsScheduler", scheduler);
return "scheduler/edit";
@RequestMapping("/scheduler/o_save.do")
public String save(CmsScheduler bean,HttpServletRequest request, ModelMap model) {
CmsSite site = CmsUtils.getSite(request);
bean.setSite(site);
bean = manager.save(bean);
model.addAttribute("moduleType", bean.getModuleType());
("save CmsScheduler id={}", bean.getId());
cmsLogMng.operating(request, "cmsAcquisition.log.save", "id="
+ bean.getId() + ";name=" + bean.getName());
return "redirect:v_listBy.do";
@RequestMapping("/scheduler/o_update.do")
public String update(CmsScheduler bean, HttpServletRequest request, ModelMap model) {
WebErrors errors = validateUpdate(bean.getId(), request);
if (errors.hasErrors()) {
return errors.showErrorPage(model);
bean = manager.update(bean);
("update CmsAcquisition id={}.", bean.getId());
cmsLogMng.operating(request, "cmsAcquisition.log.update", "id="
+ bean.getId() + ";name=" + bean.getName());
return listBy(bean.getModuleType(),request, model);
@RequestMapping("/scheduler/o_delete.do")
public String delete(String moduleType,Integer[] ids, HttpServletRequest request,
ModelMap model) {
WebErrors errors = validateDelete(ids, request);
if (errors.hasErrors()) {
return errors.showErrorPage(model);
CmsScheduler[] beans = manager.deleteByIds(ids);
for (CmsScheduler bean : beans) {
("delete CmsAcquisition id={}", bean.getId());
cmsLogMng.operating(request, "cmsScheduler.log.delete", "id="
+ bean.getId() + ";name=" + bean.getName());
return listBy(moduleType,request, model);
@RequestMapping("/scheduler/o_start.do")
public String start(Integer id, HttpServletRequest request,
HttpServletResponse response, ModelMap model) {
CmsScheduler scheduler = manager.findById(id);
schedulerTaskManageSvc.start(scheduler);
manager.start(id);
model.addAttribute("moduleType", scheduler.getModuleType());
("start CmsAcquisition id={}", id);
return "redirect:v_listBy.do";
@RequestMapping("/scheduler/o_end.do")
public String end(Integer id, HttpServletRequest request,
HttpServletResponse response, ModelMap model) {
manager.end(id);
CmsScheduler scheduler = manager.findById(id);
schedulerTaskManageSvc.stop(scheduler);
model.addAttribute("moduleType", scheduler.getModuleType());
("end CmsScheduler id={}", id);
return "redirect:v_listBy.do";
private WebErrors validateEdit(Integer id, HttpServletRequest request) {
WebErrors errors = WebErrors.create(request);
CmsSite site = CmsUtils.getSite(request);
if (vldExist(id, site.getId(), errors)) {
private WebErrors validateUpdate(Integer id, HttpServletRequest request) {
WebErrors errors = WebErrors.create(request);
CmsSite site = CmsUtils.getSite(request);
if (vldExist(id, site.getId(), errors)) {
private WebErrors validateDelete(Integer[] ids, HttpServletRequest request) {
WebErrors errors = WebErrors.create(request);
CmsSite site = CmsUtils.getSite(request);
if (errors.ifEmpty(ids, "ids")) {
for (Integer id : ids) {
vldExist(id, site.getId(), errors);
private boolean vldExist(Integer id, Integer siteId, WebErrors errors) {
if (errors.ifNull(id, "id")) {
CmsScheduler entity = manager.findById(id);
if (errors.ifNotExist(entity, CmsAcquisition.class, id)) {
持久对象基类 BaseCmsScheduler.java
package com.jeecms.cms.entity.assist.
import java.io.S
import java.util.D
public abstract class BaseCmsScheduler implements Serializable {
public static String REF = "CmsScheduler";
public static String PROP_ID = "id";
public static String PROP_SITE = "site";
public static String PROP_ASSOCIATE_ID = "associateId";
public static String PROP_MODULE_TYPE = "moduleType";
public static String PROP_NAME = "name";
public static String PROP_START_TIME = "startTime";
public static String PROP_END_TIME = "endTime";
public static String PROP_STATUS = "status";
public static String PROP_EXPRESSION = "expression";
// constructors
public BaseCmsScheduler () {
initialize();
* Constructor for primary key
public BaseCmsScheduler (java.lang.Integer id) {
this.setId(id);
initialize();
public BaseCmsScheduler(Integer id,String name, Date startTime, Date endTime,
Integer status, Integer associateId, String moduleType, String expression,com.jeecms.cms.entity.main.CmsSite site) {
this.name =
this.startTime = startT
this.endTime = endT
this.status =
this.associateId = associateId;
this.moduleType = moduleT
this.expression =
this.site =
protected void initialize () {}
private int hashCode = Integer.MIN_VALUE;
// primary key
private java.lang.I
private java.lang.S
private java.util.Date startT
private java.util.Date endT
private java.lang.I
private java.lang.Integer associateId;
private java.lang.String moduleT
private java.lang.S
private com.jeecms.cms.entity.main.CmsS
public int getHashCode() {
return hashC
public void setHashCode(int hashCode) {
this.hashCode = hashC
public java.lang.Integer getId() {
public void setId(java.lang.Integer id) {
public java.lang.String getName() {
public void setName(java.lang.String name) {
this.name =
public java.util.Date getStartTime() {
return startT
public void setStartTime(java.util.Date startTime) {
this.startTime = startT
public java.util.Date getEndTime() {
return endT
public void setEndTime(java.util.Date endTime) {
this.endTime = endT
public java.lang.Integer getStatus() {
public void setStatus(java.lang.Integer status) {
this.status =
public java.lang.Integer getAssociateId() {
return associateId;
public void setAssociateId(java.lang.Integer associateId) {
this.associateId = associateId;
public java.lang.String getModuleType() {
return moduleT
public void setModuleType(java.lang.String moduleType) {
this.moduleType = moduleT
public java.lang.String getExpression() {
public void setExpression(java.lang.String expression) {
this.expression =
public com.jeecms.cms.entity.main.CmsSite getSite() {
public void setSite(com.jeecms.cms.entity.main.CmsSite site) {
this.site =
持久对象 CmsScheduler.java
package com.jeecms.cms.entity.
import java.util.D
import com.jeecms.cms.entity.assist.base.BaseCmsS
* 计划持久对象
* @author javacoo
public class CmsScheduler extends BaseCmsScheduler {
private static final long serialVersionUID = 1L;
* 停止状态
public static final int STOP = 0;
* 采集状态
public static final int START = 1;
* 是否停止
public boolean isStop() {
int status = getStatus();
return status == 0;
public void init() {
if (getStatus() == null) {
setStatus(STOP);
public CmsScheduler(){
public CmsScheduler(java.lang.Integer id){
super(id);
public CmsScheduler(Integer id,String name, Date startTime, Date endTime,
Integer status, Integer associateId, String moduleType, String expression,com.jeecms.cms.entity.main.CmsSite site) {
super(id,name,startTime,endTime,status,associateId,moduleType,expression,site);
HBM文件 CmsScheduler.hbm.xml
&?xml version="1.0"?&
&!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&
&hibernate-mapping package="com.jeecms.cms.entity.assist"&
&class name="CmsScheduler" table="jc_scheduler"&
&meta attribute="sync-DAO"&false&/meta&
&id name="id" type="integer" column="scheduler_id"&&generator class="identity"/&&/id&
&property name="associateId" column="associate_id" type="integer" not-null="true" length="11"/&
&property name="moduleType" column="module_type" type="string" not-null="false" length="100"/&
&property name="name" column="name" type="string" not-null="false" length="100"/&
&property name="startTime" column="start_time" type="timestamp" not-null="false" length="19"/&
&property name="endTime" column="end_time" type="timestamp" not-null="false" length="19"/&
&property name="status" column="status" type="integer" not-null="true" length="1"/&
&property name="expression" column="expression" type="string" not-null="true" length="50"/&
&many-to-one name="site" column="site_id" class="com.jeecms.cms.entity.main.CmsSite" not-null="true"&&/many-to-one&
&/hibernate-mapping&
==============================定时任务模块相关互助类====================================
计划框架-任务调度 Scheduler.java
package mon.scheduling.
import java.util.D
import java.util.T
import java.util.TimerT
* 计划框架-任务调度
* 用于提供必要的计划,Scheduler 的每一个实例都拥有 Timer 的一个实例,用于提供底层计划
* 它将一组单次定时器串接在一起,以便在由 ScheduleIterator 指定的各个时间执行 SchedulerTask 类
* @author javacoo
public class Scheduler {
/**Timer实例*/
private final Timer timer = new Timer();
* 定时任务计划
* @author javacoo
class SchedulerTimerTask extends TimerTask {
private SchedulerTask schedulerT
private ScheduleI
public SchedulerTimerTask(SchedulerTask schedulerTask,
ScheduleIterator iterator) {
this.schedulerTask = schedulerT
this.iterator =
public void run() {
schedulerTask.run();
reschedule(schedulerTask, iterator);
public Scheduler() {
* 取消执行
public void cancel() {
timer.cancel();
* 计划的入口点
* 通过调用 ScheduleIterator 接口的 next(),发现第一次执行 SchedulerTask 的时间。
* 然后通过调用底层 Timer 类的单次 schedule() 方法,启动计划在这一时刻执行。
* 为单次执行提供的 TimerTask 对象是嵌入的 SchedulerTimerTask 类的一个实例,
* 它包装了任务和迭代器(iterator)。在指定的时间,调用嵌入类的 run() 方法,
* 它使用包装的任务和迭代器引用以便重新计划任务的下一次执行
* @param schedulerTask SchedulerTimerTask 类的一个实例
* @param iterator ScheduleIterator 接口的一个实例
public void schedule(SchedulerTask schedulerTask, ScheduleIterator iterator) {
Date time = iterator.next();
if (time == null) {
schedulerTask.cancel();
synchronized (schedulerTask.lock) {
if (schedulerTask.state != SchedulerTask.VIRGIN) {
throw new IllegalStateException("任务已经执行/取消");
schedulerTask.state = SchedulerTask.SCHEDULED;
schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask,iterator);
timer.schedule(schedulerTask.timerTask, time);
* 重新制定计划
* @param schedulerTask SchedulerTimerTask 类的一个实例
* @param iterator ScheduleIterator 接口的一个实例
private void reschedule(SchedulerTask schedulerTask,
ScheduleIterator iterator) {
Date time = iterator.next();
if (time == null) {
schedulerTask.cancel();
synchronized (schedulerTask.lock) {
if (schedulerTask.state != SchedulerTask.CANCELLED) {
schedulerTask.timerTask = new SchedulerTimerTask(
schedulerTask, iterator);
timer.schedule(schedulerTask.timerTask, time);
计划框架-时间生成器接口 ScheduleIterator.java
package mon.scheduling.
import java.util.D
* 计划框架-时间生成器接口
* &li&将 SchedulerTask 的计划执行时间指定为一系列 java.util.Date 对象的接口
* 然后 next() 方法按时间先后顺序迭代 Date 对象,返回值 null 会使任务取消(即它再也不会运行)&/li&
* @author javacoo
public interface ScheduleIterator {
* 返回下次计划执行时间
* @return 下次计划执行时间
Date next();
计划任务抽象类 SchedulerTask.java
package mon.scheduling.
import java.util.TimerT
* 计划任务抽象类
* SchedulerTask 在其生命周期中要经历一系列的状态。创建后,它处于 VIRGIN 状态,
* 这表明它从没有计划过。计划以后,它就变为 SCHEDULED 状态,
* 再用下面描述的方法之一取消任务后,它就变为 CANCELLED 状态。
* 管理正确的状态转变 —— 如保证不对一个非 VIRGIN 状态的任务进行两次计划 ——
* 增加了 Scheduler 和 SchedulerTask 类的复杂性。在进行可能改变任务状态的操作时,
* 代码必须同步任务的锁对象
* @author javacoo
public abstract class SchedulerTask implements Runnable {
/**同步任务的锁对象*/
final Object lock = new Object();
int state = VIRGIN;
/**初始状态*/
static final int VIRGIN = 0;
/**任务状态*/
static final int SCHEDULED = 1;
/**取消状态*/
static final int CANCELLED = 2;
/**TimerTask 对象*/
TimerTask timerT
protected SchedulerTask() {
/**执行的任务,由子类实现*/
public abstract void run();
/**取消任务
* 任务再也不会运行了,不过已经运行的任务仍会运行完成
public boolean cancel() {
synchronized (lock) {
if (timerTask != null) {
timerTask.cancel();
boolean result = (state == SCHEDULED);
state = CANCELLED;
public long scheduledExecutionTime() {
synchronized (lock) {
return timerTask == null ? 0 : timerTask.scheduledExecutionTime();
计划框架-时间生成器接口实现类 SimpleScheduleIterator.java
package mon.scheduling.
import java.util.C
import java.util.D
import java.util.GregorianC
import mon.scheduling.core.ScheduleI
* 计划框架-时间生成器接口实现类
* &li&返回 月/周/天/小时/分钟/秒 计划的下一次执行时间&/li&
* &li&约定:参数以逗号分隔,*号表示无值&/li&
* &li&参数解释:
* &br&第一位:每个月的第几周&/br&
* &br&第二位:每周的第几天&/br&
* &br&第三位:天(几号)&/br&
* &br&第四位:小时(24小时制)&/br&
* &br&第五位:分钟&/br&
* &br&第六位:秒&/br&
* &li&参数样例:
&br& 1,6,4,15,20,30
表示 从今天的15:20:30开始,每隔一个月执行一次,即下次执行时间是
下个月的第一周的第6天的15:20:30&/br&
&br& *,6,4,15,20,30
表示 从今天的15:20:30开始,每隔一周执行一次,即下次执行时间是
下一周的第6天的15:20:30&/br&
&br& *,*,4,15,20,30
表示 从今天的15:20:30开始,每隔一天执行一次,即下次执行时间是
下一天的15:20:30&/br&
&br& *,*,*,15,20,30
表示 从今天的15:20:30开始,每隔一小时执行一次,即下次执行时间是
16:20:30&/br&
&br& *,*,*,*,20,30
表示 从这个小时的20:30开始,每隔一分钟执行一次,即下次执行时间是
*:21:30&/br&
&br& *,*,*,*,*,30
表示 从当前时间的30秒开始,每隔一秒执行一次,即下次执行时间是
*:*:31&/br&
* @author javacoo
public class SimpleScheduleIterator implements ScheduleIterator {
private final ScheduleParamBean scheduleParamB
private final Calendar calendar = Calendar.getInstance();
private final Calendar orginCalendar = Calendar.getInstance();
public SimpleScheduleIterator(final ScheduleParamBean scheduleParamBean) {
this(scheduleParamBean, new Date());
public SimpleScheduleIterator(final ScheduleParamBean scheduleParamBean, Date date) {
this.scheduleParamBean = scheduleParamB
orginCalendar.setTime(date);
calendar.setTime(date);
if(null != scheduleParamBean.getWeekOfMonth()){
calendar.set(Calendar.WEEK_OF_MONTH, scheduleParamBean.getWeekOfMonth());
//如果设置了每周的第几天和一个月的第几天,则忽略一个月的第几天
if(null != scheduleParamBean.getDayOfWeek()){
calendar.set(Calendar.DAY_OF_WEEK, scheduleParamBean.getDayOfWeek());
}else if(null != scheduleParamBean.getDayOfMonth()){
calendar.set(Calendar.DAY_OF_MONTH, scheduleParamBean.getDayOfMonth());
if(null != scheduleParamBean.getHourOfDay()){
calendar.set(Calendar.HOUR_OF_DAY, scheduleParamBean.getHourOfDay());
if(null != scheduleParamBean.getMinute()){
calendar.set(Calendar.MINUTE, scheduleParamBean.getMinute());
if(null != scheduleParamBean.getSecond()){
calendar.set(Calendar.SECOND, scheduleParamBean.getSecond());
calendar.set(Calendar.MILLISECOND, 0);
//如果设置时间 大于当前时间
if (!calendar.getTime().before(date)) {
System.out.println(calendar.getTime() +"大于当前时间:"+date);
if(null != scheduleParamBean.getWeekOfMonth()){
calendar.add(Calendar.MONTH, -1);
}else if(null != scheduleParamBean.getDayOfWeek()){
calendar.add(Calendar.DAY_OF_WEEK, -6);
}else if(null != scheduleParamBean.getDayOfMonth()){
calendar.add(Calendar.DAY_OF_MONTH, -1);
}else if(null != scheduleParamBean.getHourOfDay()){
calendar.add(Calendar.HOUR_OF_DAY, -1);
}else if(null != scheduleParamBean.getMinute()){
calendar.add(Calendar.MINUTE, -1);
}else if(null != scheduleParamBean.getSecond()){
calendar.add(Calendar.SECOND, -1);
}else{//如果小于,则会一下执行多次,所以在天,小时,分钟,秒 都加上相应时间差
System.out.println(calendar.getTime() +"小于当前时间:"+date);
if(null != scheduleParamBean.getDayOfMonth()){
calendar.add(Calendar.DAY_OF_MONTH, orginCalendar.get(Calendar.DAY_OF_MONTH) - scheduleParamBean.getDayOfMonth());
}else if(null != scheduleParamBean.getHourOfDay()){
calendar.add(Calendar.HOUR_OF_DAY, orginCalendar.get(Calendar.HOUR_OF_DAY) - scheduleParamBean.getHourOfDay());
}else if(null != scheduleParamBean.getMinute()){
calendar.add(Calendar.MINUTE, orginCalendar.get(Calendar.MINUTE) - scheduleParamBean.getMinute());
}else if(null != scheduleParamBean.getSecond()){
calendar.add(Calendar.SECOND, orginCalendar.get(Calendar.SECOND) - scheduleParamBean.getSecond());
public Date next() {
if(null != scheduleParamBean.getWeekOfMonth()){
calendar.add(Calendar.MONTH, 1);
}else if(null != scheduleParamBean.getDayOfWeek()){
calendar.add(Calendar.DAY_OF_WEEK, 6);
}else if(null != scheduleParamBean.getDayOfMonth()){
calendar.add(Calendar.DAY_OF_MONTH, 1);
}else if(null != scheduleParamBean.getHourOfDay()){
calendar.add(Calendar.HOUR_OF_DAY, 1);
}else if(null != scheduleParamBean.getMinute()){
calendar.add(Calendar.MINUTE, 1);
}else if(null != scheduleParamBean.getSecond()){
calendar.add(Calendar.SECOND, 1);
System.out.println("下次执行时间:"+calendar.getTime());
return calendar.getTime();
时间计划参数bean ScheduleParamBean.java
package mon.scheduling.
* 时间计划参数bean
* @author javacoo
public class ScheduleParamBean {
/**每个月的第几周,每周的第几天,每个月的第几天,小时(24小时制),分钟,秒*/
private Integer weekOfMonth,dayOfWeek,dayOfMonth,hourOfDay, minute,
public ScheduleParamBean(){
public ScheduleParamBean(Integer weekOfMonth, Integer dayOfWeek,
Integer dayOfMonth, Integer hourOfDay, Integer minute,
Integer second) {
this.weekOfMonth = weekOfM
this.dayOfWeek = dayOfW
this.dayOfMonth = dayOfM
this.hourOfDay = hourOfD
this.minute =
this.second =
public Integer getWeekOfMonth() {
return weekOfM
public void setWeekOfMonth(Integer weekOfMonth) {
this.weekOfMonth = weekOfM
public Integer getDayOfWeek() {
return dayOfW
public void setDayOfWeek(Integer dayOfWeek) {
this.dayOfWeek = dayOfW
public Integer getDayOfMonth() {
return dayOfM
public void setDayOfMonth(Integer dayOfMonth) {
this.dayOfMonth = dayOfM
public Integer getHourOfDay() {
return hourOfD
public void setHourOfDay(Integer hourOfDay) {
this.hourOfDay = hourOfD
public Integer getMinute() {
public void setMinute(Integer minute) {
this.minute =
public Integer getSecond() {
public void setSecond(Integer second) {
this.second =
public String toString() {
return "ScheduleParamBean [dayOfMonth=" + dayOfMonth + ", dayOfWeek="
+ dayOfWeek + ", hourOfDay=" + hourOfDay + ", minute=" + minute
+ ", second=" + second + ", weekOfMonth=" + weekOfMonth + "]";
HTML解析工具类接口 ParseHtmlTool.java
package mon.crawler.
import java.util.L
import java.util.M
* HTML解析工具类接口
* @author javacoo
public interface ParseHtmlTool {
* 取得连接集合
* @param orginHtml 原始HTML
* @return 连接集合
List&String& getUrlList( String orginHtml);
* 取得标题集合
* @param orginHtml 原始HTML
* @return 标题集合
List&String& getTitleList(String orginHtml);
* 取得指定区域的HTML内容
* @return 指定区域的HTML内容
String getHtml(String orginHtml);
* 取得连接标题Map集合
* @param orginHtml 原始HTML
* @return 连接标题Map集合
List&Map&String,String&& getUrlAndTitleMap(String orginHtml);
HTML解析工具,HtmlParser实现类 HtmlParserImpl.java
package mon.crawler.
import java.io.BufferedR
import java.io.F
import java.io.FileInputS
import java.io.IOE
import java.io.InputStreamR
import java.net.URISyntaxE
import java.util.ArrayL
import java.util.HashM
import java.util.I
import java.util.L
import java.util.M
import java.util.regex.M
import java.util.regex.P
import mons.lang.StringU
import org.htmlparser.N
import org.htmlparser.NodeF
import org.htmlparser.P
import org.htmlparser.filters.HasAttributeF
import org.htmlparser.filters.NodeClassF
import org.htmlparser.filters.TagNameF
import org.htmlparser.nodes.RemarkN
import org.htmlparser.util.NodeL
import org.htmlparser.util.ParserE
import com.jeecms.cms.entity.assist.CmsA
import mon.crawler.ParamB
* HTML解析工具,HtmlParser实现类
* @author javacoo
public class HtmlParserImpl implements ParseHtmlTool{
/**连接集合标志*/
private static String LINK_KEY = "linkKey";
/**标题集合标志*/
private static String TITLE_KEY = "titleKey";
/**单标签标志*/
private static String SINGLE_TAG = "singleTag";
/**连接正则表达式*/
private static String LINK_REGX = "&a.*href=\"(.*?)\".*&(.*?)&/a&";
/**正则表达式对象*/
private Pattern pt = pile(LINK_REGX);
/**采集参数bean*/
private ParamBean paramB
public HtmlParserImpl(CmsAcquisition acqu){
parseRequestParam(acqu);
* 取得标题集合
* @param orginHtml 原始HTML
* @return 标题集合
public List&String& getTitleList(String orginHtml) {
orginHtml = getHtmlByFilter(paramBean.getLinksetStartMap(), paramBean.getLinksetEndMap(),orginHtml);
if (StringUtils.isNotEmpty(orginHtml)) {
return getUrlOrTitleListByType(orginHtml,TITLE_KEY);
* 取得连接集合
* @param orginHtml 原始HTML
* @return 连接集合
public List&String& getUrlList(String orginHtml) {
orginHtml = getHtmlByFilter(paramBean.getLinksetStartMap(), paramBean.getLinksetEndMap(),orginHtml);
if (StringUtils.isNotEmpty(orginHtml)) {
return getUrlOrTitleListByType(orginHtml,LINK_KEY);
* 取得指定区域的HTML内容
* @param orginHtml 原始HTML
* @return 指定区域的HTML内容
* @throws ParserException
public String getHtml(String orginHtml) {
orginHtml = getHtmlByFilter(paramBean.getContentStartMap(), paramBean.getContentEndMap(),orginHtml);
return orginH
* 取得连接标题Map
* @param orginHtml 原始HTML
* @return 连接标题Map
public List&Map&String,String&& getUrlAndTitleMap(String orginHtml){
return getUrlAandTitleMap(orginHtml);
* 解析采集参数,并封装到ParamBean
* @param acqu 原始采集参数
* @return 采集参数封装bean
private void parseRequestParam(CmsAcquisition acqu){
paramBean = new ParamBean();
if(!StringUtils.isEmpty(acqu.getLinksetStart())){
paramBean.setLinksetStartMap(populateParamMap(acqu.getLinksetStart()));
if(!StringUtils.isEmpty(acqu.getLinksetEnd())){
paramBean.setLinksetEndMap(populateParamMap(acqu.getLinksetEnd()));
if(!StringUtils.isEmpty(acqu.getContentStart())){
paramBean.setContentStartMap(populateParamMap(acqu.getContentStart()));
if(!StringUtils.isEmpty(acqu.getContentEnd())){
paramBean.setContentEndMap(populateParamMap(acqu.getContentEnd()));
* 得到连接标题MAP
* @param html html内容
* @return 连接或者标题集合
private List&Map&String,String&& getUrlAandTitleMap(String html) {
html = getHtmlByFilter(paramBean.getLinksetStartMap(), paramBean.getLinksetEndMap(),html);
List&Map&String,String&& resultMapList = new ArrayList&Map&String,String&&();
Map&String,String& resultMap =
Matcher m = pt.matcher(html);
while (m.find()) {
if(StringUtils.isNotEmpty(m.group(1)) && StringUtils.isNotEmpty(m.group(2))){
resultMap = new HashMap&String, String&();
resultMap.put(LINK_KEY, m.group(1));
resultMap.put(TITLE_KEY, m.group(2));
resultMapList.add(resultMap);
return resultMapL
* 得到地址集
* @param html html内容
* @param type 1 :取得连接集合,2:取得标题集合
* @return 连接或者标题集合
private List&String& getUrlOrTitleListByType(String html, String type) {
List&String& resultList = new ArrayList&String&();
Matcher m = pt.matcher(html);
String result = "";
int pos = 1;
if(TITLE_KEY.equals(type)){
while (m.find()) {
result = m.group(pos);
resultList.add(result);
return resultL
* 取得指定区域的HTML内容
* @param tagMap 标签MAP
* @param removeTagMap 要过滤的标签MAP
* @param orginHtml 原始HTML
* @return 指定区域的HTML内容
* @throws ParserException
private String getHtmlByFilter(Map&String, String& tagMap,
Map&String, String& removeTagMap, String orginHtml) {
Parser parser = new Parser();
parser.setInputHTML(orginHtml);
// 第一步取得指定属性/标签内容
String tempKey =
String tempValue =
String[] tempValueArr =
StringBuilder sb = new StringBuilder();
NodeFilter filter =
for(Iterator&String& it = tagMap.keySet().iterator(); it.hasNext();){
tempKey = it.next();
tempValue = tagMap.get(tempKey);
if(tempValue.contains("|")){
tempValueArr = tempValue.split("\\|");
tempValueArr = new String[]{tempValue};
for(String value : tempValueArr){
filter = populateFilter(tempKey,value);
appendHtmlByFilter(parser, filter, sb);
// 第二步过滤指定属性/标签内容
String contentHtml = sb.toString();
for (Iterator&String& it = removeTagMap.keySet().iterator(); it
.hasNext();) {
tempKey = it.next();
tempValue = removeTagMap.get(tempKey);
if(tempValue.contains("|")){
tempValueArr = tempValue.split("\\|");
tempValueArr = new String[]{tempValue};
for(String value : tempValueArr){
filter = populateFilter(tempKey,value);
contentHtml = removeHtmlByFilter(parser, filter, contentHtml);
//第三步过滤注释
filter = new NodeClassFilter(RemarkNode.class);
contentHtml = removeHtmlByFilter(parser, filter, contentHtml);
System.out.println("=================================结果=======================================");
System.out.println(contentHtml);
return contentH
} catch (ParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
* 解析并组装采集参数,支持标签属性/值形式和标签名称形式,可混合使用
* &li&约定采集参数格式如下&/li&
* &li&1,标签属性/值形式,如:class=articleList|tips,id=fxwb|fxMSN|fxMSN&/li&
* &li&2,标签名称形式,如:div,p,span&/li&
* &li&3,混合形式,如:class=articleList|tips,id=fxwb|fxMSN|fxMSN,div,p,span&/li&
* @param paramStr 参数字符串
private Map&String, String& populateParamMap(String paramStr) {
Map&String, String& paramMap = new HashMap&String, String&();
String[] paramStrArr = paramStr.split(",");
String[] tempStrArr =
StringBuilder sb = new StringBuilder();
for(String temp : paramStrArr){
if(temp.contains("=")){
tempStrArr = temp.split("=");
paramMap.put(tempStrArr[0], tempStrArr[1]);
if(StringUtils.isNotEmpty(temp)){
sb.append(temp).append("|");
if(StringUtils.isNotEmpty(sb.toString())){
paramMap.put(SINGLE_TAG, sb.substring(0, sb.length() - 1));
return paramM
* 组装过滤器
* @param key 键
* @param value 值
* @return 过滤器
private NodeFilter populateFilter(String key,String value) {
if(SINGLE_TAG.equals(key)){
new TagNameFilter(value);
filter = new HasAttributeFilter(key,value);
* 过滤指定属性标签HTML
* @param parser 解析器
* @param filter 属性过滤器
* @param orginHtml 原始HTML
* @return 过滤后HTML
* @throws ParserException
private String removeHtmlByFilter(Parser parser, NodeFilter filter,String orginHtml) throws ParserException {
parser.setInputHTML(orginHtml);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
for (int i = 0; i & nodes.size(); i++) {
Node textnode = (Node) nodes.elementAt(i);
orginHtml = StringUtils.remove(orginHtml, textnode.toHtml());
return orginH
* 取得所有指定属性/标签的HTML
* @param parser 解析器
* @param filter 过滤器
* @param sb
* @throws ParserException
private void appendHtmlByFilter(Parser parser, NodeFilter filter,
StringBuilder sb) throws ParserException {
NodeList nodes = parser.extractAllNodesThatMatch(filter);
for (int i = 0; i & nodes.size(); i++) {
Node textnode = (Node) nodes.elementAt(i);
sb.append(textnode.toHtml());
* 解析并组装采集参数,支持标签属性/值形式和标签名称形式,可混合使用
* &li&约定采集参数格式如下&/li&
* &li&1,标签属性/值形式,如:class=articleList|tips,id=fxwb|fxMSN|fxMSN&/li&
* &li&2,标签名称形式,如:div,p,span&/li&
* &li&3,混合形式,如:class=articleList|tips,id=fxwb|fxMSN|fxMSN,div,p,span&/li&
* @param paramMap 参数map
* @param str 参数字符串
private void populateParamMap(Map&String, String& paramMap,String paramStr) {
String[] paramStrArr = paramStr.split(",");
String[] tempStrArr =
StringBuilder sb = new StringBuilder();
for(String temp : paramStrArr){
if(temp.contains("=")){
tempStrArr = temp.split("=");
paramMap.put(tempStrArr[0], tempStrArr[1]);
if(StringUtils.isNotEmpty(temp)){
sb.append(temp).append("|");
if(StringUtils.isNotEmpty(sb.toString())){
paramMap.put(SINGLE_TAG, sb.substring(0, sb.length() - 1));
* 测试方法-打开文件并返回内容
* @param szFileName 文件绝对地址
* @param charset 字符集
* @return 内容
public static String openFile(String szFileName,String charset) {
BufferedReader bis = new BufferedReader(new InputStreamReader(
new FileInputStream(new File(szFileName)), charset));
StringBuilder szContent = new StringBuilder();
String szT
while ((szTemp = bis.readLine()) != null) {
szContent.append(szTemp).append("\n");
bis.close();
return szContent.toString();
} catch (Exception e) {
return "";
* 测试取得连接地址和标题
* @throws ParserException
public void testFetchLinkAndTitle() throws ParserException{
String html = openFile("F:\\4.htm","UTF-8");
String result = "";
Map&String, String& map = new HashMap&String, String&();
map.put("class", "m_list");
Map&String, String& notMap = new HashMap&String, String&();
//notMap.put("class", "atc_ic_f");
result = getHtmlByFilter(map,notMap,html);
System.out.println("=============================result============================");
System.out.println(result);
System.out.println("==========================================================");
Pattern pt = pile("&a.*href=\"(.*?)\".*&(.*?)&/a&");
Matcher m = pt.matcher(result);
String link =
String title =
while (m.find()) {
link = m.group(1);
title = m.group(2);
if (StringUtils.isNotEmpty(link)) {
System.out.println("url : " + link);
System.out.println("title : " + title);
* 测试取得内容
* @throws ParserException
public void testFetchContent() throws ParserException{
String html = openFile("F:\\6.shtml","GB2312");
Map&String, String& map = new HashMap&String, String&();
map.put("id", "artibody");
Map&String, String& notMap = new HashMap&String, String&();
notMap.put(SINGLE_TAG, "style|script");
notMap.put("type", "text/javascript");
notMap.put("class", "icon_fx|blkComment otherContent_01");
notMap.put("style", "text-align:padding-right:10|margin-top:6|font-size: 12px !|font-size:12px");
notMap.put("id", "fxwb|fxMSN|fxMSN|comment_t_show_top");
getHtmlByFilter(map,notMap,html);
* 测试解析参数
public void testParseParam(){
Map&String, String& map = new HashMap&String, String&();
populateParamMap(map,"class=articleList|tips,p,div");
String tempKey =
String tempValue =
String[] tempValueArr =
for (Iterator&String& it = map.keySet().iterator(); it.hasNext();) {
tempKey = it.next();
tempValue = map.get(tempKey);
if(tempValue.contains("|")){
tempValueArr = tempValue.split("\\|");
tempValueArr = new String[]{tempValue};
for(String value : tempValueArr){
System.out.println("tempKey:" + tempKey);
System.out.println("value:" + value);
* 测试过滤标签
* @throws ParserException
public void testRemarkFilter() throws ParserException{
String html = openFile("F:\\6.shtml","GB2312");
System.out.println("=========================过滤注释前HTML==================================");
System.out.println(html);
NodeFilter filter = new NodeClassFilter(RemarkNode.class);
html = removeHtmlByFilter(new Parser(), filter, html);
System.out.println("=========================过滤注释后HTML==================================");
System.out.println(html);
public static void main(String[] args) throws ParserException,
URISyntaxException, IOException {
HtmlParserImpl parseHtmlTool = new HtmlParserImpl(new CmsAcquisition());
//parseHtmlTool.testParseParam();
//parseHtmlTool.testFetchLinkAndTitle();
//parseHtmlTool.testFetchContent();
//parseHtmlTool.testRemarkFilter();
采集参数封装bean ParamBean.java
package mon.
import java.util.HashM
import java.util.M
* 采集参数封装bean
* @author javacoo
public class ParamBean {
/**待采集连接区域属性MAP*/
private Map&String, String& linksetStartMap = new HashMap&String, String&();
/**待采集连接区域过滤属性MAP*/
private Map&String, String& linksetEndMap = new HashMap&String, String&();
/**待采集内容区域属性MAP*/
private Map&String, String& contentStartMap = new HashMap&String, String&();
/**待采集内容区域过滤属性MAP*/
private Map&String, String& contentEndMap = new HashMap&String, String&();
public Map&String, String& getLinksetStartMap() {
return linksetStartM
public void setLinksetStartMap(Map&String, String& linksetStartMap) {
this.linksetStartMap = linksetStartM
public Map&String, String& getLinksetEndMap() {
return linksetEndM
public void setLinksetEndMap(Map&String, String& linksetEndMap) {
this.linksetEndMap = linksetEndM
public Map&String, String& getContentStartMap() {
return contentStartM
public void setContentStartMap(Map&String, String& contentStartMap) {
this.contentStartMap = contentStartM
public Map&String, String& getContentEndMap() {
return contentEndM
public void setContentEndMap(Map&String, String& contentEndMap) {
this.contentEndMap = contentEndM
队列 Queue.java
package mon.
import java.util.LinkedL
* @author javacoo
* @param &T&
public class Queue&T& {
private LinkedList&T& queue = new LinkedList&T&();
* @param t
public void enQueue(T t){
queue.addLast(t);
* @return t
public T deQueue(){
return queue.removeFirst();
* 判断队列是否为空
public boolean isEmpty(){
return queue.isEmpty();
* 判断队列是否含有t
* @param t
public boolean contains(T t){
return queue.contains(t);
* 取得队列大小
public int getSize(){
return queue.size();
URL队列 UrlQueue.java
package mon.
import java.util.HashS
import java.util.M
import java.util.S
import org.springframework.util.CollectionU
* @author javacoo
* @param &Map&String, String&&
public class UrlQueue {
/**已访问URL集合*/
private Set&Map&String, String&& visitedUrl = new HashSet&Map&String, String&&();
/**待访问URL集合*/
private Queue&Map&String, String&& unVisitedUrl = new Queue&Map&String, String&&();
* 获得 URL 队列
public Queue&Map&String, String&& getUnVisitedUrl() {
return unVisitedU
* 未访问的 URL 出队列
public Map&String, String& unVisitedUrlDeQueue() {
return unVisitedUrl.deQueue();
* 保证每个 URL 只被访问一次
* @param url
public void addUnVisitedUrl(Map&String, String& urlMap) {
if (!CollectionUtils.isEmpty(urlMap) && !unVisitedUrl.contains(urlMap) && !visitedUrl.contains(urlMap)){
unVisitedUrl.enQueue(urlMap);
* 判断是否为空
public boolean isEmpty(){
return unVisitedUrl.isEmpty();
* 未访问URL数量
public int getUnVisitedUrlNum(){
return unVisitedUrl.getSize();
* 添加到访问过的URL队列中
* @param urlMap
public void addVisitedUrl(Map&String, String& urlMap){
visitedUrl.add(urlMap);
* 删除访问过的URL
* @param urlMap
public void removeVisitedUrl(Map&String, String& urlMap){
visitedUrl.remove(urlMap);
* 已访问URL数量
public int getVisitedUrlNum(){
return visitedUrl.size();
接下来是XML配置
==============================定时任务模块XML配置====================================
&bean id="cmsSchedulerDao" class="com.jeecms.cms.dao.assist.impl.CmsSchedulerDaoImpl"/&
manage配置
&bean id="cmsSchedulerMng" class="com.jeecms.cms.manager.assist.impl.CmsSchedulerMngImpl"/&
SERVICE配置
&bean id="schedulerAcquisitionSvc" class="com.jeecms.cms.service.scheduler.SchedulerAcquisitionSvcImpl"/&
&bean id="schedulerTaskManageSvc" class="com.jeecms.cms.service.scheduler.SchedulerTaskManageSvcImpl"/&
接下来是messages_zh_CN.properties 添加了常量
==============================messages_zh_CN.properties====================================}

我要回帖

更多关于 task定时任务不执行 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信