思路
1.首先连接ftp服务器
2.连接到服务器之后如何上传文件
3.上传后如何获取文件
4.文件格式是图片如何展示到客户端浏览器
5.服务端代码如何接收客户端的文件以及如何返回响应信息给浏览器
主要jar包依赖文件
public class SftpUtils {
private static final Logger log = LoggerFactory.getLogger(SftpUtils.class);
private static ChannelSftp sftp;
public static Properties properties = LoadProperties.getProperties("/config/sftp.properties");
private static Channel channel;
private static Session sshSession;
/**
* 登陆SFTP服务器
* @return
*/
public static boolean getConnect() throws Exception{
log.info("进入SFTP====");
boolean result = false;
JSch jsch = new JSch();
//获取sshSession 账号-ip-端口,从properties文件中获取连接ftp服务器的相关信息
sshSession =jsch.getSession(properties.getProperty("user"), properties.getProperty("ip"), Integer.parseInt(properties.getProperty("port")));
//添加密码
sshSession.setPassword(properties.getProperty("password"));
Properties sshConfig = new Properties();
//严格主机密钥检查
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
//开启sshSession链接
sshSession.connect();
//获取sftp通道
channel = sshSession.openChannel("sftp");
//开启
channel.connect();
sftp = (ChannelSftp) channel;
result = true;
return result;
}
/**
* 文件上传
* @param inputStream 上传的文件输入流
* @param fileCategory 存储文件目录分类
* @return
*/
public static String upload(InputStream inputStream, String fileCategory, String fileName) throws Exception{
String destinationPath = properties.getProperty("destinationPath")+fileCategory;
try {
sftp.cd(destinationPath);
//获取随机文件名
fileName = UUID.randomUUID().toString().replace("-", "") + fileName;
//文件名是 随机数加文件名的后5位
sftp.put(inputStream, fileName);
}finally {
sftp.disconnect();
}
return fileName;
}
/**
* 下载文件
*
* @param downloadFilePath 下载的文件完整目录
* @param saveFile 保存在本地的文件路径
* @return 返回的是文件
*/
public static File download(String downloadFilePath, String saveFile) {
FileOutputStream fileOutputStream = null;
try {
int i = downloadFilePath.lastIndexOf('/');
if (i == -1)
return null;
sftp.cd(downloadFilePath.substring(0, i));
File file = new File(saveFile);
fileOutputStream = new FileOutputStream(file);
sftp.get(downloadFilePath.substring(i + 1), fileOutputStream);
return file;
} catch (Exception e) {
log.error(e.getMessage());
return null;
}finally {
sftp.disconnect();
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 获取ftp服务器 (图片)文件流
* @param downloadFilePath ftp文件上的文件全路径,包括具体文件名 a/b/c.png
* @return 返回的是文件流
*/
public static InputStream download(String downloadFilePath) {
int i = downloadFilePath.lastIndexOf('/');
InputStream inputStream = null;
if (i == -1)
return null;
try {
sftp.cd(downloadFilePath.substring(0, i));
inputStream = sftp.get(downloadFilePath.substring(i + 1));
} catch (SftpException e) {
log.error("获取ftp服务文件流发生异常!");
e.printStackTrace();
}
return inputStream;
}
/* * 断开SFTP Channel、Session连接
* @throws Exception
*
*/
public static void disconnect() {
if (SftpUtils.sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
log.info("sftp is closed already");
}
}
if (SftpUtils.sshSession != null) {
if (SftpUtils.sshSession.isConnected()) {
SftpUtils.sshSession.disconnect();
log.info("sshSession is closed already");
}
}
}
/**
* 文件流转为base64字节码
* @param in
* @return
*/
public static String inputStreamtoBase64(InputStream in) throws Exception{
byte[] bytes = IOUtils.toByteArray(in);
String base64str = Base64.getEncoder().encodeToString(bytes);
return base64str;
}
/** 删除sftp文件
* @param directPath 需要删除的文件目录
* @param fileName 需要删除的文件
* @return
**/
public static void deleteFile(String directPath, String fileName) throws Exception{
//进入需要删除的文件目录下
sftp.cd(directPath);
sftp.rm(fileName);
}
/**
* 列出某目录下的文件名
* @param directory 需要列出的文件目录(sftp服务器目录下的)
* @return List
* @throws Exception
*/
public static List
Vector fileList;
List
fileList = sftp.ls(directory);
Iterator it = fileList.iterator();
while(it.hasNext())
{
String fileName = ((LsEntry)it.next()).getFilename();
if(".".equals(fileName) || "..".equals(fileName)){
continue;
}
fileNameList.add(fileName);
}
return fileNameList;
}
总结:上面是一个ftp工具类,包括ftp连接,文件上传,文件下载,ftp服务硬盘目录下的文件查询
二,服务端后台代码
/**
* 上传文件
* @param multipartFile 客户端上传的文件
* @param request
* @param response
* @return
*/
@PostMapping("uploadFile")
@ResponseBody
public String uploadFile(@RequestParam("multipartFile") MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) {
//连接sftp服务
String fileName = null;
try {
SftpUtils.getConnect();
//上传的文件所属类型 banner, mobile, pc, share四种
//如果未明确默认存放在ftp服务器的share文件目录下
String fileCategory = request.getParameter("fileCategory")== null ? "share" : request.getParameter("fileCategory");
//上传的文件名
fileName = multipartFile.getOriginalFilename();
int index = fileName.lastIndexOf(".");
String nameSuffix = fileName.substring(index, fileName.length());
//禁止上传.exe文件
if(".exe".equalsIgnoreCase(nameSuffix)) {
return renderResult(Global.FALSE, text("上传的文件格式不支持!"));
}
InputStream inputStream = multipartFile.getInputStream();
String filePath = SftpUtils.upload(inputStream, fileCategory, fileName);
SftpUtils.disconnect();
//需要保存到数据库的文件名称
fileName = fileCategory+"/"+filePath;
} catch (Exception e) {
e.printStackTrace();
logger.error("文件上传过程中发生异常!");
return renderResult(Global.FALSE, text("上传失败!"));
}
return renderResult(Global.TRUE, text(fileName));
}
/**
* 下载文件
* @param request
* @param response
* @return
*/
@RequestMapping("downLoad")
@ResponseBody
public Map
Map
paraMap.put("result", "true");
paraMap.put("msg", "文件下载成功");
//获取需要下载的文件名称
//正式情况下是从表中获取,文件格式,文件名称,存入数据库中
//测试某文件名称
String fileName = "share/eae3b1a4a6fe4bb48af11381add03c59textJGY.jpg";
//判断需要下载的文件是否是图片格式,如果是图片则传Base64格式给浏览器
String fileType = "jpg";
String oldName = "JGY.jpg";
String [] imagesTypes = {"jpg", "JPG", "png", "PNG", "bmp", "BMP", "gif", "GIF"};
boolean flag = false;
for (int i = 0; i < imagesTypes.length; i++) {
if(fileType.equalsIgnoreCase(imagesTypes[i])) {
flag = true;
break;
}
}
try {
SftpUtils.getConnect();
} catch (Exception ftpexp) {
logger.error("ftp连接时发生异常!");
ftpexp.printStackTrace();
paraMap.put("result", "false");
paraMap.put("msg", "ftp连接时发生异常!");
return paraMap;
}
//获取properties文件中ftp服务器存放的路径
String direct = SftpUtils.properties.getProperty("destinationPath");
//获取下载文件的文件流
String downloadFilePath = direct+fileName;
InputStream inputStream = SftpUtils.download(downloadFilePath);
//图片转为base64
if(flag) {
try {
//文件流转为base64
String base64String = SftpUtils.inputStreamtoBase64(inputStream);
paraMap.put("base64", base64String);
} catch (Exception e) {
logger.error("文件下载出现异常!");
e.printStackTrace();
paraMap.put("result", "false");
paraMap.put("msg", "文件下载失败!");
return paraMap;
}
//非图片文件就直接浏览器下载
} else {
String agent = request.getHeader("user-agent");
try {
if(StringUtils.contains(agent, "MSIE")||StringUtils.contains(agent,"Trident")){//IE浏览器
oldName = URLEncoder.encode(oldName,"UTF8");
System.out.println("IE浏览器");
}else if(StringUtils.contains(agent, "Mozilla")) {//google,火狐浏览器
oldName = new String(oldName.getBytes(), "ISO8859-1");
}else {
oldName = URLEncoder.encode(oldName,"UTF8");//其他浏览器
}
response.reset();//重置 响应头
response.setContentType("application/x-download");//告知浏览器下载文件,而不是直接打开,浏览器默认为打开
response.addHeader("Content-Disposition" ,"attachment;filename=\"" +oldName+ "\"");//下载文件的名称
byte[] b = new byte[1024];
int len;
while((len = inputStream.read(b)) > 0) {
response.getOutputStream().write(b, 0, len);;
}
}catch (Exception e) {
e.printStackTrace();
paraMap.put("result", "false");
paraMap.put("msg", "文件下载失败!");
return paraMap;
}finally {
try {
response.getOutputStream().close();
} catch (IOException e) {
logger.error("文件输出流关闭发生异常!");
e.printStackTrace();
}
SftpUtils.disconnect();
}
}
return paraMap;
}