导入依赖包
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
还需要下载一个ftp.server 服务器工具
新建FTPUtil工具类
只在window上测试过,Linux没有测试
package com.comn.util;
import com.aliyuncs.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.List;
public class FileUtil {
private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
private static String ftp_IP = "127.0.0.1";
private static String ftp_user = "admin"
private static String ftp_psw = "123456"
private static Integer ftp_port = 21;
private static String localPath = "G:\\";
/**
* 上传
* @param fileList
* @param remotePath 服务器上的路径
* @return
*/
public static boolean uploadFileFromFTP(List<File> fileList, String remotePath) {
logger.info("ftp文件夹路径" + remotePath);
FTPClient ftpClient = new FTPClient();
FileInputStream fis = null;
boolean result = false;
String[] split = remotePath.split("/");
try {
logger.info("开始连接ftp服务器");
ftpClient.setControlEncoding("gbk");
ftpClient.connect(ftp_IP, ftp_port);
ftpClient.login(ftp_user, ftp_psw);
ftpClient.enterLocalPassiveMode();
// 设置上传目录
ftpClient.setBufferSize(1024);
ftpClient.setConnectTimeout(10 * 1000);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
for (String str : split) {
if (StringUtils.isBlank(str)) {
continue;
}
if (!ftpClient.changeWorkingDirectory(str)) {
ftpClient.makeDirectory(str);
ftpClient.changeWorkingDirectory(str);
}
}
// 保存文件
for (File fileItem : fileList) {
fis = new FileInputStream(fileItem);
ftpClient.storeFile(fileItem.getName(), fis);
}
} catch (NumberFormatException e) {
System.err.println("FTP端口配置错误:不是数字:");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(fis);
try {
ftpClient.disconnect();
} catch (IOException e) {
throw new RuntimeException("关闭FTP连接发生异常!", e);
}
}
logger.info("开始连接ftp服务器,结束上传,上传结果:{}", result);
return result;
}
/**
* 下载
* @param remotePath 服务器上的路径
* @param fileName 要下载的文件
*/
public static boolean downloadFileFromFTP(String remotePath, String fileName) {
boolean success = false;
FTPClient ftp = new FTPClient();
try {
logger.info("开始连接ftp服务器");
int reply;
// 1. 连接ftp服务器, 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.connect(ftp_IP, ftp_port);
// 2. 登录ftp服务器
ftp.login(ftp_user, ftp_psw);
ftp.enterLocalPassiveMode();
ftp.setControlEncoding("gbk");
// 3. 登录是否成功
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
logger.error("连接服务器异常");
return success;
}
// 设置上传目录
ftp.changeWorkingDirectory(remotePath);
FTPFile[] fs = ftp.listFiles();
for (FTPFile ff : fs) {
if (ff.getName().equals(fileName)) {
File localFile = new File(localPath + "/" + ff.getName());
OutputStream is = new FileOutputStream(localFile);
logger.info("指定输出到本地路径:{}", localPath);
ftp.retrieveFile(new String(ff.getName().getBytes("GBK"), "ISO-8859-1"), is);
is.close();
}
}
ftp.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
logger.info("开始连接ftp服务器,结束下载,下载结果:{}", success);
return success;
}
}
- service
package com.comn.service;
import com.bolt.common.ServerResponse;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
public interface ILocalStorageService {
String uploadFile(MultipartFile file, String path);
ServerResponse<String> downloadFile(String fileName);
}
- serviceImpl
package com.comn.service.impl;
import cn.hutool.core.date.DateUtil;
import com.bolt.common.ServerResponse;
import com.bolt.service.ILocalStorageService;
import com.bolt.shiro.util.UserContext;
import com.bolt.util.FileUtil;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.Date;
@Service
public class ILocalStorageServiceImpl implements ILocalStorageService {
private Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
@Override
public String uploadFile(MultipartFile file, String path) {
// 获取上传时文件名
String fileName = file.getOriginalFilename();
//获取扩展名(abc.jpg)----.jpg
// String fileExtensionName = fileName.substring(fileName.lastIndexOf(".") + 1);
logger.info("开始上传文件,上传文件的文件名:{},上传的路径:{},新文件名:{}", fileName, path, fileName);
Integer userId = 2;
String remotePath=String.valueOf(userId);
//新建c盘缓存文件
File fileDir = new File(path);
if (!fileDir.exists()) {
fileDir.setWritable(true);
fileDir.mkdirs();
}
File targetFile = new File(path, fileName);
try {
//上传到缓存中-文件已经上传成功了
file.transferTo(targetFile);
//已经上传到ftp服务器上
FileUtil.uploadFileFromFTP(Lists.newArrayList(targetFile), remotePath);
//删除缓存文件
targetFile.delete();
} catch (IOException e) {
logger.error("上传文件异常", e);
return null;
}
//A:abc.jpg
//返回新文件名
return remotePath+"/"+targetFile.getName();
}
@Override
public ServerResponse<String> downloadFile(String fileName) {
Integer userId = 2;
String remotePath=String.valueOf(userId);
try {
FileUtil.downloadFileFromFTP(remotePath, fileName);
} catch (Exception e) {
logger.error("下载异常", e);
return ServerResponse.createByErrorMessage("下载异常");
}
return ServerResponse.createBySuccess();
}
}``
- controller
```java
package com.bolt.controller.partal;
import com.comn.common.ServerResponse;
import com.comn.service.ILocalStorageService;
import com.comn.util.FileUtil;
import com.comn.util.PropertiesUtil;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@RestController
public class UserUploadFileController {
@Autowired
private ILocalStorageService fileService;
@PostMapping("upload_file")
public ServerResponse uploadFile(MultipartFile file, HttpServletRequest request) {
// 获取tomcat服务器目录路径
String path = request.getSession().getServletContext().getRealPath("upload");
//新文件名称
String targetFileName = fileService.uploadFile(file, path);
//文件完整路劲
String url = PropertiesUtil.getProperty("ftp.server.http.prefix") + targetFileName;
Map fileMap = Maps.newHashMap();
fileMap.put("uri", targetFileName);
fileMap.put("url", url);
// fileMap.put("fileName", file.getOriginalFilename());
return ServerResponse.createBySuccess(fileMap);
}
// fileName 文件名称
@PostMapping("download_file")
public ServerResponse downloadFile(String fileName) {
return fileService.downloadFile(fileName);
}
}
遇到的问题
- 上传文件大小限制,springboot默认文件上传为1M需要设置
- 文件名称为中文时,无法上传下载
- 下载压缩文件,文件被损坏,文件大小为0kb