parent
8cffce33b7
commit
97c9501dc0
@ -0,0 +1,166 @@ |
||||
package com.dxhy.oss.service; |
||||
|
||||
import cn.hutool.core.io.FileUtil; |
||||
import com.dxhy.oss.utils.SshPool; |
||||
import com.jcraft.jsch.ChannelSftp; |
||||
import com.jcraft.jsch.SftpException; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.io.File; |
||||
import java.io.InputStream; |
||||
import java.nio.file.Files; |
||||
|
||||
/** |
||||
* @author jiaohongyang |
||||
*/ |
||||
@Slf4j |
||||
@Service |
||||
public class SshService { |
||||
|
||||
private final SshPool pool; |
||||
|
||||
public SshService(SshPool pool) { |
||||
this.pool = pool; |
||||
} |
||||
|
||||
/** |
||||
* 将输入流的数据上传到sftp作为文件。文件完整路径 = basePath+directory |
||||
* |
||||
* @param pathName ftp服务保存地址,完整路径 |
||||
* @param fileName 上传到ftp的文件名 |
||||
* @param originFileName 待上传文件的名称(绝对地址) |
||||
*/ |
||||
|
||||
public boolean uploadFile(String pathName, String fileName, String originFileName) { |
||||
log.info("开始上传文件"); |
||||
ChannelSftp sftp = null; |
||||
InputStream inputStream; |
||||
try { |
||||
sftp = pool.borrowObject(); |
||||
try { |
||||
sftp.cd(pathName); |
||||
} catch (SftpException e) { |
||||
// 目录不存在,则创建文件夹
|
||||
String[] dirs = pathName.split("/"); |
||||
String tempPath = ""; |
||||
for (String dir : dirs) { |
||||
if (null == dir || "".equals(dir)) { |
||||
continue; |
||||
} |
||||
tempPath += "/" + dir; |
||||
try { |
||||
sftp.cd(tempPath); |
||||
} catch (SftpException ex) { |
||||
try { |
||||
sftp.mkdir(tempPath); |
||||
sftp.cd(tempPath); |
||||
} catch (SftpException e1) { |
||||
e1.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
File orgFile = new File(originFileName); |
||||
inputStream = Files.newInputStream(orgFile.toPath()); |
||||
sftp.put(inputStream, fileName); |
||||
inputStream.close(); |
||||
// 删除本地文件,防止服务器空间不足
|
||||
FileUtil.del(orgFile); |
||||
log.info("上传文件成功"); |
||||
return true; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
log.info("上传文件失败"); |
||||
return false; |
||||
} finally { |
||||
if (sftp != null) { |
||||
log.info("回收线程"); |
||||
pool.returnObject(sftp); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
|
||||
public boolean downloadFile(String directory, String downloadFile, String saveFile) { |
||||
log.info("开始下载文件!"); |
||||
ChannelSftp sftp = null; |
||||
try { |
||||
sftp = pool.borrowObject(); |
||||
if (directory != null && !"".equals(directory)) { |
||||
sftp.cd(directory); |
||||
} |
||||
String file = saveFile + "/" + downloadFile; |
||||
File fileLocal = new File(file); |
||||
if (fileLocal.exists()) { |
||||
boolean delete = fileLocal.delete(); |
||||
log.info("删除本地路径文件:{}", delete); |
||||
} |
||||
this.directoryIsExists(saveFile); |
||||
sftp.get(downloadFile, file); |
||||
log.info("下载文件成功!"); |
||||
return true; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
log.info("下载文件失败!"); |
||||
return false; |
||||
} finally { |
||||
if (sftp != null) { |
||||
log.info("回收线程"); |
||||
pool.returnObject(sftp); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
/** |
||||
* 删除文件 |
||||
* |
||||
* @param directory 要删除文件所在目录 |
||||
* @param deleteFile 要删除的文件 |
||||
* @return 返回是否删除成功 |
||||
*/ |
||||
|
||||
public boolean deleteFile(String directory, String deleteFile) { |
||||
ChannelSftp sftp = null; |
||||
try { |
||||
sftp = pool.borrowObject(); |
||||
sftp.cd(directory); |
||||
sftp.rm(deleteFile); |
||||
return true; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return false; |
||||
} finally { |
||||
if (sftp != null) { |
||||
log.info("回收线程"); |
||||
pool.returnObject(sftp); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
public void directoryIsExists(String path) { |
||||
File directory = new File(path); |
||||
if (directory.exists()) { |
||||
return; |
||||
} |
||||
|
||||
if (!directory.mkdir()) { |
||||
return; |
||||
} |
||||
|
||||
if (directory.canWrite()) { |
||||
return; |
||||
} |
||||
|
||||
boolean setWritable = directory.setWritable(true); |
||||
log.info("是否创建文件 directoryIsExists :{} ", setWritable); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,70 @@ |
||||
package com.dxhy.oss.utils; |
||||
|
||||
import com.jcraft.jsch.ChannelSftp; |
||||
import com.jcraft.jsch.JSch; |
||||
import com.jcraft.jsch.JSchException; |
||||
import com.jcraft.jsch.Session; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.commons.pool2.BasePooledObjectFactory; |
||||
import org.apache.commons.pool2.PooledObject; |
||||
import org.apache.commons.pool2.impl.DefaultPooledObject; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
@EqualsAndHashCode(callSuper = true) |
||||
@Data |
||||
@Slf4j |
||||
public class SshFactory extends BasePooledObjectFactory<ChannelSftp> { |
||||
|
||||
private SshProperties ossConfig; |
||||
|
||||
public SshFactory(SshProperties ossConfig) { |
||||
this.ossConfig = ossConfig; |
||||
} |
||||
|
||||
@Override |
||||
public ChannelSftp create() throws SftpPoolException { |
||||
try { |
||||
JSch jsch = new JSch(); |
||||
Session session = jsch.getSession(ossConfig.getUsername(), ossConfig.getHostname(), Integer.parseInt(ossConfig.getPort())); |
||||
// 设置密码
|
||||
if (ossConfig.getPassword() != null) { |
||||
session.setPassword(ossConfig.getPassword()); |
||||
} |
||||
// 设置密码
|
||||
if (ossConfig.getPassword() != null) { |
||||
session.setPassword(ossConfig.getPassword()); |
||||
} |
||||
// 为Session对象设置properties
|
||||
Properties config = new Properties(); |
||||
config.put("StrictHostKeyChecking", "no"); |
||||
session.setConfig(config); |
||||
// 设置超时时间
|
||||
session.setTimeout(Integer.parseInt(ossConfig.getTimeout())); |
||||
// 建立链接
|
||||
session.connect(); |
||||
// 打开SFTP通道
|
||||
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); |
||||
// 建立SFTP通道的连接
|
||||
channel.connect(); |
||||
return channel; |
||||
} catch (JSchException e) { |
||||
throw new SftpPoolException("获取ftp连接失败", e); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) { |
||||
return new DefaultPooledObject<>(channelSftp); |
||||
} |
||||
|
||||
// 销毁对象
|
||||
@Override |
||||
public void destroyObject(PooledObject<ChannelSftp> p) { |
||||
ChannelSftp channelSftp = p.getObject(); |
||||
channelSftp.disconnect(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,41 @@ |
||||
package com.dxhy.oss.utils; |
||||
|
||||
import com.jcraft.jsch.ChannelSftp; |
||||
import lombok.Data; |
||||
import org.apache.commons.pool2.impl.GenericObjectPool; |
||||
|
||||
@Data |
||||
public class SshPool { |
||||
|
||||
private GenericObjectPool<ChannelSftp> pool; |
||||
|
||||
public SshPool(SshFactory factory) { |
||||
this.pool = new GenericObjectPool<>(factory, factory.getOssConfig().getPool()); |
||||
} |
||||
|
||||
/** |
||||
* 获取一个sftp连接对象 |
||||
* |
||||
* @return sftp连接对象 |
||||
*/ |
||||
public ChannelSftp borrowObject() throws SftpPoolException { |
||||
try { |
||||
return pool.borrowObject(); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
throw new SftpPoolException("获取ftp连接失败", e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 归还一个sftp连接对象 |
||||
* |
||||
* @param channelSftp sftp连接对象 |
||||
*/ |
||||
public void returnObject(ChannelSftp channelSftp) { |
||||
if (channelSftp != null) { |
||||
pool.returnObject(channelSftp); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,61 @@ |
||||
package com.dxhy.oss.utils; |
||||
|
||||
import com.jcraft.jsch.ChannelSftp; |
||||
import lombok.Data; |
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
||||
@Data |
||||
@ConfigurationProperties(prefix = "ftp.connection") |
||||
public class SshProperties { |
||||
|
||||
private String hostname; |
||||
private String port = "22"; |
||||
private String username; |
||||
private String password; |
||||
private String timeout; |
||||
private Pool pool = new Pool(); |
||||
|
||||
public static class Pool extends GenericObjectPoolConfig<ChannelSftp> { |
||||
|
||||
private int maxTotal = DEFAULT_MAX_TOTAL; |
||||
private int maxIdle = DEFAULT_MAX_IDLE; |
||||
private int minIdle = DEFAULT_MIN_IDLE; |
||||
|
||||
public Pool() { |
||||
super(); |
||||
} |
||||
|
||||
@Override |
||||
public int getMaxTotal() { |
||||
return maxTotal; |
||||
} |
||||
|
||||
@Override |
||||
public void setMaxTotal(int maxTotal) { |
||||
this.maxTotal = maxTotal; |
||||
} |
||||
|
||||
@Override |
||||
public int getMaxIdle() { |
||||
return maxIdle; |
||||
} |
||||
|
||||
@Override |
||||
public void setMaxIdle(int maxIdle) { |
||||
this.maxIdle = maxIdle; |
||||
} |
||||
|
||||
@Override |
||||
public int getMinIdle() { |
||||
return minIdle; |
||||
} |
||||
|
||||
@Override |
||||
public void setMinIdle(int minIdle) { |
||||
this.minIdle = minIdle; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue