国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot-集成FTP(上傳、下載、刪除)

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot-集成FTP(上傳、下載、刪除)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一、引入依賴

二、配置文件

三、Controller層

四、Service層

五、相關(guān)工具類


由于服務(wù)在內(nèi)網(wǎng)部署,需要使用ftp服務(wù)器管理文件,總結(jié)如下

一、引入依賴

<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.9.0</version>
</dependency>

<!-- hutool -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.22</version>
</dependency>

Tip:使用commons-net 3.9.0版本,之前的版本有漏洞

二、配置文件

ftp:
  basePath: /
  host: 192.168.1.100
  httpPath: ftp://192.168.1.100
  password: demo
  port: 21
  username: demo

配置文件類:

package com.example.demo.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @Author: meng
 * @Description: ftp配置
 * @Date: 2023/6/30 13:44
 * @Version: 1.0
 */
@Data
@Component
@ConfigurationProperties(prefix = "ftp")
public class FtpProperties {
	/**
	 * ftp服務(wù)器的地址
	 */
	private String host;
	/**
	 * ftp服務(wù)器的端口號(連接端口號)
	 */
	private String port;
	/**
	 * ftp的用戶名
	 */
	private String username;
	/**
	 * ftp的密碼
	 */
	private String password;
	/**
	 * ftp上傳的根目錄
	 */
	private String basePath;
	/**
	 * 回顯地址
	 */
	private String httpPath;
}

三、Controller層

Tip:Response為通用返回類,不熟悉的可以看這篇文章:Springboot - 通用返回類BaseResults_W_Meng_H的博客-CSDN博客BaseResults類public class BaseResults { private Integer code; private String message; private T data; public BaseResults() { super(); } public BaseResu...https://blog.csdn.net/W_Meng_H/article/details/104995823

package com.example.demo.controller;

import com.example.demo.service.FtpService;
import com.template.common.core.data.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author: meng
 * @Description: 文件服務(wù)
 * @Date: 2023/6/30 14:33
 * @Version: 1.0
 */
@RestController
@RequestMapping("/file")
public class FileController {

	@Autowired
	private FtpService ftpService;

	// 單上傳文件
	@PostMapping(value = "upload", consumes = "multipart/*", headers = "content-type=multipart/form-data")
	public Response uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
		return ftpService.uploadMultipartFile(file, request);
	}

	// 導(dǎo)出文件
	@GetMapping(value = "download")
	public void downloadFile(@RequestParam String fileName, @RequestParam String ftpFilePath, HttpServletResponse response) {
		ftpService.downloadFileToFtp(fileName, ftpFilePath, response);
	}

	// 刪除文件
	@GetMapping(value = "delete")
	public Response deleteFile(@RequestParam String ftpFilePath) {
		return ftpService.deleteFileToFtp(ftpFilePath);
	}


}

四、Service層

package com.example.demo.service;

import com.template.common.core.data.Response;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author: meng
 * @Description: ftp服務(wù)類
 * @Date: 2023/6/30 13:46
 * @Version: 1.0
 */
public interface FtpService {
	/**
	 * 上傳文件到ftp
	 * @param multipartFile
	 * @param request
	 * @return
	 */
	public Response uploadMultipartFile(MultipartFile multipartFile, HttpServletRequest request);

	/**
	 * 下載ftp文件,直接轉(zhuǎn)到輸出流
	 * @param fileName
	 * @param ftpFilePath
	 * @param response
	 */
	public void downloadFileToFtp(String fileName, String ftpFilePath, HttpServletResponse response);

	/**
	 * 刪除ftp文件
	 * @param ftpFilePath ftp下文件路徑,根目錄開始
	 * @return
	 */
	Response deleteFileToFtp(String ftpFilePath);
}

實(shí)現(xiàn)類:文章來源地址http://www.zghlxwxcb.cn/news/detail-518759.html

package com.example.demo.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.example.demo.config.FtpProperties;
import com.example.demo.service.FtpService;
import com.example.demo.tools.FileUtils;
import com.template.common.core.data.Response;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;

