Java上传日志至sftp服务器

730 阅读3分钟

本文是本人做项目中遇到的问题,其中有一些坑。欢迎查看与转载: 1、引入SFTP jar包

<dependency>  
	      <groupId>com.jcraft</groupId>  
	      <artifactId>jsch</artifactId>  
	      <version>0.1.53</version>  
	</dependency> 

2、写定时器类,定时上传至sftp服务器

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.jcraft.jsch.SftpException;
	@Component
public class FtpUploadLogTask extends AbstractBaseTask {

Logger logger = LoggerFactory.getLogger(FtpUploadLogTask.class);

private static final ResourceBundle bundle = java.util.ResourceBundle.getBundle("config");

private String ftpIp = bundle.getString("ftpIp");

private String ftpUser = bundle.getString("ftpUser");

private int ftpPort = Integer.parseInt(bundle.getString("ftpPort"));

private String ftpPwd = bundle.getString("ftpPwd");

private String ftpRemotePath = bundle.getString("ftpRemotePath");

private String localAddress =  bundle.getString("localAddress");

private LoadLogService loadLogService;


@SuppressWarnings("unused")
private Map<String, Object> map;

FtpUtils ftpUtils = new FtpUtils();
SFtpUtils sfTpUtils = new SFtpUtils();

@Override
public void init() {
	
}

@Override
public void work() {
	logger.info("********上传登陆日志文件定时任务开始********");
	try {
		uploadTxtToFtp();
	} catch (SftpException e) {
		logger.error("********上传登陆日志文件定时任务失败:{}********", e);
	}
	logger.info("********上传登陆日志文件定时任务结束********");
}  

public void uploadTxtToFtp() throws SftpException {
	LogInfo logInfo = new LogInfo(this, Thread.currentThread().getStackTrace()[1].getMethodName());
	SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
	Map<String, Object> result = new HashMap<>();
	loadLogService = (LoadLogService) SpringContextUtil.getBean("loadLogService");
	// 登录日志表当天所有记录
	List<LoadLog> list = new ArrayList<LoadLog>();
	list = loadLogService.getLoadLogListBefore();
	String filePath = "";
	if (list != null && list.size() > 0) {
		filePath = FileReadUtil.createDatFile(list);
	}
	Date today = new Date();
	Date yesterday = new Date(today.getTime() - FtpConstant.ONE_DAY_MIL);
	String dateStr = formatter.format(yesterday).replace(" ", "");
	String fileName = "lnv_loadLog" + dateStr + "_00001.xml";
	// Windows下
	//	String originfilename = localAddress + "\\" + fileName;
	// Linux下
	String originfilename = localAddress + File.separator + fileName;
	try {
		Boolean booleanResult = false;
		sfTpUtils.setIp(ftpIp);
		sfTpUtils.setUserName(ftpUser);
		sfTpUtils.setPort(ftpPort);
		sfTpUtils.setPassword(ftpPwd);
		sfTpUtils.setSrc(originfilename);
		sfTpUtils.setDst(ftpRemotePath);
		booleanResult = sfTpUtils.put();
		if (booleanResult) {
			result.put("result", "success");
			result.put("msg", "上传成功");
		} else {
			result.put("result", "error");
			result.put("msg", "上传失败");
		}
	} catch (Exception e) {
		e.printStackTrace();
		result.put("result", "error");
		result.put("msg", "上传失败");
	} finally {
		logInfo.setResponseObject(result);
		logger.info(logInfo.toJson());
	}
}

/**
 * 自己需要含参构造且注入service
 * @param map
 */
public FtpUploadLogTask(Map<String, Object> map) {
	super();
	loadLogService = (LoadLogService) SpringContextUtil.getBean("loadLogService");
	this.map = map;
}

public FtpUploadLogTask() {
	super();
}

/**
 * @Title: addDay 
 * @Description: 增加或减少天数  
 * @param date
 * @param num
 * @return 
 * @return: Date
 * @throws
 */
public Date addDay(Date date, int num) {  
    Calendar startDT = Calendar.getInstance();  
    startDT.setTime(date);
    startDT.add(Calendar.DAY_OF_MONTH, num);  
    return startDT.getTime();  
}

此时有个坑,loadLogService调用为null

所以,需要用SpringContextUtil 先实例化 loadLogService loadLogService = (LoadLogService) SpringContextUtil.getBean("loadLogService");

3、Service 层

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.jcraft.jsch.SftpException;


/**
 * @ClassName: LoadLogService 
 * @Description: 查询登陆日志
 */
@Service("loadLogService")
public class LoadLogService {
	
	Logger logger = LoggerFactory.getLogger(LoadLogService.class);
	
	@Autowired
	LoadLogRepository loadLogRepository;
	
	private static final ResourceBundle bundle = java.util.ResourceBundle.getBundle("config");
	
	private String localAddress =  bundle.getString("localAddress");
	
	private String ftpIp = bundle.getString("ftpIp");
	
	private String ftpUser = bundle.getString("ftpUser");
	
	private int ftpPort = Integer.parseInt(bundle.getString("ftpPort"));
	
