项目中需要实现每天凌晨1点定时去FTP上读取文件插入数据库,这样一个定时任务,下面将这个功能分享如下:
先写一个任务调度的的类:采用了spring 的quartz 很简单:
package com.longtop.ecommerce.service.dept.quartz;
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import com.longtop.ecommerce.service.dept.OrgService;
/**
* 定时任务调度类
* @author tony
*
*/
public class QuartzJob {
public static Logger log = Logger.getLogger(QuartzJob.class);
OrgService orgService;
public OrgService getOrgService() {
return orgService;
}
public void setOrgService(OrgService orgService) {
this.orgService = orgService;
}
public void work(){
try{
log.info("系统更新机构信息处理任务开始>........");
//业务逻辑代码调用
orgService.deleteOrgInfo();
orgService.addOrgInfo();
orgService.updateOrgInfos("2");
orgService.updateOrgInfos("4");
orgService.updateOrgInfos("6");
orgService.updateOrgInfos("8");
log.info("系统更新机构信息处理任务结束!");
}catch(Exception e){
log.error("系统更新机构信息任务出现异常",e);
}
}
/**
* 第二种方式,此方法需要继承QuartzJobBean
*/
/*protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
// TODO Auto-generated method stub
try{
log.info("系统更新机构信息处理任务开始>........");
ApplicationContext context = new ClassPathXmlApplicationContext("config/spring/spring-quartz.xml");
//如果配置文件中将startQuertz bean的lazy-init设置为false 则不用实例化
orgService = (OrgService) context.getBean("orgService");
orgService.addOrgInfo();
//业务逻辑代码调用
log.info("系统更新机构信息任务结束!");
}catch(Exception e){
log.error("系统更新机构信息任务出现异常",e);
}
}*/
}
下面是spring-quartz.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--
<bean name="jobtask" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.longtop.ecommerce.service.dept.quartz.QuartzJob</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="timeout">
<value>5</value>
</entry>
</map>
</property>
</bean>
-->
<bean id="orgService" class="com.longtop.ecommerce.service.dept.OrgServiceImpl" >
<property name="cifwContext" ref="cifwContext"></property>
</bean>
<!-- 要调用的工作类 -->
<bean id="quartzJob" class="com.longtop.ecommerce.service.dept.quartz.QuartzJob" >
<property name="orgService" ref="orgService"></property>
</bean>
<!-- 定义调用对象和调用对象的方法 -->
<bean id="jobtask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="quartzJob"/>
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>work</value>
</property>
</bean>
<!-- 定义触发时间 -->
<bean id="doTime" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="jobtask"/>
</property>
<!-- cron表达式 -->
<property name="cronExpression">
<!-- 每隔5秒钟执行一次
<value>10,15,20,25,30,35,40,45,50,55 * * * * ?</value>
-->
<!-- 每分钟第五秒执行
<value>5 * * * * ?</value>
-->
<!-- 定时执行-->
<value>0 27 16 * * ?</value>
<!--每天一点钟执行一次
<value>* * 1 * * ?</value>
-->
</property>
</bean>
<!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
<bean id="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="doTime"/>
</list>
</property>
</bean>
</beans>
定时任务就这样简单,应用启动后会执行任务,别忘记将配置文件在web.xml里加载。
下面是去FTP读取文件的详细过程:
package com.longtop.ecommerce.service.dept;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import com.longtop.ecommerce.bo.Organization;
/**
* 从FTP读取文件
* @author tony
*
*/
public class FtpUtils {
private FTPClient ftpClient;
private String fileName, strencoding;
private int columns, rowCount;
private String ip = "65.0.15.26"; //服务器IP地址
private String userName = "anonymous"; //用户名
private String userPwd = "anonymous"; //密码
private int port = 21; //端口号
private String path = "/aaa/CIC_Department/"; //读取文件的存放目录
/**
* init ftp servere
*/
public FtpUtils() {
this.reSet();
}
public void reSet(){
//以当前系统时间拼接文件名
fileName = "t_department_"+getFileName()+".txt";
columns = 0;
rowCount = 0;
strencoding = "GBK";
this.connectServer(ip, port, userName, userPwd, path);
}
/**
* 以当前系统时间生成文件名
* @return
*/
private String getFileName(){
SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMdd");
String str = "";
try {
str = sdFormat.format(new Date());
}
catch(Exception e) {
return "";
}
if (str.equals("1900-01-01")) {
str = "";
}
return str;
}
/**
* @param ip
* @param port
* @param userName
* @param userPwd
* @param path
* @throws SocketException
* @throws IOException
* function:连接到服务器
*/
public void connectServer(String ip , int port , String userName , String userPwd , String path){
ftpClient = new FTPClient();
try {
// 连接
ftpClient.connect(ip, port);
// 登录
ftpClient.login(userName, userPwd);
if(path != null && path.length() > 0){
// 跳转到指定目录
ftpClient.changeWorkingDirectory(path);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @throws IOException
* function:关闭连接
*/
public void closeServer(){
if(ftpClient.isConnected()){
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* @param path
* @return
* function:读取指定目录下的文件名
* @throws IOException
*/
public List<String> getFileList(String path){
List<String> fileLists = new ArrayList<String>();
// 获得指定目录下所有文件名
FTPFile[] ftpFiles = null;
try {
ftpFiles = ftpClient.listFiles(path);
} catch (IOException e) {
e.printStackTrace();
}
for(int i = 0 ; ftpFiles != null && i < ftpFiles.length ; i++){
FTPFile file = ftpFiles[i];
if(file.isFile()){
fileLists.add(file.getName());
}
}
return fileLists;
}
/**
* @param fileName
* @param sourceFile
* @return
* @throws IOException
* function:下载文件
*/
public boolean unloadFile(String fileName , String sourceFile){
boolean flag = false;
try{
FileOutputStream fos = new FileOutputStream(fileName);
flag = ftpClient.retrieveFile(sourceFile, fos);
fos.flush();
fos.close();
}catch(Exception e){
flag = false;
e.printStackTrace();
}
return flag;
}
/**
* 返回一个文件流
* @param fileName
* @return
*/
public String readFile(String fileName){
String result = "";
InputStream ins = null;
try {
ins = ftpClient.retrieveFileStream(fileName);
// byte []b = new byte[ins.available()];
// ins.read(b);
BufferedReader reader=new BufferedReader(new InputStreamReader(ins));
String inLine = reader.readLine();
while (inLine != null) {
result += (inLine + System.getProperty("line.separator"));
inLine = reader.readLine();
}
reader.close();
if(ins != null){
ins.close();
}
// 主动调用一次getReply()把接下来的226消费掉. 这样做是可以解决这个返回null问题
ftpClient.getReply();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* @param fileName
* @return
* function:从服务器上读取指定的文件
* @throws ParseException
* @throws IOException
*/
public List readFile() throws ParseException{
List<Organization> contentList = new ArrayList<Organization>();
InputStream ins = null;
try {
//从服务器上读取指定的文件
ins = ftpClient.retrieveFileStream(fileName);
BufferedReader reader=new BufferedReader(new InputStreamReader(ins,strencoding));
String inLine = reader.readLine();
while (inLine != null) {
if (inLine.length() + 1 > columns)
columns = inLine.length() + 1;
String beanStr = inLine+System.getProperty("line.separator");
if(beanStr.indexOf(",")>0){
String[] beanStrs = beanStr.split(",");
Organization org = new Organization();
DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
date = format1.parse(beanStrs[0].substring(1, beanStrs[0].length()-1));
org.setBuildDate(date);
String parentId = null;
if((beanStrs[1].substring(1, beanStrs[1].length()-1)).equals("")){
parentId = "00";//默认值,表示顶级机构
org.setOrgLevel("00");//机构级别为00
}else parentId = (beanStrs[1].substring(1, beanStrs[1].length()-1));
org.setParentId(parentId);//去掉引号
org.setOrgCode(beanStrs[2].substring(1, beanStrs[2].length()-1));
org.setOrgBrief(beanStrs[3].substring(1, beanStrs[3].length()-1));
if(beanStrs[4].length()>3){
org.setOrgName(beanStrs[4].substring(1, beanStrs[4].length()-3));
}
contentList.add(org);
}
inLine = reader.readLine();
rowCount++;
}
reader.close();
if(ins != null){
ins.close();
}
// 主动调用一次getReply()把接下来的226消费掉. 这样做是可以解决这个返回null问题
ftpClient.getReply();
System.out.println("此次任务一共读取["+contentList.size()+"]条数据记录");
} catch (IOException e) {
e.printStackTrace();
}
return contentList;
}
/**
* @param fileName
* function:删除文件
*/
public void deleteFile(String fileName){
try {
ftpClient.deleteFile(fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param args
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
FtpUtils ftp = new FtpUtils();
ftp.readFile();
/*ftp.unloadFile("D:\\test_t_department.txt", "t_department_20110623.txt");
List<String> files = ftp.getFileList(path);
for(int i = 0 ; i < files.size() ; i++){
String fileName = files.get(i);
ftp.unloadFile("D:\\test", "t_department_20110623.txt");
System.out.println(fileName);
String result = ftp.readFile("t_department_20110623.txt");
System.out.println(result);
ftp.deleteFile(fileName);
}*/
}
这样定时去FTP读取文件的调度任务的功能就完成了。希望对有需要的人提供帮助。此过程中如果有问题可以相互交流。email: [email protected]
}