/**
 * @Author: meng
 * @Description: ftp服務(wù)類
 * @Date: 2023/6/30 13:47
 * @Version: 1.0
 */
@Service
public class FtpServiceImpl implements FtpService {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private FtpProperties ftpProperties;


	// 方式一
	@Override
	public Response uploadMultipartFile(MultipartFile multipartFile, HttpServletRequest request) {
		if (multipartFile == null || multipartFile.isEmpty()) {
			return Response.error("沒有上傳文件");
		}
		//1、獲取原文件后綴名
		String originalFileName = multipartFile.getOriginalFilename();
		String suffix = originalFileName.substring(originalFileName.lastIndexOf('.'));
		//2、使用UUID生成新文件名
		String newFileName = IdUtil.fastSimpleUUID();
		//3、將MultipartFile轉(zhuǎn)化為File
		File file = null;
		try {
			// file = FileUtils.multipartFileToFile(multipartFile);
            flag = uploadFileToFtp(multipartFile.getInputStream(), newFileName + suffix, today, ftpClient);
		} catch (Exception e) {
			logger.error("文件上傳失敗:", e);
			return Response.error("文件上傳失敗");
		}
		if (ObjectUtil.isNull(file)) {
			return Response.error("文件上傳失敗");
		}
		//當(dāng)前日期字符串
		String today = File.separator + DateUtil.format(new Date(), "yyyyMMdd");
		Boolean flag = uploadFileToFtp(file, newFileName + suffix, today);
		if (!flag) {
			return Response.error("文件上傳失敗");
		}
		System.out.println(file.toURI());
		File f = new File(file.toURI());
		f.delete();
		String filePath = ftpProperties.getHttpPath() + today + File.separator + newFileName + suffix;
		return Response.success(filePath);
	}
	
	// 方式二
	public Response uploadMultipartFile2(MultipartFile multipartFile, HttpServletRequest request) {
		FTPClient ftpClient = connectFtpServer();
		if (multipartFile == null || multipartFile.isEmpty()) {
			return R.error(Constants.FILE_EMPTY);
		}
		//獲取原文件后綴名
		String originalFileName = multipartFile.getOriginalFilename();
		String suffix = originalFileName.substring(originalFileName.lastIndexOf('.'));
		//使用UUID生成新文件名
		String newFileName = IdUtil.fastSimpleUUID();
		//當(dāng)前日期字符串
		String today = separator + DateUtil.date().toString(DATE_FORMAT);
		Boolean flag = false;
		try {
			flag = uploadFileToFtp(multipartFile.getInputStream(), newFileName + suffix, today, ftpClient);
		} catch (Exception e) {
			logger.error("文件上傳失敗:", e);
		}
		if (!flag) {
			logger.info("文件上傳失敗");
			return R.error("文件上傳失敗");
		}
		String filePath = ftpProperties.getHttpPath() + today + File.separator + newFileName + suffix;
		return Response.success(filePath);
	}

	public Boolean uploadFileToFtp(File file, String fileName, String filePath) {
		logger.info("調(diào)用文件上傳接口");
		// 定義保存結(jié)果
		boolean iaOk = false;
		// 初始化連接
		FTPClient ftp = connectFtpServer();
		if (ftp != null) {
			try {
				// 設(shè)置文件傳輸模式為二進(jìn)制,可以保證傳輸?shù)膬?nèi)容不會被改變
				ftp.setFileType(FTP.BINARY_FILE_TYPE);
				ftp.enterLocalPassiveMode();    //注:上傳文件都為0字節(jié),設(shè)置為被動(dòng)模式即可
				// 跳轉(zhuǎn)到指定路徑,逐級跳轉(zhuǎn),不存在的話就創(chuàng)建再進(jìn)入
				toPathOrCreateDir(ftp, filePath);
				InputStream inputStream = new FileInputStream(file);
				// 上傳文件 參數(shù):上傳后的文件名,輸入流,,返回Boolean類型,上傳成功返回true
				iaOk = ftp.storeFile(fileName, inputStream);
				// 關(guān)閉輸入流
				inputStream.close();
				// 退出ftp
				ftp.logout();
			} catch (IOException e) {
				logger.error(e.toString());
			} finally {
				if (ftp.isConnected()) {
					try {
						// 斷開ftp的連接
						ftp.disconnect();
					} catch (IOException ioe) {
						logger.error(ioe.toString());
					}
				}
			}
		}
		return iaOk;
	}

