web定时任务实例

时间:2021-10-23 07:49:19

定时任务很常用,在此写个例子做一下展示。

例子很简单,利用servlet的load-on-startup配置在init方法中启动一个定时器。

在需要的时间点启动任务即可。

 

web.xml配置

  <!-- lsy测试   -->
  <servlet>
    <servlet-name>lsytestServlet</servlet-name>
    <servlet-class>com.xxx.lsy.LsyTestServlet</servlet-class>
    
    <init-param>
      <param-name>dataSourceName</param-name>
      <param-value>data1</param-value>
    </init-param>
    
    <load-on-startup>5</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>lsytestServlet</servlet-name>
    <url-pattern>/lsytestServlet</url-pattern>
  </servlet-mapping>


定时任务一般会和数据库打交道,这里我简单写了个数据库操作的任务,所以把数据库jdbc的部分封装了一下。

package com.sunyard.hawaii.lsy;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.naming.Context;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sunyard.hawaii.lsy.sql.LsySqlUtil;
import com.sunyard.hawaii.lsy.sql.TimerTaskOne;

/**
 * 内容1:
 * 利用servlet配置中的load-on-startup在web应用启动后,servlet调用init方法。
 * 在这个过程中可以初始化数据源,同时可以做一些其他操作,例如启动一个定时任务等。
 * 注意load-on-startup范围是1-10,数字越大,优先级越小,启动越往后。
 * 
 * 内容2:
 * 把jdbc结果集封装到一个map中,包括字段名和值
 * 数据库使用db2
 * 
 * @author lushuaiyin
 *
 */
public class LsyTestServlet extends HttpServlet {
	
	public ServletContext servletContext=null;
	public HttpServletRequest httpServletRequest=null;
	public Context ctx = null;
	
	public void init() throws ServletException {
		System.out.println("LsyTestServlet  init --------------------------------");
		
		this.servletContext= this.getServletContext();
		
		//获取web.xml配置中的初始化参数
		String dataSourceName=this.getInitParameter("dataSourceName");
		if(dataSourceName==null||dataSourceName.trim().equals("")){
			System.out.println("初始化参数dataSourceName 未获取到!");
		}else{
			System.out.println("初始化参数dataSourceName :"+dataSourceName);
			
		}
		
		//定时任务
		Timer timer = new Timer();
		TimerTask tt1=new TimerTaskOne("task111");
		
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date startPoint_date=null;
		String startPoint_Str="2013-08-16 08:37:15";
		int taskPeriod=20000;//毫秒
		try {
			startPoint_date=sdf.parse(startPoint_Str);
			System.out.println("开始执行任务时间点:"+startPoint_Str+",此后每隔"+taskPeriod+"毫秒执行一次任务。");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		timer.scheduleAtFixedRate(tt1, startPoint_date, taskPeriod);
	}
	
	public void destroy(){
		System.out.println("LsyTestServlet  destroy --------------------------------");
    }

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		doPost( req, resp);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		resp.setHeader("cache-control", "no-cache");
		req.setCharacterEncoding("GBK");
		resp.setContentType("text/plain; charset=GBK");
		
		
		work( req, resp);
	}
	
	protected void work(HttpServletRequest request, HttpServletResponse resp)
			throws ServletException, IOException {
		PrintWriter out = resp.getWriter();
		HttpSession session = request.getSession();
		
		
		System.out.println(request.getParameter("startTime"));
		if(request.getParameter("enforceStartTask")!=null&&!request.getParameter("enforceStartTask").trim().equals("")){
			if(request.getParameter("enforceStartTask").trim().equals("1")){
				
				TimerTask task111=new TimerTaskOne("task111");
				Thread th1=new Thread(task111);
				th1.start();
				
				System.out.println("收到强制启动定时任务命令,开启一次定时任务。。。");
			}
		}
		
		out.println("success");
		
	}
	

}

 

package com.sunyard.hawaii.lsy.sql;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 一个定时任务
 * 这里只是简单的查表并更新字段。
 * 
 * @author lushuaiyin
 *
 */
