将前端上传的文件同步到sftp服务器
配置
<!--连接ssh-->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version> <!-- 检查最新版本 -->
</dependency>
@PostMapping("/voice/file/upload")
@ApiOperation("文件--上传录音文件")
public Result uploadFile(UploadVoiceFileReq req, @RequestParam("uploadFile") MultipartFile uploadFile) {
if (CommonUtil.isEmpty(req.getContent())) {
return Result.fail("语音内容不能为空");
}
if (CommonUtil.isEmpty(req.getLanguage())) {
return Result.fail("语音语言类别不能为空");
}
if (CommonUtil.isEmpty(req.getFileName())) {
return Result.fail("文件名称不能为空");
}
String filename = uploadFile.getOriginalFilename();
if (CommonUtil.isEmpty(uploadFile)) {
return Result.fail("上传文件不能为空!");
}
long fileSize = uploadFile.getSize();
if (0 == fileSize) {
return Result.fail("上传文件内容不能为空!");
}
String originalFilename = uploadFile.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
if (ObjectUtil.isEmpty(suffix)) {
return Result.fail("上传文件格式缺失!");
}
if (!suffix.equals("wav")) {
return Result.fail("不支持的文件格式!");
}
VoiceFile voiceFile = new VoiceFile();
// 存储绝对路径
voiceFile.setFilePath(ctiConfig.getFlowFilePath() + filename);
voiceFile.setFileName(filename);
voiceFile.setContent(req.getContent());
if (null == UserContext.getUser()) {
voiceFile.setAuthor("local_test");
} else {
String username = UserContext.getUser().getUsername();
voiceFile.setAuthor(username);
}
voiceFile.setLanguage(req.getLanguage());
voiceFile.setStatus(0);
voiceFile.setDuration(30);
ChannelSftp channel = null;
try {
InputStream inputStream = uploadFile.getInputStream();
channel = (ChannelSftp) SftpUtil.initialChannel(null, sftpCtiConfiguration.getAccountSftp(), sftpCtiConfiguration.getEntranceTicketSftp(), sftpCtiConfiguration.getServerIp(), sftpCtiConfiguration.getPortSftp(), "180000");
if (channel == null) {
log.error(this.getClass().getSimpleName() + "#callVoiceFileList, step0:初始化连接sftp服务器失败!");
return Result.fail("连接服务器(CTI)失败,请排查配置信息!");
}
channel.put(inputStream, ctiConfig.getFlowFilePath() + filename);
} catch (Exception e) {
log.error(getClassName() + "#uploadFile,上传失败!");
e.printStackTrace();
return Result.fail("uploadFile,文件上传发生异常!");
} finally {
SftpUtil.closeChannel(channel);
}
// 上传到sftp服务器
voiceFileService.save(voiceFile);
return Result.ok();
}
sftp工具类
import com.jcraft.jsch.*;
import com.zhuao.constant.BusinessCode;
import com.zhuao.dto.SftpFile;
import com.zhuao.exception.FileBizException;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
@Slf4j
public class SftpUtil {
public static Channel initialChannel(String sshKnownHost, String sftpUsername, String sftpPassword, String sftpHost, String sftpPort, String sftpTimeOut) {
Channel channel = null;
try {
JSch jsch = new JSch();
if (sshKnownHost != null) {
jsch.setKnownHosts(sshKnownHost);
}
Session session = jsch.getSession(sftpUsername, sftpHost, Integer.valueOf(sftpPort));
if (sshKnownHost == null) {
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
}
if (sftpPassword != null) {
session.setPassword(sftpPassword);
}
Integer timeout = 30000;
if (sftpTimeOut != null) {
timeout = Integer.valueOf(sftpTimeOut);
session.setTimeout(timeout);
}
session.connect(timeout);
channel = session.openChannel("sftp");
channel.connect(timeout);
} catch (Exception e) {
log.error("", e);
}
return channel;
}
public static void closeChannel(Channel channel) {
try {
Session session = null;
if (channel != null && channel.isConnected()) {
session = channel.getSession();
channel.disconnect();
}
if (session != null && session.isConnected()) {
session.disconnect();
}
} catch (JSchException e) {
log.error("", e);
}
}
/**
* Download single file from remote to local
*/
public static File download(ChannelSftp channelSftp, String local, String remote) throws SftpException, IOException {
File localFile = new File(local);
FileOutputStream fio = null;
try {
if (!channelSftp.isConnected() || channelSftp.stat(remote) == null) {
return localFile;
}
} catch (Exception e) {
// TODO: handle exception
log.error("", e);
throw e;
}
if (localFile.exists() && localFile.isDirectory()) {
Path filePath = Paths.get(remote);
String fileName = filePath.getFileName().toString();
localFile = new File(localFile, fileName);
} else if (!localFile.exists()) {
try {
localFile.createNewFile();
} catch (Exception e) {
log.error("", e);
throw e;
}
}
try {
fio = new FileOutputStream(localFile);
channelSftp.get(remote, fio);
} catch (Exception e) {
log.error("", e);
throw e;
} finally {
if (fio != null) {
try {
fio.flush();
fio.close();
} catch (Exception e) {
log.error("", e);
}
}
}
return localFile;
}
/**
* Download single file from remote to local by OutputStream
*/
public static void download(ChannelSftp channelSftp, OutputStream fio, String remote) throws SftpException {
try {
if (!channelSftp.isConnected() || channelSftp.stat(remote) == null) {
return;
}
} catch (Exception e) {
log.error("", e);
throw new SftpException(BusinessCode.BusinessStatus.FILE_NOT_EXIST.getCode(), "文件不存在!");
}
try {
channelSftp.get(remote, fio);
} catch (Exception e) {
log.error("", e);
throw new SftpException(BusinessCode.BusinessStatus.FILE_NOT_EXIST.getCode(), "文件不存在");
} finally {
if (fio != null) {
try {
fio.flush();
fio.close();
} catch (Exception e) {
log.error("", e);
throw new SftpException(BusinessCode.BusinessStatus.FILE_DOWNLOAD_FAILED.getCode(), BusinessCode.BusinessStatus.FILE_DOWNLOAD_FAILED.getValue());
}
}
}
}
/**
* Download file folder from remote to local
*/
public static File downloadAll(ChannelSftp channelSftp, String localDir, String remoteDir) {
File localFile = new File(localDir);
FileOutputStream fio = null;
try {
if (!channelSftp.isConnected() || channelSftp.stat(remoteDir) == null) {
return localFile;
}
} catch (Exception e) {
// TODO: handle exception
log.error("", e);
}
try {
Vector<ChannelSftp.LsEntry> entries = channelSftp.ls(remoteDir);
log.info("entries->" + entries);
//download all from root folder
for (ChannelSftp.LsEntry en : entries) {
if (en.getFilename().equals(".") || en.getFilename().equals("..") || en.getAttrs().isDir()) {
continue;
}
System.out.println(en.getFilename());
File localDownloadedFile = new File(localDir + en.getFilename());
if (!localDownloadedFile.exists()) {
localDownloadedFile.createNewFile();
try {
fio = new FileOutputStream(localDownloadedFile);
channelSftp.get(remoteDir + en.getFilename(), fio);
// logger.debug(String.format("Complete get remote file to '%s'", localFile.getName().toString()));
} catch (Exception e) {
log.error("", e);
} finally {
if (fio != null) {
try {
fio.flush();
fio.close();
} catch (Exception e) {
log.error("", e);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fio != null) {
try {
fio.flush();
fio.close();
} catch (Exception e) {
log.error("", e);
}
}
}
return localFile;
}
/**
* 指定路径下的所有文件上传到服务器
*
* @param channelSftp
* @param local
* @param remote
* @throws FileNotFoundException
* @throws SftpException
*/
public static void uploads(ChannelSftp channelSftp, String local, String remote)
throws FileNotFoundException, SftpException {
File localFile = new File(local);
SftpATTRS attrs = null;
if (!localFile.exists()) {
throw new FileNotFoundException();
}
if (!localFile.isDirectory()) {
upload(channelSftp, local, remote);
return;
}
queryAndCreateFolders(channelSftp, remote);
try {
attrs = channelSftp.stat(remote);
} catch (SftpException e) {
channelSftp.mkdir(remote);
attrs = channelSftp.stat(remote);
// e.printStackTrace();
}
if (attrs != null && !attrs.isDir()) {
// Cannot copy directory contains multiple files to a single file, but move to same directory.
remote = Paths.get(remote).getParent().toString();
}
for (File file : localFile.listFiles()) {
if (file.isDirectory()) {
uploads(channelSftp, file.getPath(),
String.format("%s/%s", remote, file.getName()));
continue;
}
FileInputStream fis = null;
try {
fis = new FileInputStream(localFile);
channelSftp.put(fis, String.format("%s/%s", remote, file.getName()));
// logger.debug(String.format("Complete put '%s' to remote", file.getName().toString()));
} catch (FileNotFoundException | SftpException e) {
log.error("", e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
log.error("fis close error...", e);
}
}
}
}
return;
}
/**
* @param channelSftp
* @param local
* @param remote
* @throws FileNotFoundException
* @throws SftpException
* @Description 指定文件(单个)上传到服务器
*/
public static void upload(ChannelSftp channelSftp, String local, String remote) throws FileNotFoundException, SftpException {
File localFile = new File(local);
SftpATTRS attrs = null;
if (!localFile.exists()) {
throw new FileNotFoundException();
}
if (localFile.isDirectory()) {
uploads(channelSftp, local, remote);
return;
}
queryAndCreateFolders(channelSftp, remote);
try {
attrs = channelSftp.stat(remote);
} catch (SftpException e) {
// channelSftp.mkdir(remote);
// e.printStackTrace();
log.error("", e);
}
if (attrs != null && attrs.isDir()) {
// Cannot replace existing directory by file, copy to that directory
Path filePath = Paths.get(local);
String fileName = filePath.getFileName().toString();
remote = String.format("%s/%s", remote, fileName);
}
FileInputStream fis = null;
try {
fis = new FileInputStream(localFile);
channelSftp.put(fis, remote);
// logger.debug(String.format("Complete put '%s' to remote", localFile.getName().toString()));
} catch (FileNotFoundException | SftpException e) {
log.error("", e);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
log.error("fis close error...", e);
}
}
}
return;
}
/**
* Upload single file to remote path
*/
public static void upload(ChannelSftp channelSftp, File localFile, String remote)
throws FileNotFoundException, SftpException {
log.info("execute upload start-->");
SftpATTRS attrs = null;
if (!localFile.exists()) {
throw new FileNotFoundException();
}
queryAndCreateFolders(channelSftp, remote);
try {
attrs = channelSftp.stat(remote);
} catch (SftpException e) {
log.error("channelSftp.stat() error...", e);
}
if (attrs != null && attrs.isDir()) {
// Cannot replace existing directory by file, copy to that directory
String fileName = localFile.getName();
remote = String.format("%s/%s", remote, fileName);
}
log.info("remote-->" + remote);
FileInputStream fis = null;
try {
fis = new FileInputStream(localFile);
channelSftp.put(fis, remote);
// logger.debug(String.format("Complete put '%s' to remote", localFile.getName().toString()));
} catch (FileNotFoundException | SftpException e) {
log.error("", e);
throw new FileBizException(BusinessCode.BusinessStatus.FILE_NOT_EXIST.getCode(), "上傳文件失敗");
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
log.error("fis close error...", e);
}
}
}
log.info("execute upload end");
return;
}
/**
* linux環境,判斷是否存在路徑,不存在則創建
*
* @param channelSftp
* @param filePath
* @throws SftpException
*/
private static void queryAndCreateFolders(ChannelSftp channelSftp, String filePath) throws SftpException {
String[] paths = filePath.split("/");
StringBuilder sb = new StringBuilder();
for (String p : paths) {
if (CommonUtil.isEmpty(p)) {
continue;
}
sb.append("/" + p);
String nextPath = sb.toString();
try {
channelSftp.ls(nextPath);
} catch (Exception e) {
channelSftp.mkdir(nextPath);
}
}
}
public static boolean isExistFile(ChannelSftp sftp, String path) throws SftpException {
boolean isExist = false;
try {
SftpATTRS sftpATTRS = sftp.stat(path);
isExist = true;
} catch (Exception e) {
String errMsg = e.getMessage();
if (!CommonUtil.isEmpty(errMsg) && errMsg.toLowerCase().equals("no such file")) {
isExist = false;
} else {
throw e;
}
}
return isExist;
}
public static void main(String[] args) {
ChannelSftp channelSftp = (ChannelSftp) initialChannel(null, "root", "ZHyjzx@2023!#", "10.152.245.14", "22", "180000");
if (channelSftp == null) {
return;
}
try {
//upload(channelSftp, "C:\\Users\\nigel.szeto\\Desktop\\testFolder", "/mnt/c/Users/nigel.szeto/Desktop/testDes");
//listAllFiles(channelSftp, "/usr/local/isoftcall/data/user/0/flow/");
System.err.println("*******************************************************************");
listAllFileNames(channelSftp, "/usr/local/isoftcall/data/user/0/flow/");
} catch (Exception e) {
// TODO Auto-generated catch block
log.error("", e);
}
closeChannel(channelSftp);
}
public static List<SftpFile> listAllFiles(ChannelSftp sftp, String remoteDir) {
List<SftpFile> sftpFileList = new ArrayList<>();
try {
sftp.ls(remoteDir).forEach(vector -> {
SftpFile sftpFile = new SftpFile();
ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry) vector;
sftpFile.setFilename(lsEntry.getFilename());
sftpFile.setLongname(lsEntry.getLongname());
sftpFile.setSize(lsEntry.getAttrs().getSize());
sftpFile.setAtime(lsEntry.getAttrs().getATime());
sftpFile.setMtime(lsEntry.getAttrs().getMTime());
sftpFile.setFlags(lsEntry.getAttrs().getFlags());
sftpFile.setGid(lsEntry.getAttrs().getGId());
sftpFileList.add(sftpFile);
});
} catch (SftpException e) {
log.error("", e);
}
try {
sftp.getSession().disconnect();
} catch (JSchException e) {
log.error("", e);
}
sftpFileList.stream().forEach(System.out::println);
return sftpFileList;
}
public static List<String> listAllFileNames(ChannelSftp sftp, String remoteDir) {
List<String> fileNameList = new ArrayList<>();
try {
sftp.ls(remoteDir).forEach(vector -> {
ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry) vector;
if (!lsEntry.getAttrs().isDir() && lsEntry.getFilename().endsWith(".wav")) {
fileNameList.add(lsEntry.getFilename());
}
});
} catch (SftpException e) {
log.error("", e);
}
closeChannel(sftp);
fileNameList.stream().forEach(System.out::println);
return fileNameList;
}
}