	@Override
	public void downloadFileToFtp(String fileName, String ftpFilePath, HttpServletResponse response) {
		FTPClient ftpClient = connectFtpServer();
		try {
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.enterLocalPassiveMode();
			// 設(shè)置文件ContentType類型,這樣設(shè)置,會自動(dòng)判斷下載文件類型
			response.setContentType("application/x-msdownload");
			// 設(shè)置文件頭:最后一個(gè)參數(shù)是設(shè)置下載的文件名并編碼為UTF-8
			response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
			InputStream is = ftpClient.retrieveFileStream(ftpFilePath);
			BufferedInputStream bis = new BufferedInputStream(is);
			OutputStream out = response.getOutputStream();
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = bis.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			out.flush();
			out.close();

			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			ftpClient.logout();
		} catch (Exception e) {
			logger.error("FTP文件下載失敗:", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException ioe) {
					logger.error(ioe.toString());
				}
			}
		}
	}

	@Override
	public Response deleteFileToFtp(String ftpFilePath) {
		FTPClient ftp = connectFtpServer();
		boolean resu = false;
		try {
			resu = ftp.deleteFile(ftpFilePath);
			ftp.logout();
		} catch (Exception e) {
			logger.error("FTP文件刪除失敗:{}", e);
			return Response.error("文件刪除失敗");
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
					logger.error(ioe.toString());
				}
			}
		}
		return Response.SUCCESS;
	}

	private FTPClient connectFtpServer() {
		// 創(chuàng)建FTPClient對象(對于連接ftp服務(wù)器,以及上傳和上傳都必須要用到一個(gè)對象)
		logger.info("創(chuàng)建FTP連接");
		FTPClient ftpClient = new FTPClient();
		// 設(shè)置連接超時(shí)時(shí)間
		ftpClient.setConnectTimeout(1000 * 60);
		// 設(shè)置ftp字符集
		ftpClient.setControlEncoding("utf-8");
		// 設(shè)置被動(dòng)模式,文件傳輸端口設(shè)置,否則文件上傳不成功,也不報(bào)錯(cuò)
		ftpClient.enterLocalPassiveMode();
		try {
			// 定義返回的狀態(tài)碼
			int replyCode;
			// 連接ftp(當(dāng)前項(xiàng)目所部署的服務(wù)器和ftp服務(wù)器之間可以相互通訊,表示連接成功)
			ftpClient.connect(ftpProperties.getHost());
			// 輸入賬號和密碼進(jìn)行登錄
			ftpClient.login(ftpProperties.getUsername(), ftpProperties.getPassword());
			// 接受狀態(tài)碼(如果成功,返回230,如果失敗返回503)
			replyCode = ftpClient.getReplyCode();
			// 根據(jù)狀態(tài)碼檢測ftp的連接,調(diào)用isPositiveCompletion(reply)-->如果連接成功返回true,否則返回false
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				logger.info("connect ftp {} failed", ftpProperties.getHost());
				// 連接失敗,斷開連接
				ftpClient.disconnect();
				return null;
			}
			logger.info("replyCode:" + replyCode);
		} catch (IOException e) {
			logger.error("connect fail:" + e.toString());
			return null;
		}
		return ftpClient;
	}

	private void toPathOrCreateDir(FTPClient ftp, String filePath) throws IOException {
		String[] dirs = filePath.split("/");
		for (String dir : dirs) {
			if (StrUtil.isBlank(dir)) {
				continue;
			}

			if (!ftp.changeWorkingDirectory(dir)) {
				ftp.makeDirectory(dir);
				ftp.changeWorkingDirectory(dir);
			}
		}
	}

}

