定时任务很常用,在此写个例子做一下展示。
例子很简单,利用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 (
IDINTEGERNOT NULL,
CNAMEVARCHAR(100),
CDATEDATE,
BAKVARCHAR(100),
FLAGINTEGER
)
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毫秒。