一、在搭建一個ftp服務器用於存儲文件
二、下載nginx,安裝完成後更改配置文件
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location ~ \.(gif|jpg|jpeg|png|bmp|swf)$ { //設置圖片的格式
root D:/cateringFTP; //ftp跟目錄
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
三、上傳文件到ftp
依賴
<!--ftp文件上傳-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
FtpUtil如下
/**
*
*/
package shqn.sthj.modules.catering.utils;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
/**
* @author hxl
* @date 2019年10月31日
* FtpUtil.java
*/
@Component
public class FtpUtil {
Logger logger = Logger.getLogger(getClass());
private String LOCAL_CHARSET = "GBK";
//ftp服務器地址
String hostname = "192.168.2.119";
//ftp服務器端口
int port = 22;
//ftp登錄賬號
String username = "catering";
//ftp登錄密碼
String password = "catering";
//ftp保存目錄
String basePath = "";
/**
* 初始化ftp服務器
*/
public FTPClient getFtpClient() {
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("utf-8");
try {
ftpClient.setDataTimeout(1000 * 120);//設置連接超時時間
logger.info("connecting...ftp服務器:" + hostname + ":" + port);
ftpClient.connect(hostname,port); // 連接ftp服務器
ftpClient.login(username, password); // 登錄ftp服務器
int replyCode = ftpClient.getReplyCode(); // 是否成功登錄服務器
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
"OPTS UTF8", "ON"))) { // 開啓服務器對UTF-8的支持,如果服務器支持就用UTF-8編碼,否則就使用本地編碼(GBK).
LOCAL_CHARSET = "UTF-8";
}
if (!FTPReply.isPositiveCompletion(replyCode)) {
logger.error("connect failed...ftp服務器:" + hostname + ":" + port);
}
logger.info("connect successfu...ftp服務器:" + hostname + ":" + port);
} catch (MalformedURLException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return ftpClient;
}
/**
* 上傳文件
*
* @param targetDir ftp服務保存地址
* @param fileName 上傳到ftp的文件名
* @param inputStream 輸入文件流
* @return
*/
public boolean uploadFileToFtp(String targetDir, String fileName, InputStream inputStream) {
boolean isSuccess = false;
String servicePath = String.format("%s%s%s", basePath, "/", targetDir);
FTPClient ftpClient = getFtpClient();
// makeDirectory(ftpClient,servicePath); //創建文件夾
// 切換到根目錄
try {
ftpClient.changeWorkingDirectory("/");
String path = servicePath;
String[] pah = path.split("/");
// 分層創建目錄
for (String pa : pah) {
System.out.println(pa);
ftpClient.makeDirectory(pa);
// 切到到對應目錄
ftpClient.changeWorkingDirectory(pa);
}
} catch (IOException e1) {
e1.printStackTrace();
}
try {
if (ftpClient.isConnected()) {
logger.info("開始上傳文件到FTP,文件名稱:" + fileName);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//設置上傳文件類型爲二進制,否則將無法打開文件
ftpClient.makeDirectory(servicePath);
ftpClient.changeWorkingDirectory(servicePath);
//設置爲被動模式(如上傳文件夾成功,不能上傳文件,註釋這行,否則報錯refused:connect )
ftpClient.enterLocalPassiveMode();//設置被動模式,文件傳輸端口設置
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
isSuccess = true;
logger.info(fileName + "文件上傳到FTP成功");
} else {
logger.error("FTP連接建立失敗");
}
} catch (Exception e) {
logger.error(fileName + "文件上傳到FTP出現異常");
logger.error(e.getMessage(), e);
} finally {
closeFtpClient(ftpClient);
closeStream(inputStream);
}
return isSuccess;
}
public void closeStream(Closeable closeable) {
if (null != closeable) {
try {
closeable.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
//改變目錄路徑
public boolean changeWorkingDirectory(FTPClient ftpClient, String directory) {
boolean flag = true;
try {
flag = ftpClient.changeWorkingDirectory(directory);
if (flag) {
logger.info("進入文件夾" + directory + " 成功!");
} else {
logger.info("進入文件夾" + directory + " 失敗!開始創建文件夾");
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return flag;
}
//創建多層目錄文件,如果有ftp服務器已存在該文件,則不創建,如果無,則創建
public boolean CreateDirecroty(FTPClient ftpClient, String remote) throws IOException {
boolean success = true;
String directory = remote;
if (!remote.endsWith(File.separator)) {
directory = directory + File.separator;
}
// 如果遠程目錄不存在,則遞歸創建遠程服務器目錄
if (!directory.equalsIgnoreCase(File.separator) && !changeWorkingDirectory(ftpClient, new String(directory))) {
int start = 0;
int end = 0;
if (directory.startsWith(File.separator)) {
start = 1;
} else {
start = 0;
}
end = directory.indexOf(File.separator, start);
String path = "";
String paths = "";
while (true) {
String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
path = path + File.separator + subDirectory;
if (!existFile(ftpClient, path)) {
if (makeDirectory(ftpClient, subDirectory)) {
changeWorkingDirectory(ftpClient, subDirectory);
} else {
logger.error("創建目錄[" + subDirectory + "]失敗");
changeWorkingDirectory(ftpClient, subDirectory);
}
} else {
changeWorkingDirectory(ftpClient, subDirectory);
}
paths = paths + File.separator + subDirectory;
start = end + 1;
end = directory.indexOf(File.separator, start);
// 檢查所有目錄是否創建完畢
if (end <= start) {
break;
}
}
}
return success;
}
//判斷ftp服務器文件是否存在
public boolean existFile(FTPClient ftpClient, String path) throws IOException {
boolean flag = false;
FTPFile[] ftpFileArr = ftpClient.listFiles(path);
if (ftpFileArr.length > 0) {
flag = true;
}
return flag;
}
//創建目錄
public boolean makeDirectory(FTPClient ftpClient, String dir) {
boolean flag = true;
try {
flag = ftpClient.makeDirectory(dir);
if (flag) {
logger.info("創建文件夾" + dir + " 成功!");
} else {
logger.info("創建文件夾" + dir + " 失敗!");
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return flag;
}
/**
* 下載文件 *
*
* @param pathName FTP服務器文件目錄 *
* @param pathName 下載文件的條件*
* @return
*/
public boolean downloadFile(FTPClient ftpClient, String pathName, String targetFileName, String localPath) {
boolean flag = false;
OutputStream os = null;
try {
System.out.println("開始下載文件");
//切換FTP目錄
ftpClient.changeWorkingDirectory(pathName);
ftpClient.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles) {
String ftpFileName = file.getName();
if (targetFileName.equalsIgnoreCase(ftpFileName.substring(0, ftpFileName.indexOf(".")))) {
File localFile = new File(localPath);
os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
os.close();
}
}
ftpClient.logout();
flag = true;
logger.info("下載文件成功");
} catch (Exception e) {
logger.error("下載文件失敗");
logger.error(e.getMessage(), e);
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
if (null != os) {
try {
os.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
return flag;
}
/*下載文件*/
public InputStream download(String ftpFile, FTPClient ftpClient) throws IOException {
String servicePath = String.format("%s%s%s", basePath, "/", ftpFile);
logger.info("【從文件服務器獲取文件流】ftpFile : " + ftpFile);
if (Utils.isEmpty(servicePath)) {
throw new RuntimeException("【參數ftpFile爲空】");
}
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
ftpFile = new String(servicePath.getBytes("utf-8"), "iso-8859-1");
return ftpClient.retrieveFileStream(ftpFile);
}
/**
* 刪除文件 *
*
* @param pathname FTP服務器保存目錄 *
* @param filename 要刪除的文件名稱 *
* @return
*/
public boolean deleteFile(String pathname, String filename) {
boolean flag = false;
FTPClient ftpClient = getFtpClient();
try {
logger.info("開始刪除文件");
if (ftpClient.isConnected()) {
//切換FTP目錄
ftpClient.changeWorkingDirectory(pathname);
ftpClient.enterLocalPassiveMode();
ftpClient.dele(filename);
ftpClient.logout();
flag = true;
logger.info("刪除文件成功");
} else {
logger.info("刪除文件失敗");
}
} catch (Exception e) {
logger.error("刪除文件失敗");
logger.error(e.getMessage(), e);
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
return flag;
}
public void closeFtpClient(FTPClient ftpClient) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
public InputStream downloadFile(String pathname, String filename) {
FTPClient ftpClient = getFtpClient();
String filePath = "company/3101051020110114/annexes_url";
InputStream inputStream = null;
try {
System.out.println("開始下載文件");
//切換FTP目錄
ftpClient.changeWorkingDirectory(filePath);
ftpClient.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles) {
System.err.println(file.getName()+"file.getName()");
if (filename.equalsIgnoreCase(file.getName())) {
System.err.println("找到文件了");
inputStream = ftpClient.retrieveFileStream(file.getName());
break;
}
}
ftpClient.logout();
logger.info("下載文件成功");
} catch (Exception e) {
logger.error("下載文件失敗");
logger.error(e.getMessage(), e);
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
return inputStream;
}
}
controller代碼如下:
@RequestMapping(value = "/C20000009",method = RequestMethod.POST)
public Result addPhotoToFTP(MultipartFile file,HttpServletRequest request){
String path = request.getParameter("path");
//給圖片起一個新的名稱,防止在圖片名稱重複
String msg = "";
int code = 0;
if(file!=null){
try {
//圖片上傳,調用ftp工具類 image 上傳的文件夾名稱,newname 圖片名稱,inputStream
boolean hopson = ftpUtil.uploadFileToFtp(path, file.getOriginalFilename(), file.getInputStream());
if(hopson) {
// 把圖片信息存入到數據庫中
msg = "上傳成功";
}
} catch (Exception e) {
msg = "上傳失敗";
code = -1;
e.printStackTrace();
}
}
return Result.error(code, msg);
}
/**
* 功能代碼 C20000010
* 功能名稱 deletePhotoToFTP
* 功能描述 刪除FTP上的文件
* @return
*/
@RequestMapping(value = "/C20000010",method = RequestMethod.POST)
public Result deletePhotoToFTP(@RequestBody Map<String, String> params){
String path = params.get("path");
String filename = params.get("fileName");
String msg = "";
int code = 0;
try {
boolean result = ftpUtil.deleteFile(path, filename);
if (result) {
msg = "刪除成功";
}else {
msg = "刪除失敗";
code = -1;
}
} catch (Exception e) {
msg = "刪除失敗";
code = -1;
}
return Result.error(code, msg);
}
四:從ftp上下載文件到ftp
controller代碼:
@RequestMapping(value = "/C20000012",method = { RequestMethod.POST }, produces = "application/json; charset=utf-8")
@ResponseBody
public Result downloadFileByFTP(@RequestBody Map<String, Object> params,HttpServletRequest request,HttpServletResponse response)throws Exception {
String filePath = params.get("filePath").toString();
String fileName = params.get("fileName").toString();
String msg = "";
int code = 0;
//當文件路徑爲空
if (Utils.isEmpty(filePath)) {
throw new IOException("File'" + filePath + "'is empty");
} else {
// 1.讀取要下載的內容
InputStream in = ftpUtil.downloadFile(filePath, fileName);
// 2. 告訴瀏覽器下載的方式以及一些設置
// 解決文件名亂碼問題,獲取瀏覽器類型,轉換對應文件名編碼格式,IE要求文件名必須是utf-8, firefo要求是iso-8859-1編碼
String agent = request.getHeader("user-agent");
if (agent.contains("FireFox")) {
fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
} else {
fileName = URLEncoder.encode(fileName, "UTF-8");
}
// 設置下載文件的mineType,告訴瀏覽器下載文件類型
String mineType = request.getServletContext().getMimeType(fileName);
response.setContentType(mineType);
// 設置一個響應頭,無論是否被瀏覽器解析,都下載
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
// 將要下載的文件內容通過輸出流寫到瀏覽器
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
//創建存放文件內容的數組
byte[] buff =new byte[1024];
//所讀取的內容使用n來接收
int n;
//當沒有讀取完時,繼續讀取,循環
while((n=in.read(buff))!=-1){
//將字節數組的數據全部寫入到輸出流中
outputStream.write(buff,0,n);
}
//強制將緩存區的數據進行輸出
outputStream.flush();
//關流
outputStream.close();
in.close();
}
return Result.error(code, msg);
}
前端js代碼:
//下載企業附件
previewfile(file){
var params = {
"filePath":file.url,
"fileName":file.name
}
return axios({
method: 'post',
url: baseURL+'api/C20000012',
data: params,
responseType:'blob'
}).then((response)=>{
console.log(response.data,"0000000000")
// 處理返回的文件流
const a = document.createElement('a');
const blob = new Blob([response.data]);
const blobUrl = window.URL.createObjectURL(blob);
download(blobUrl,file.name) ;
}
);
},
download(blobUrl,fileName) {
console.log(fileName,"3333333333333")
const a = document.createElement('a');
a.style.display = 'none';
a.download = fileName;
a.href = blobUrl;
a.click();
},