导读
原本在腾讯云搭建了一台Nginx和FTP服务器,用来作为图片保存之地。
使用步骤
1、依赖
SpringBoot项目导入以下依赖。
<dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.6</version></dependency>
2、FTP连接工厂
该连接工厂使用createFtpConnection创建FTP连接,ftpConnectionClose关闭FTP连接。
import lombok.Data;import org.apache.commons.net.ftp.FTPClient;import org.apache.commons.net.ftp.FTPReply;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;/*** FTP连接工厂** @author chaohen* @date 2019/8/23*/@Datapublic class FtpConnectionFactory {private static Logger LOGGER = LoggerFactory.getLogger(FtpConnectionFactory.class);/*** FTP ip地址*/private static String address = "000.000.000.000";/*** FTP 端口号*/private static int port = 21;/*** FTP 设置字符集*/private static String charset = "GBK";/*** FTP 用户名*/private static String username = "uftp";/*** FTP 密码*/private static String password = "upwd123456";/*** ftpClient*/private static FTPClient ftpClient;/*** 新建FTP连接** @return*/synchronized public static FTPClient createFtpConnection() {if (ftpClient == null || !ftpClient.isConnected()) {try {ftpClient = new FTPClient();//连接IP 如果port【端口】存在的话ftpClient.connect(address, port);//设置编码类型ftpClient.setControlEncoding(charset);//每次数据连接之前,ftpClient告诉ftp server开通一个端口来传输数据ftpClient.enterLocalPassiveMode();//登录ftpClient.login(username, password);//连接尝试后,应检查回复代码以验证int reply = ftpClient.getReplyCode();//没验证成功if (!FTPReply.isPositiveCompletion(reply)) {//断开ftp连接ftpClient.disconnect();return null;}LOGGER.info("The ftp server is successfully connected.");} catch (Exception e) {LOGGER.error("Failed to log in. The error message is: " + e.getMessage());}}return ftpClient;}/*** 关闭FTP连接 ftpClose*/public static void ftpConnectionClose(FTPClient ftpClient) {if (ftpClient != null) {if (ftpClient.isConnected()) {try {ftpClient.disconnect();LOGGER.info("Ftp connection closed...");} catch (IOException e) {LOGGER.error("Ftp connection failed to disconnect, error message is:" + e.getMessage());}}}}}
3、FTP上传下载工具类
里面有两个方法,uploadFile用来上传,getFileByFtp用来下载。
import com.heioky.filesystemupload.config.FtpConnectionFactory;import org.apache.commons.net.ftp.FTPClient;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.*;/*** ftp文件上传工具类** @author hanyc* @date 2019/8/23*/public class FtpFileUploadUtils {private static Logger logger = LoggerFactory.getLogger(FtpFileUploadUtils.class);/*** 文件上传** @param remotePath 上传到远程的文件夹路径* @param originFileName 文件名* @param inputStream 文件流* @return*/public static boolean uploadFile(String remotePath, String originFileName, InputStream inputStream) {//连接FTPFTPClient ftpClient = FtpConnectionFactory.createFtpConnection();try {// 设置文件类型(二进制)ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//创建文件夹,如果有的话 就不会创建,返回falseftpClient.makeDirectory(remotePath);// 设置上传目录ftpClient.changeWorkingDirectory(remotePath);//文件转移时候的一次性读取大小ftpClient.setBufferSize(1024);//将流写到服务器ftpClient.storeFile(originFileName, inputStream);inputStream.close();//ftp服务退出ftpClient.logout();return true;} catch (IOException e) {e.printStackTrace();} finally {if (ftpClient != null) {FtpConnectionFactory.ftpConnectionClose(ftpClient);}}return false;}/*** 下载文件** @param remotePath ftp上文件存放的地址 如: /img/logo.png* @param localPath:本地存放文件的地址 如:E:\images\logo.png*/public static void getFileByFtp(String remotePath, String localPath) {File localFile = new File(localPath);OutputStream ous = null;FTPClient ftpClient = FtpConnectionFactory.createFtpConnection();try {ous = new FileOutputStream(localFile);ftpClient.retrieveFile(remotePath, ous);} catch (FileNotFoundException e) {e.printStackTrace();logger.info("file not fount...");} catch (IOException e) {e.printStackTrace();} finally {if (ftpClient != null) {FtpConnectionFactory.ftpConnectionClose(ftpClient);}}}}
4、测试
4.1 controller层代码
package com.heioky.filesystemupload.controller;import com.heioky.filesystemupload.utils.FtpFileUploadUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.multipart.MultipartFile;import java.io.*;import java.util.UUID;/*** 文件上传** @author chaohen* @date 2019/8/22*/@Controller@RequestMapping("/api")public class IndexController {private static final Logger logger = LoggerFactory.getLogger(IndexController.class);@PostMapping("/uploadFile")@ResponseBodypublic String updateAvatar(MultipartFile file) {try {if (!file.isEmpty()) {//获取文件(图片或者文件)的后缀名String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));//拼接图片或文件名称,32位随机uuid+后缀名,当然也可以使用其他方式生成String fileName = UUID.randomUUID().toString().replace("-", "").toLowerCase() + suffix;InputStream inputStream = file.getInputStream();//调用ftp上传文件工具类,返回true成功,返回false失败Boolean flag = FtpFileUploadUtils.uploadFile("/", fileName, inputStream);if (flag == true) {//这里是上传成功后,所需要执行的逻辑代码return "上传成功!";}}return "上传失败,文件不能为空!";} catch (Exception e) {return "上传异常,请重试!";}}}
4.2 页面代码
<body><form action="/api/uploadFile" method="post" enctype="multipart/form-data"><input id="file" name="file" type="file" multiple="multiple" style="margin:100px;"/><input type="submit" value="上传"></form></body>
注意
如果使用yml的形式,需要导入以下依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>
也就是通过使用 @ConfigurationProperties(prefix = "ftp") 来获取yml自定义属性的信息。
@Data@Component@ConfigurationProperties(prefix = "ftp")public Class FtProperties{private String address;private int port;private String username;private String password;}
application.yml配置
ftp:address: 000.000.000.000port: 21charset: GBKusername: uftppassword: upwd123456
普通的文件上传,请点击查看:SpirngBoot文件上传