	private String ftpPwd = bundle.getString("ftpPwd");
	
	private String ftpRemotePath = bundle.getString("ftpRemotePath");
	
	
	/**
	 * @Title: getLoadLogListBefore 
	 * @Description: 获取昨天的记录(测试)
	 * @return 
	 * @return: List<LoadLog>
	 * @throws
	 */
	public List<LoadLog> getLoadLogListBefore(){
		return loadLogRepository.getLoadLogListBefore();
	}
	
	/**
	 * @Title: uploadTxtToFtp 
	 * @Description: 上传日志文件到sftp服务器
	 * @throws SftpException 
	 * @return: void
	 * @throws
	 */
	public void uploadTxtToFtp() throws SftpException {
		LogInfo logInfo = new LogInfo(this, Thread.currentThread().getStackTrace()[1].getMethodName());
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		SFtpUtils sfTpUtils = new SFtpUtils();
		Map<String, Object> result = new HashMap<>();
		LoadLogService loadLogService = (LoadLogService) SpringContextUtil.getBean("loadLogService");
		// 登录日志表当天所有记录
		List<LoadLog> list = new ArrayList<LoadLog>();
		list = loadLogService.getLoadLogListBefore();
		String param = "";
		String filePath = "";
		if (list != null && list.size() > 0) {
			// list 转换成json格式的字符串
			try {
				param = FtpUtils.ObjListConvertToString(list);
			} catch (IOException e) {
				e.printStackTrace();
			}
			filePath = FileReadUtil.createDatFile(list);
		}
		// 组装字符串成json格式
		param = param.replace("[", "");
		param = param.replace("]", "");
		param = "{".concat(param);
		param = param.concat("}");
		
		JSONObject jsonObject = JSONObject.parseObject(param);
		byte[] bytes = null;
		try {
			bytes = DatUtil.encode(FtpConstant.CM_ID, jsonObject, FtpConstant.MSG_SEQ);
		} catch (Exception e) {
			e.printStackTrace();
		}
		FileReadUtil.outByFileDataOutputStream(filePath, bytes);
		
		Date today = new Date();
		Date yesterday = new Date(today.getTime() - FtpConstant.ONE_DAY_MIL);
		String dateStr = formatter.format(yesterday).replace(" ", "");
		String fileName = "lnv_loadLog" + dateStr + "_00001.dat";
		String originfilename = localAddress  + fileName;
		try {
			Boolean booleanResult = false;
			sfTpUtils.setIp(ftpIp);
			sfTpUtils.setUserName(ftpUser);
			sfTpUtils.setPort(ftpPort);
			sfTpUtils.setPassword(ftpPwd);
			sfTpUtils.setSrc(originfilename);
			sfTpUtils.setDst(ftpRemotePath);
			booleanResult = sfTpUtils.put();
			if (booleanResult) {
				result.put("result", "success");
				result.put("msg", "上传成功");
			} else {
				result.put("result", "error");
				result.put("msg", "上传失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "error");
			result.put("msg", "上传失败");
		} finally {
			logInfo.setResponseObject(result);
			logger.info(logInfo.toJson());
		}
	}
}

4、工具类

import java.util.Properties;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;	
/**
 * @ClassName: SFtpUtils 
 * @Description: SFTP 上传文件工具类
 */
public class SFtpUtils {	
	/**
	 * ftp服务的地址 (ip)
	 */
	public String ip;
	/**
	 * sftp服务器的端口号 默认22
	 */
	public int port;
	/**
	 * sftp服务器的登入帐号
	 */
	public String userName;
	/**
	 * sftp服务器的登入密码
	 */
	public String password;
	/**
	 * 连接超时时间
	 */
	public int timeout = 60000;
	/**
	 * 将要上传的文件地址(网络地址没试过)
	 */
	public String src;
	/**
	 * 要保存到服务器的文件地址和名称(最好带后缀,如果不带后缀会变成未知文件)
	 */
	public String dst;
	/**
	 * 尝试重复几次上传(未支持)
	 */
	public int retryTime = 3;
	// set、get方法省略
	}

5、beas-task.xml文件:配置定时器执行时间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd">

	<task:annotation-driven/>
	
	<bean id="ftpUploadLogTask" class="com.xxx.job.task.FtpUploadLogTask" />
	
	<task:scheduled-tasks>
		<task:scheduled ref="ApiTask" method="work" cron="0 0/30 * * * ?"/>
		<task:scheduled ref="redisSyncAreaTask" method="work" cron="0 0/30 * * * ?"/>
		
		<!-- 添加设备 统计 定时任务-->
		<task:scheduled ref="rStatTask" method="work" cron="0 5 0 * * ?"/>
		<!-- 添加上传登陆日志文件 定时任务  凌晨2点 -->
		<task:scheduled ref="ftpUploadLogTask" method="work" cron="0 0 2 * * ?" />
	</task:scheduled-tasks>
</beans>

6、修改定时任务时间,查看是否可以正常上传至sftp服务器

我是进阶的球儿,大家一起2019年的爬坑历程。感觉分享很给力的话给个赞,谢谢!!!有问题也可以下方留言沟通。