提示:文章如有错误的地方请指出,以免误人子弟!
文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、导入maven jar包
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
二、上代码
- application.yml (根据自己业务来添加路径地址,用不上的可以删掉,我这里就不删了)
sftp:
# 服务器地址
host: 192.168.96.135
# 端口
port: 22
# 账号
userName: root
# 密码
password: wang521
# 图片的根路径
basePath: /home/nginx/image
# 音频的根路径
audioPath: /home/nginx/audio
# 视频的根路径
videoPath: /home/nginx/video
# channel连接超时时间
timeout: 30000
#连接次数
count: 10
#休眠时间
sleepTime: 6000
#服务器头像地址
titleImgsPath: http://192.168.96.135:80/image/
#服务器音频地址
titleAudiosPath: http://192.168.96.135:80/audio/
#服务器视频地址
titleVideosPath: http://192.168.96.135:80/video/
- 新建一个实体类,用起来方便的
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
/**
* @author Mr.Tiger
* @date 2021/01/07 17:59
*/
@Data
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class SftpDTO implements Serializable {
/**
* description: Ip
*/
private String hostname;
/**
* description: 端口
*/
private Integer port;
/**
* description: 服务器用户名
*/
private String username;
/**
* description: 服务器密码
*/
private String password;
/**
* description: 连接超时
*/
private Integer timeout;
/**
* description: 服务器根路径
*/
private String remoteRootPath;
public SftpDTO() {}
public SftpDTO(String hostname, Integer port, String username, String password, Integer timeout, String remoteRootPath) {
this.hostname = hostname;
this.port = port;
this.username = username;
this.password = password;
this.timeout = timeout;
this.remoteRootPath = remoteRootPath;
}
}
- sftp工具类
注意:
这里有个地方需要注意下,单个文件或多个文件上传只需要连接一次 sftp 就好了
import com.jcraft.jsch.*;
import com.wwwh.onlyone.common.entity.userInfo.dto.SftpDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* @author Mr.Tiger
* @date 2021/01/07 18:17
*/
@Slf4j
@Component
@RefreshScope
public class SftpUtil
{
/**
* description: count-> 连接超过次数,线程休眠
*/
@Value("${sftp.count}")
private long count;
/**
* description: sleepTime-> 休眠时间
*/
@Value("${sftp.sleepTime}")
private long sleepTime;
/**
* description: count1-> 已经连接次数
*/
private long count1 = 0;
/**
* description: 连接sftp服务器
*
* @param sftpConfig sftp实体类
* @return com.jcraft.jsch.ChannelSftp
* @author Mr.Tiger
*/
public ChannelSftp connect(SftpDTO sftpConfig) {
ChannelSftp sftp = null;
try {
JSch jsch = new JSch();
jsch.getSession(sftpConfig.getUsername(), sftpConfig.getHostname(), sftpConfig.getPort());
Session sshSession = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getHostname(), sftpConfig.getPort());
log.info("Session created ... UserName=" + sftpConfig.getUsername() + ";host=" + sftpConfig.getHostname() + ";port=" + sftpConfig.getPort());
sshSession.setPassword(sftpConfig.getPassword());
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
log.info("Session connected ...");
//协议
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
log.info("登录成功");
} catch (Exception e) {
try {
count1 += 1;
if (count == count1) {
throw new RuntimeException(e);
}
Thread.sleep(sleepTime);
log.info("重新连接....");
connect(sftpConfig);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
}
}
return sftp;
}
/**
* description: 关闭 流
*
* @param ins 输入流
* @param file MultipartFile 转 File的文件
* @return void 返回类型
* @author Mr.Tiger
*/
public static void inputStreamToFile(InputStream ins,File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* description: 上传文件
*
* @param file 要上传的文件
* @param directory 上传的目录
* @param sftpConfig sftp实体类
* @return java.util.Map<java.lang.String,java.lang.Object>
* @author Mr.Tiger
*/
public Map<String, String> upload(MultipartFile file, String directory, SftpDTO sftpConfig, String fileName) {
Map<String, String> map = new HashMap<String, String>(10);
ChannelSftp sftp = connect(sftpConfig);
try {
sftp.cd(directory);
} catch (SftpException e) {
try {
sftp.mkdir(directory);
sftp.cd(directory);
log.info("创建的路径为--:"+directory);
} catch (SftpException e1) {
throw new RuntimeException("ftp创建文件路径失败" + directory);
}
}
InputStream inputStream = null;
try
{
inputStream = file.getInputStream();
sftp.put(inputStream, fileName);;
map.put("code","200");
log.info("文件头像成功");
} catch (Exception e) {
map.put("code","500");
throw new RuntimeException("sftp异常" + e);
} finally {
disConnect(sftp);
closeStream(inputStream,null);
}
return map;
}
/**
* description: 上传多个文件
*
* @param file 要上传的文件
* @param directory 上传的目录
* @param sftp sftp连接对象
* @return java.util.Map<java.lang.String,java.lang.Object>
* @author Mr.Tiger
*/
public void uploadList(MultipartFile file, String directory, ChannelSftp sftp, String fileName) {
try {
sftp.cd(directory);
} catch (SftpException e) {
try {
sftp.mkdir(directory);
sftp.cd(directory);
log.info("创建的路径为--:"+directory);
} catch (SftpException e1) {
throw new RuntimeException("ftp创建文件路径失败" + directory);
}
}
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
sftp.put(inputStream, fileName);
log.info("文件上传成功");
} catch (Exception e) {
throw new RuntimeException("sftp异常" + e);
} finally {
closeStream(inputStream,null);
}
}
/**
* description: 下载文件
*
* @param directory 下载目录
* @param downloadFileUrl 下载的文件名称
* @param sftpConfig sftp 实体类
* @return byte[]
* @author Mr.Tiger
*/
public byte[] download(String directory, String downloadFileUrl, SftpDTO sftpConfig) {
ChannelSftp sftp = connect(sftpConfig);
ByteArrayOutputStream byteArrayOutputStream = null;
try {
//进到文件夹下
sftp.cd(directory);
if (log.isInfoEnabled()) {
log.info("打开远程文件:[{}]", new Object[]{directory});
}
InputStream inputStream = sftp.get(downloadFileUrl);
byteArrayOutputStream = new ByteArrayOutputStream();
int n = 0;
byte[] data = new byte[1024];
while ((n = inputStream.read(data, 0, data.length)) != -1) {
byteArrayOutputStream.write(data, 0, n);
}
return byteArrayOutputStream.toByteArray();
} catch (Exception e) {
if (log.isInfoEnabled()) {
log.info("文件下载出现异常,[{}]", e);
}
throw new RuntimeException("文件下载出现异常,[{}]", e);
} finally
{
if (byteArrayOutputStream != null)
{
try
{
byteArrayOutputStream.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
}
disConnect(sftp);
}
}
/**
* description: 关闭流
*
* @param inputStream 输入流
* @param outputStream 输出流
* @return void
* @author Mr.Tiger
*/
private void closeStream(InputStream inputStream,OutputStream outputStream) {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* description: 删除文件
*
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
* @param sftpConfig sftp实体类
* @return void 返回类型
* @author Mr.Tiger
*/
public void delete(String directory, String deleteFile, SftpDTO sftpConfig) {
ChannelSftp sftp = null;
try {
sftp = connect(sftpConfig);
sftp.cd(directory);
sftp.rm(deleteFile);
} catch (Exception e) {
throw new RuntimeException(e);
} finally
{
disConnect(sftp);
}
}
/**
* description: 断掉连接
*
* @param sftp sftp实体类
* @return void 返回类型
* @author Mr.Tiger
*/
public void disConnect(ChannelSftp sftp) {
try {
sftp.disconnect();
sftp.getSession().disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- controller 使用
单个,多个文件上传,单个文件下载,因为本人比较懒,这里把业务代码也贴上去了没有删掉,大家用的时候把没有的业务代码删掉就好了。因为这是cloud的项目,@RefreshScope删掉,@DubboReference替换成@Autowired或者@Resource。
import com.alibaba.fastjson.JSON;
import com.jcraft.jsch.ChannelSftp;
import com.wwwh.onlyone.common.entity.userInfo.doo.SysAudios;
import com.wwwh.onlyone.common.entity.userInfo.doo.SysVideos;
import com.wwwh.onlyone.common.entity.userInfo.dto.SftpDTO;
import com.wwwh.onlyone.common.service.registry.system.SysAudiosService;
import com.wwwh.onlyone.common.service.registry.system.SysEmpInfoService;
import com.wwwh.onlyone.common.service.registry.system.SysVideosService;
import com.wwwh.onlyone.common.util.createId.SnowFlakeGenerateIdWorker;
import com.wwwh.onlyone.common.util.responseJson.ResponseResult;
import com.wwwh.onlyone.consumer.util.RedisUtil;
import com.wwwh.onlyone.consumer.util.SftpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author Mr.Tiger
* @date 2021/01/07 19:07
*/
@Slf4j
@RestController
@RequestMapping("/sftpFile")
@RefreshScope
public class SftpController
{
private final SftpUtil sftpUtil;
public SftpController(SftpUtil sftpUtil)
{
this.sftpUtil = sftpUtil;
}
@DubboReference
private SysEmpInfoService sysEmpInfoService;
@DubboReference
private SysAudiosService sysAudiosService;
@DubboReference
private SysVideosService sysVideosService;
@Autowired
private RedisUtil redisUtil;
@Value("${sftp.host}")
private String host;
@Value("${sftp.port}")
private int port;
@Value("${sftp.userName}")
private String userName;
@Value("${sftp.password}")
private String password;
@Value("${sftp.timeout}")
private int timeout;
@Value("${sftp.basePath}")
private String basePath;
@Value("${sftp.audioPath}")
private String audioPath;
@Value("${sftp.videoPath}")
private String videoPath;
@Value("${sftp.titleImgsPath}")
private String titleImgsPath;
@Value("${sftp.titleAudiosPath}")
private String titleAudiosPath;
@Value("${sftp.titleVideosPath}")
private String titleVideosPath;
/**
* description: 上传文件
*
* @param file 要上传的文件
* @param userPhone 手机号(用户标识)
* @return java.util.Map<java.lang.String,java.lang.Object>
* @author Mr.Tiger
*/
@PostMapping("/uploads")
public String upload(MultipartFile file, String userPhone) {
//获取文件名称
String filename = file.getOriginalFilename();
String fix = null;
if (StringUtils.isNotBlank(filename)) {
filename = filename.replace(" ", "");
// 获取文件名后缀
fix = filename.substring(filename.length() - 3);;
}
log.info("文件后缀---:"+fix);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date());
// 雪花算法, 生成id
SnowFlakeGenerateIdWorker snowFlakeGenerateIdWorker = new SnowFlakeGenerateIdWorker(0L, 0L);
String nextId = snowFlakeGenerateIdWorker.generateNextId();
String fileName = nextId+"."+fix;
//个人头像全路径
String titleImgs = titleImgsPath+format+"/"+fileName;
log.info("头像上传-存库路径---:"+titleImgs);
//修改用户头像
int i = sysEmpInfoService.updateUserTitleImg(titleImgs, userPhone);
// 更新redis 中的头像地址
redisUtil.hset(userPhone, "headImg", titleImgs);
Map<String, String> upload = new HashMap<String, String>();
if(i > 0) {
String path = basePath + "/" + format;
log.info("上传到服务器的路径--:"+path);
SftpDTO sftpConfig = new SftpDTO(host,port,userName,password,timeout,path);
upload = sftpUtil.upload(file, sftpConfig.getRemoteRootPath(), sftpConfig, fileName);
}
//头像地址返回前端
upload.put("imgUrl",titleImgs);
return JSON.toJSONString(upload);
}
/**
* description: 下载文件
*
* @param imgFileName 下载的文件名称
* @param downloadFileName 下载目录
* @param response response
* @author Mr.Tiger
*/
@PostMapping("/downLoads")
public void downLoad(String imgFileName, String downloadFileName, HttpServletResponse response) throws UnsupportedEncodingException {
SftpDTO sftpConfig = new SftpDTO(host,port,userName,password,timeout,basePath);
//需要下载的服务器文件目录
String downloadFileUrl = sftpConfig.getRemoteRootPath() + "/" + imgFileName;
byte[] bytes = sftpUtil.download(sftpConfig.getRemoteRootPath(), downloadFileUrl, sftpConfig);
InputStream inputStream = new ByteArrayInputStream(bytes);
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(downloadFileName, "UTF-8"));
byte[] buffer = new byte[1024];
//缓存字节流
BufferedInputStream bufferedInputStream = null;
//输出流
OutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
bufferedInputStream = new BufferedInputStream(inputStream);
int i = bufferedInputStream.read(buffer);
while (i != -1) {
outputStream.write(buffer, 0, i);
i = bufferedInputStream.read(buffer);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if(bufferedInputStream != null) {
try {
bufferedInputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if(outputStream != null) {
try {
outputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* description: 上传多个文件
*
* @param file 要上传的文件
* @param type 文件类型
* @param createName 上传人姓名
* @return java.util.Map<java.lang.String,java.lang.Object>
* @author Mr.Tiger
*/
@PostMapping("/uploadList")
public ResponseResult uploadLists(List<MultipartFile> file, Integer type, String createName)
{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date());
SftpDTO sftpConfig = null;
String path = null;
List<SysAudios> sysAudiosList = null;
List<SysVideos> sysVideosList = null;
if (type != null) {
// 1: 音频 2:视频
if (type == 1) {
path = audioPath + "/" + format;
sysAudiosList = new ArrayList<>(file.size());
}
else {
path = videoPath + "/" + format;
sysVideosList = new ArrayList<>(file.size());
}
log.info("上传到服务器的路径--:"+path);
}
sftpConfig = new SftpDTO(host,port,userName,password,timeout,path);
// 连接sftp
ChannelSftp sftp = sftpUtil.connect(sftpConfig);
if (file.size() != 0 && type != null) {
for (MultipartFile multipartFile : file) {
//获取文件名称
String filename = multipartFile.getOriginalFilename();
if (StringUtils.isNotBlank(filename)) {
filename = filename.replace(" ", "");
// 获取文件名
String fileName = filename.substring(0, filename.length() - 4);
String titleFilePaths = null;
SysAudios sysAudios = null;
SysVideos sysVideos = null;
// 1: 音频 2:视频
if (type == 1) {
// 存库音频全路径
titleFilePaths = titleAudiosPath + format + "/" + filename;
sysAudios = new SysAudios();
sysAudios.setAudioName(fileName);
sysAudios.setAudioPath(titleFilePaths);
sysAudios.setCreateBy(createName);
sysAudiosList.add(sysAudios);
sftpUtil.uploadList(multipartFile, sftpConfig.getRemoteRootPath(), sftp, filename);
} else {
// 存库视频全路径
titleFilePaths = titleVideosPath + format + "/" + filename;
sysVideos = new SysVideos();
sysVideos.setVideoName(fileName);
sysVideos.setVideoPath(titleFilePaths);
sysVideos.setCreateBy(createName);
sysVideosList.add(sysVideos);
sftpUtil.uploadList(multipartFile, sftpConfig.getRemoteRootPath(), sftp, filename);
}
log.info(type == 1 ? "音频" : "视频" +"——"+"文件上传-存库路径---:"+titleFilePaths);
}
}
// 断开sftp连接
sftpUtil.disConnect(sftp);
// 储存数据
if (sysAudiosList != null && sysAudiosList.size() != 0) {
sysAudiosService.saveAudioInfo(sysAudiosList);
log.info("音频信息入库成功");
}
if (sysVideosList != null && sysVideosList.size() != 0) {
sysVideosService.saveVideoInfo(sysVideosList);
log.info("视频信息入库成功");
}
}
return ResponseResult.create().success(true).data(200);
}
}
希望对你有所帮助!