public class TimerTaskOne extends TimerTask{
	
	String name;
	public TimerTaskOne(String name){
		this.name=name;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long startTime=new Date().getTime();
		System.out.println("");
		System.out.println("执行一次任务:开始时间"+sdf.format(new Date()));
		
		
		String sql = "select id,cname,bak,flag  from LSY_TEST";
		Map resultData=LsySqlUtil.getInstancce().selectSql(sql);
		if(resultData!=null){
			Iterator it=resultData.keySet().iterator();
			for(;it.hasNext();){
				Object key=it.next();
				Object value=resultData.get(key);
				
				Pattern p=Pattern.compile("^[0-9]+$");
				Matcher m=p.matcher(key.toString());
				if(m.find()){
					Map row=(Map)value;
					String id=(String)row.get("ID");
					String bak=(String)row.get("BAK");
					if(id!=null&&!id.trim().equals("")){
						String updateSql="update LSY_TEST " +
								"set CDATE=date('"+sdf.format(new Date())+"') " +
								" where ID="+id.trim();
						LsySqlUtil.getInstancce().executeSql(updateSql);
						System.out.println(updateSql);
					}
				}//end if
			}// end for
		}//end if
		
		long endTime=new Date().getTime();
		long spend=endTime-startTime;
		System.out.println("任务结束时间:"+sdf.format(new Date())+",花费时间:"+String.valueOf(spend)+"毫秒。");
		
	}

}



 

package com.sunyard.hawaii.lsy.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 封装了jdbc底层操作,数据库使用db2
 * 查询功能把jdbc结果集封装到一个map中,包括字段名和值
 * 
 * 使用了单例模式
 * 
 * @author lushuaiyin
 *
 */
public class LsySqlUtil {
	
	public static final String DB2_URL = "jdbc:db2://127.0.0.1:50000/example";
	public static final String DB2_USERNAME = "db2admin";
	public static final String DB2_PASSWORD = "db2admin";

	public Connection con = null;
	public PreparedStatement stmt = null;
	
	public static LsySqlUtil lsySqlUtil=null;
	
	public static LsySqlUtil getInstancce(){
		if(lsySqlUtil==null){
			lsySqlUtil=new LsySqlUtil();
		}
		return lsySqlUtil;
	}
	
	public Connection getConnection() {
		try {
			if (con == null || con.isClosed()) {// 数据库操作
				Class.forName("com.ibm.db2.jcc.DB2Driver");
				con = DriverManager.getConnection(DB2_URL, DB2_USERNAME,
						DB2_PASSWORD);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return con;
	}
	public void close() {
		try {
			if (stmt != null) {
				stmt.close();
			}
			if (con != null) {
				con.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public Map selectSql(String sql) {
		Map resultData = new LinkedHashMap();// 结果集,序号key即第几条;value是一个map,存放一条数据,key是数据库字段名,值是字段值。
		if(sql==null||sql.trim().equals("")){
			
		}else{
			// 数据库操作
			try {
				stmt = getInstancce().getConnection().prepareStatement(sql);
				
				ResultSet rs = stmt.executeQuery();
				System.out.println("rs.getType() :" + rs.getType()
						+ ",rs.getFetchSize():" + rs.getFetchSize());
				Map tableColumns = new HashMap();
				tableColumns = getResultColumns(rs);
				resultData.put("tableColumns", tableColumns);

				int rowNum = 0;
				while (rs.next()) {
					rowNum = rs.getRow();
					Map oneRowData = getRowMapFromResultRow(rs, tableColumns);
					resultData.put(rowNum, oneRowData);
				}

				System.out.println("获取最后结果集Map大小:" + resultData.size());
				System.out.println("获取最后结果集Map内容:" + resultData.toString());
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					getInstancce().close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		return resultData;
	}
	
	
	//insert delete update 
	public int executeSql(String sql) {
		int res = 0;
		if(sql==null||sql.trim().equals("")){
			
		}else{
			// 数据库操作
			try {
				stmt = getInstancce().getConnection().prepareStatement(sql);
				
				res= stmt.executeUpdate();
				/*
				 Returns:
					either (1) the row count for SQL Data Manipulation Language (DML) statements 
					or (2) 0 for SQL statements that return nothing
				 */
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					getInstancce().close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		return res;
	}

	// 获取结果集的所有字段名放入一个map中
	public static Map getResultColumns(ResultSet rs) {
		Map tableColumns = new HashMap();
		try {
			ResultSetMetaData rsMetaData = rs.getMetaData();
			for (int i = 1; i < rsMetaData.getColumnCount() + 1; i++) {
				System.out.println("结果集列信息:" + rsMetaData.getColumnName(i)
						+ "------" + "getColumnLabel :"
						+ rsMetaData.getColumnLabel(i) + ",getColumnName :"
						+ rsMetaData.getColumnName(i) + ",rgetColumnType :"
						+ rsMetaData.getColumnType(i) + ",getColumnTypeName :"
						+ rsMetaData.getColumnTypeName(i) + ",getTableName :"
						+ rsMetaData.getTableName(i));
				tableColumns.put(i, rsMetaData.getColumnName(i));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return tableColumns;
	}

	// 把结果集中的一条数据放到一个map中
	public static Map getRowMapFromResultRow(ResultSet rs, Map tableColumns) {
		Map rowObj = new HashMap();

		if (tableColumns == null) {

		} else {
			try {
				Iterator it = tableColumns.keySet().iterator();
				while (it.hasNext()) {
					Object key = it.next();
					String value_columnName = (String) tableColumns.get(key);
					value_columnName = value_columnName == null ? ""
							: value_columnName.trim();
					rowObj.put(value_columnName, rs.getString(value_columnName));
				}
				System.out.println("一条记录:" + rowObj.toString());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return rowObj;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String sql = "select id,cname,bak,flag  from LSY_TEST";
		Map resultData=LsySqlUtil.getInstancce().selectSql(sql);
	}

}


附上表结构:

CREATE TABLE AGENT.LSY_TEST (
  ID	INTEGER	NOT NULL,
  CNAME	VARCHAR(100),
  CDATE	DATE,
  BAK	VARCHAR(100),
  FLAG	INTEGER
  ) 
  IN USERSPACE1;

ALTER TABLE AGENT.LSY_TEST
  DATA CAPTURE NONE
  PCTFREE 0
  LOCKSIZE ROW
  APPEND OFF
  NOT VOLATILE;

COMMENT ON AGENT.LSY_TEST ( 
	ID IS '主键',
	CNAME IS '名称',
	BAK IS '备注',
	FLAG IS '标志' );


启动工程,定时任务控制台打印(其中也可以强制法命令启动任务,具体看代码):

2013-8-16 8:36:21 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-80
2013-8-16 8:36:21 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 265 ms
2013-8-16 8:36:21 org.apache.catalina.core.StandardService start
信息: Starting service Catalina
2013-8-16 8:36:21 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/5.0.28
2013-8-16 8:36:21 org.apache.catalina.core.StandardHost start
信息: XML validation disabled
2013-8-16 8:36:21 org.apache.catalina.core.StandardHost getDeployer
信息: Create Host deployer for direct deployment ( non-jmx ) 
2013-8-16 8:36:21 org.apache.catalina.core.StandardHostDeployer install
信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\admin.xml
2013-8-16 8:36:21 org.apache.struts.util.PropertyMessageResources <init>
信息: Initializing, config='org.apache.struts.util.LocalStrings', returnNull=true
2013-8-16 8:36:21 org.apache.struts.util.PropertyMessageResources <init>
信息: Initializing, config='org.apache.struts.action.ActionResources', returnNull=true
2013-8-16 8:36:21 org.apache.struts.util.PropertyMessageResources <init>
信息: Initializing, config='org.apache.webapp.admin.ApplicationResources', returnNull=true
2013-8-16 8:36:22 org.apache.catalina.core.StandardHostDeployer install
信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\balancer.xml
2013-8-16 8:36:22 org.apache.catalina.core.StandardHostDeployer install
信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\manager.xml
2013-8-16 8:36:22 org.apache.catalina.core.StandardHostDeployer install
信息: Processing Context configuration file URL file:D:\appEclipse\Tomcat5.0\conf\Catalina\localhost\webagent.xml
LsyTestServlet  init --------------------------------
初始化参数dataSourceName :data1
开始执行任务时间点:2013-08-16 08:37:15,此后每隔20000毫秒执行一次任务。
2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install
信息: Installing web application at context path /downfle from URL file:D:\appEclipse\Tomcat5.0\webapps\downfle
2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install
信息: Installing web application at context path /jsp-examples from URL file:D:\appEclipse\Tomcat5.0\webapps\jsp-examples
2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install
信息: Installing web application at context path  from URL file:D:\appEclipse\Tomcat5.0\webapps\ROOT
2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install
信息: Installing web application at context path /servlets-examples from URL file:D:\appEclipse\Tomcat5.0\webapps\servlets-examples
2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install
信息: Installing web application at context path /tomcat-docs from URL file:D:\appEclipse\Tomcat5.0\webapps\tomcat-docs
2013-8-16 8:36:23 org.apache.catalina.core.StandardHostDeployer install
信息: Installing web application at context path /webdav from URL file:D:\appEclipse\Tomcat5.0\webapps\webdav
2013-8-16 8:36:23 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-80
2013-8-16 8:36:23 org.apache.jk.common.ChannelSocket init
信息: JK2: ajp13 listening on /0.0.0.0:8009
2013-8-16 8:36:23 org.apache.jk.server.JkMain start
信息: Jk running ID=0 time=0/63  config=D:\appEclipse\Tomcat5.0\conf\jk2.properties
2013-8-16 8:36:23 org.apache.catalina.startup.Catalina start
信息: Server startup in 1968 ms

执行一次任务:开始时间2013-08-16 08:37:15
rs.getType() :1003,rs.getFetchSize():0
结果集列信息:ID------getColumnLabel :ID,getColumnName :ID,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST
结果集列信息:CNAME------getColumnLabel :CNAME,getColumnName :CNAME,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST
结果集列信息:BAK------getColumnLabel :BAK,getColumnName :BAK,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST
结果集列信息:FLAG------getColumnLabel :FLAG,getColumnName :FLAG,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST
一条记录:{CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}
一条记录:{CNAME=cc2, BAK=b2, ID=12, FLAG=0}
一条记录:{CNAME=cc3, BAK=b33, ID=13, FLAG=0}
一条记录:{CNAME=cc4, BAK=b4, ID=14, FLAG=1}
一条记录:{CNAME=cc5, BAK=b5, ID=15, FLAG=1}
获取最后结果集Map大小:6
获取最后结果集Map内容:{tableColumns={1=ID, 2=CNAME, 3=BAK, 4=FLAG}, 1={CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}, 2={CNAME=cc2, BAK=b2, ID=12, FLAG=0}, 3={CNAME=cc3, BAK=b33, ID=13, FLAG=0}, 4={CNAME=cc4, BAK=b4, ID=14, FLAG=1}, 5={CNAME=cc5, BAK=b5, ID=15, FLAG=1}}
update LSY_TEST set CDATE=date('2013-08-16 08:37:15')  where ID=11
update LSY_TEST set CDATE=date('2013-08-16 08:37:15')  where ID=12
update LSY_TEST set CDATE=date('2013-08-16 08:37:15')  where ID=13
update LSY_TEST set CDATE=date('2013-08-16 08:37:15')  where ID=14
update LSY_TEST set CDATE=date('2013-08-16 08:37:15')  where ID=15
任务结束时间:2013-08-16 08:37:15,花费时间:375毫秒。

执行一次任务:开始时间2013-08-16 08:37:35
rs.getType() :1003,rs.getFetchSize():0
结果集列信息:ID------getColumnLabel :ID,getColumnName :ID,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST
结果集列信息:CNAME------getColumnLabel :CNAME,getColumnName :CNAME,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST
结果集列信息:BAK------getColumnLabel :BAK,getColumnName :BAK,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST
结果集列信息:FLAG------getColumnLabel :FLAG,getColumnName :FLAG,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST
一条记录:{CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}
一条记录:{CNAME=cc2, BAK=b2, ID=12, FLAG=0}
一条记录:{CNAME=cc3, BAK=b33, ID=13, FLAG=0}
一条记录:{CNAME=cc4, BAK=b4, ID=14, FLAG=1}
一条记录:{CNAME=cc5, BAK=b5, ID=15, FLAG=1}
获取最后结果集Map大小:6
获取最后结果集Map内容:{tableColumns={1=ID, 2=CNAME, 3=BAK, 4=FLAG}, 1={CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}, 2={CNAME=cc2, BAK=b2, ID=12, FLAG=0}, 3={CNAME=cc3, BAK=b33, ID=13, FLAG=0}, 4={CNAME=cc4, BAK=b4, ID=14, FLAG=1}, 5={CNAME=cc5, BAK=b5, ID=15, FLAG=1}}
update LSY_TEST set CDATE=date('2013-08-16 08:37:35')  where ID=11
update LSY_TEST set CDATE=date('2013-08-16 08:37:35')  where ID=12
update LSY_TEST set CDATE=date('2013-08-16 08:37:35')  where ID=13
update LSY_TEST set CDATE=date('2013-08-16 08:37:35')  where ID=14
update LSY_TEST set CDATE=date('2013-08-16 08:37:35')  where ID=15
任务结束时间:2013-08-16 08:37:35,花费时间:95毫秒。
null
收到强制启动定时任务命令,开启一次定时任务。。。

执行一次任务:开始时间2013-08-16 08:37:46
rs.getType() :1003,rs.getFetchSize():0
结果集列信息:ID------getColumnLabel :ID,getColumnName :ID,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST
结果集列信息:CNAME------getColumnLabel :CNAME,getColumnName :CNAME,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST
结果集列信息:BAK------getColumnLabel :BAK,getColumnName :BAK,rgetColumnType :12,getColumnTypeName :VARCHAR,getTableName :LSY_TEST
结果集列信息:FLAG------getColumnLabel :FLAG,getColumnName :FLAG,rgetColumnType :4,getColumnTypeName :INTEGER,getTableName :LSY_TEST
一条记录:{CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}
一条记录:{CNAME=cc2, BAK=b2, ID=12, FLAG=0}
一条记录:{CNAME=cc3, BAK=b33, ID=13, FLAG=0}
一条记录:{CNAME=cc4, BAK=b4, ID=14, FLAG=1}
一条记录:{CNAME=cc5, BAK=b5, ID=15, FLAG=1}
获取最后结果集Map大小:6
获取最后结果集Map内容:{tableColumns={1=ID, 2=CNAME, 3=BAK, 4=FLAG}, 1={CNAME=lushuaiyin, BAK=b1, ID=11, FLAG=1}, 2={CNAME=cc2, BAK=b2, ID=12, FLAG=0}, 3={CNAME=cc3, BAK=b33, ID=13, FLAG=0}, 4={CNAME=cc4, BAK=b4, ID=14, FLAG=1}, 5={CNAME=cc5, BAK=b5, ID=15, FLAG=1}}
update LSY_TEST set CDATE=date('2013-08-16 08:37:46')  where ID=11
update LSY_TEST set CDATE=date('2013-08-16 08:37:46')  where ID=12
update LSY_TEST set CDATE=date('2013-08-16 08:37:46')  where ID=13
update LSY_TEST set CDATE=date('2013-08-16 08:37:46')  where ID=14
update LSY_TEST set CDATE=date('2013-08-16 08:37:46')  where ID=15
任务结束时间:2013-08-16 08:37:46,花费时间:111毫秒。