将前端上传的文件同步到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 exceptionlog.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 exceptionlog.error("", e);}try {Vector<ChannelSftp.LsEntry> entries = channelSftp.ls(remoteDir);log.info("entries->" + entries);//download all from root folderfor (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 directoryPath 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 directoryString 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 blocklog.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;}
}