由于在业务中会经常有上传和下载的功能需要实现,所以掌握基本fileUpload技能是必不可少的。当然,从Sftp服务器下载文件并解析是和我们平时使用的从普通文件服务器下载文件是不同的,接下来,我就来一步一步做个记录。
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch --> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency> 复制代码
jsch常用密码登陆和密钥认证的形式进行sftp服务器登陆 。
import com.jcraft.jsch.*; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Properties; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; @Slf4j //此处注解用来将本类交给Spring管理,也就是让Springboot启动类可以扫描到 @Component public class SFtpUtil { public static final String NO_FILE = "No such file"; private ChannelSftp sftp = null; private Session sshSession = null; private String username; private String password; private String host; private int port; //输入自己的密码账号ip地址即可 public SFtpUtil() { this.username = "*******"; this.password = "*******"; this.host = "*******"; this.port = 22; } /** * 连接sftp服务器 * * @return ChannelSftp sftp类型 */ public ChannelSftp connect() { log.info("ftp连接开始host=" + host + "port" + port + "username=" + username); JSch jsch = new JSch(); try { jsch.getSession(username, host, port); sshSession = jsch.getSession(username, host, port); log.info("ftp---Session created."); sshSession.setPassword(password); Properties properties = new Properties(); properties.put("StrictHostKeyChecking", "no"); sshSession.setConfig(properties); sshSession.connect(); log.info("ftp---Session connected."); Channel channel = sshSession.openChannel("sftp"); channel.connect(); log.info("Opening Channel."); sftp = (ChannelSftp) channel; log.info("ftp---Connected to " + host); } catch (JSchException e) { throw new BadRequestException(null, SFtpUtil.class.getSimpleName(), "connect异常" + e.getMessage()); } return sftp; } 复制代码
/** * 下载单个文件 * @param directory 远程下载目录(以路径符号结束) * @param remoteFileName FTP服务器文件名称 如:xxx.txt ||xxx.txt.zip * @param localFile 本地文件路径 如 D://xxx.txt * @return * @throws BadRequestException //自定义异常 */ public File downloadFile(String directory, String remoteFileName, String localFile){ log.info("ftp下载文件" + remoteFileName + "开始"); connect(); File file = null; OutputStream output = null; try { file = new File(localFile); if (file.exists()) { file.delete(); } boolean newFile = file.createNewFile(); //进入FTP服务器文件目录 sftp.cd(directory); output = new FileOutputStream(file); sftp.get(remoteFileName, output); log.info("DownloadFile:" + remoteFileName + "success from sftp"); } catch (SftpException e) { if (e.toString().equals(NO_FILE)) { log.info("sftp下载文件失败" + directory + remoteFileName + "不存在"); throw new BadRequestException(null, SFtpUtil.class.getSimpleName(), "ftp下载文件失败" + directory + remoteFileName + "不存在"); } throw new BadRequestException(null,SFtpUtil.class.getSimpleName(), "ftp目录或者文件异常,检查ftp目录和文件" + e.toString()); } catch (FileNotFoundException e) { throw new BadRequestException(null, SFtpUtil.class.getSimpleName(), "本地目录异常,请检查" + file.getPath() + e.getMessage()); } catch (IOException e) { throw new BadRequestException(null, SFtpUtil.class.getSimpleName(), "创建本地文件失败" + file.getPath() + e.getMessage()); } finally { if (output != null) { try { output.close(); } catch (IOException e) { throw new BadRequestException(null, SFtpUtil.class.getSimpleName(), "Close stream error" + e.getMessage()); } } disconnect(); } log.info("ftp下载文件结束"); return file; } 复制代码
4.关闭连接
public void disconnect() { if (this.sftp != null) { if (this.sftp.isConnected()) { this.sftp.disconnect(); this.sftp = null; log.info("sftp is closed already"); } } if (this.sshSession != null) { if (this.sshSession.isConnected()) { this.sshSession.disconnect(); this.sshSession = null; log.info("sshSession is closed already"); } } } 复制代码