五、相關(guān)工具類

package com.example.demo.tools;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @Author: meng
 * @Description: 文件轉(zhuǎn)換工具類
 * @Date: 2023/6/30 14:13
 * @Version: 1.0
 */
public class FileUtils {

	/**
	 * MultipartFile 轉(zhuǎn) File
	 * @param file
	 * @throws Exception
	 */
	public static File multipartFileToFile(MultipartFile file) throws Exception {
		File toFile = null;
		if(file.equals("")||file.getSize()<=0){
			file = null;
		}else {
			InputStream ins = null;
			ins = file.getInputStream();
			toFile = new File(file.getOriginalFilename());
			toFile = inputStreamToFile(ins, toFile);
			ins.close();
		}
		return toFile;
	}


	private static File 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();
			return file;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}

到了這里,關(guān)于SpringBoot-集成FTP(上傳、下載、刪除)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring Boot集成Quartz實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)創(chuàng)建、啟動(dòng)、暫停、恢復(fù)、刪除

    Spring Boot集成Quartz實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)創(chuàng)建、啟動(dòng)、暫停、恢復(fù)、刪除

    一、整個(gè) Quartz 的代碼流程基本基本如下: 首先需要?jiǎng)?chuàng)建我們的任務(wù)(Job),比如取消訂單、定時(shí)發(fā)送短信郵件之類的,這是我們的任務(wù)主體,也是寫業(yè)務(wù)邏輯的地方。 創(chuàng)建任務(wù)調(diào)度器(Scheduler),這是用來調(diào)度任務(wù)的,主要用于啟動(dòng)、停止、暫停、恢復(fù)等操作,也就是那幾個(gè)api的

    2024年02月11日
    瀏覽(21)
  • Spring Boot學(xué)習(xí)隨筆- 文件上傳和下載(在線打開、附件下載、MultipartFile)

    Spring Boot學(xué)習(xí)隨筆- 文件上傳和下載(在線打開、附件下載、MultipartFile)

    學(xué)習(xí)視頻:【編程不良人】2021年SpringBoot最新最全教程 文件上傳是指將文件從客戶端計(jì)算機(jī)傳輸?shù)椒?wù)器的過程。 上傳思路 前端的上傳頁面:提交方式必須為 post , enctype 屬性必須為 multipart/form-data 開發(fā)后端的Controller 后端方法接收參數(shù)必須和前端標(biāo)簽的name名一致 upload.js

    2024年02月04日
    瀏覽(51)
  • Springboot + MySQL + html 實(shí)現(xiàn)文件的上傳、存儲、下載、刪除

    Springboot + MySQL + html 實(shí)現(xiàn)文件的上傳、存儲、下載、刪除

    實(shí)現(xiàn)步驟及效果呈現(xiàn)如下: 1.創(chuàng)建數(shù)據(jù)庫表: 表名:file_test 存儲后的數(shù)據(jù): 2.創(chuàng)建數(shù)據(jù)庫表對應(yīng)映射的實(shí)體類: import com.baomidou.mybatisplus.annotation.IdType ; import com.baomidou.mybatisplus.annotation. TableField ; import com.baomidou.mybatisplus.annotation. TableId ; import com.baomidou.mybatisplus.annotation. Tab

    2024年04月29日
    瀏覽(28)
  • minio + linux + docker + spring boot實(shí)現(xiàn)文件上傳與下載

    minio + linux + docker + spring boot實(shí)現(xiàn)文件上傳與下載

    檢查linux內(nèi)核,必須是3.10以上 安裝docker 啟動(dòng)docker 搜索鏡像 拉取鏡像 啟動(dòng)minio -p: 指定端口映射,格式為:主機(jī)端口:容器端口 (這里注意要映射兩個(gè),否則API會訪問不到) -e “MINIO_ROOT_USER=vinci” minio用戶名; -e MINIO_SECRET_KEY=123456 minio 密碼 -d: 后臺運(yùn)行容器,并返回容器ID; -

    2024年02月07日
    瀏覽(28)
  • spring boot集成Elasticsearch-SpringBoot(25)

    spring boot集成Elasticsearch-SpringBoot(25)

    ??搜索引擎(search engine )通常意義上是指:根據(jù)特定策略,運(yùn)用特定的爬蟲程序從互聯(lián)網(wǎng)上搜集信息,然后對信息進(jìn)行處理后,為用戶提供檢索服務(wù),將檢索到的相關(guān)信息展示給用戶的系統(tǒng)。 ??而我們講解的是捜索的索引和檢索,不涉及爬蟲程序的內(nèi)容爬取。大部分公司

    2023年04月09日
    瀏覽(24)
  • 【SpringBoot3】Spring Boot 3.0 集成 Redis 緩存

    Redis緩存是一個(gè)開源的使用ANSIC語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。它主要用于作為數(shù)據(jù)庫、緩存和消息中間件,以快速讀寫和豐富的數(shù)據(jù)結(jié)構(gòu)支持而著稱。 在應(yīng)用程序和數(shù)據(jù)庫之間,Redis緩存作為一個(gè)中間層起著關(guān)鍵

    2024年02月21日
    瀏覽(90)
  • spring boot學(xué)習(xí)第六篇:SpringBoot 集成WebSocket詳解

    spring boot學(xué)習(xí)第六篇:SpringBoot 集成WebSocket詳解

    1、WebSocket簡介 WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動(dòng)發(fā)送信息給客戶端。 2、為什么需要WebSocket HTTP 是基于請求響應(yīng)式的,即通信只能由客戶端發(fā)起,服務(wù)端做出響應(yīng),無狀態(tài),無連接。 無狀態(tài):每次連

    2024年01月21日
    瀏覽(25)
  • Java spring-boot項(xiàng)目中如何上傳下載文件或圖片到spring-boot規(guī)定的非靜態(tài)目錄

    spring-boot的項(xiàng)目,雖然它自己定義了一個(gè)靜態(tài)文件的存儲目錄,但是這個(gè)目錄一般是作為前端靜態(tài)文件的目錄來作為使用的。如果使用這個(gè)靜態(tài)目錄來作為我們上傳文件的目錄會有一個(gè)比較尷尬的地方:將spring-boot打包成為jar包后,隨著上傳圖片的增多,這個(gè)jar包也會跟著變大

    2024年02月16日
    瀏覽(20)
  • SpringBoot整合hdfs,實(shí)現(xiàn)文件上傳下載刪除與批量刪除,以及vue前端發(fā)送請求,實(shí)現(xiàn)前后端交互功能;

    SpringBoot整合hdfs,實(shí)現(xiàn)文件上傳下載刪除與批量刪除,以及vue前端發(fā)送請求,實(shí)現(xiàn)前后端交互功能;

    部分工具類代碼參考文章:https://blog.csdn.net/qq_27242695/article/details/119683823 前端實(shí)現(xiàn)效果 HDFSController HDFS FileInterface (文件接口) HDFS FileImplService (文件接口實(shí)現(xiàn)類) HDFSConfig(從yaml讀取文件) HDFSUTils 前端vue代碼:

    2024年02月16日
    瀏覽(130)
  • Spring Boot學(xué)習(xí)隨筆- 集成MyBatis-Plus(三)自定義SQL、分頁實(shí)現(xiàn)(PaginationInterceptor )、更新和刪除詳細(xì)方法

    學(xué)習(xí)視頻:【編程不良人】Mybatis-Plus整合SpringBoot實(shí)戰(zhàn)教程,提高的你開發(fā)效率,后端人員必備! 自定義mapper文件是為了應(yīng)對一些更復(fù)雜的查詢場景,首先先配置映射路徑 由于這里的mapper文件放在java文件夾中,所以要在pom.xml里進(jìn)行配置 mapper 測試 在MyBatis Plus中, 物理分頁 和 內(nèi)

    2024年02月03日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包