SpringBoot-集成FTP(上传、下载、删除)

举报
林欣 发表于 2025/04/26 21:35:34 2025/04/26
【摘要】 SpringBoot集成FTP实现文件上传、下载、删除在SpringBoot项目中集成FTP功能,可以通过Apache Commons Net库来实现。下面是一个完整的实现方案,包括配置、上传、下载和删除文件的功能。 1. 添加依赖首先,在pom.xml中添加Apache Commons Net依赖:<dependency> <groupId>commons-net</groupId...

在SpringBoot项目中集成FTP功能,可以通过Apache Commons Net库来实现。下面是一个完整的实现方案,包括配置、上传、下载和删除文件的功能。

1. 添加依赖

首先,在pom.xml中添加Apache Commons Net依赖:

<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.9.0</version>
</dependency>

2. FTP配置类

创建一个FTP配置类,用于存储FTP连接信息:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "ftp")
public class FtpConfig {
    private String host;
    private int port;
    private String username;
    private String password;
    private String basePath;
    
    // getters and setters
    public String getHost() {
        return host;
    }
    
    public void setHost(String host) {
        this.host = host;
    }
    
    public int getPort() {
        return port;
    }
    
    public void setPort(int port) {
        this.port = port;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public String getBasePath() {
        return basePath;
    }
    
    public void setBasePath(String basePath) {
        this.basePath = basePath;
    }
}

application.ymlapplication.properties中配置FTP信息:

ftp:
  host: 127.0.0.1
  port: 21
  username: your_username
  password: your_password
  basePath: /ftp/files

3. FTP工具类

创建一个FTP工具类,封装上传、下载和删除功能:

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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

@Component
public class FtpUtil {

    @Autowired
    private FtpConfig ftpConfig;

    /**
     * 连接FTP服务器
     */
    private FTPClient connect() throws IOException {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("UTF-8");
        ftpClient.connect(ftpConfig.getHost(), ftpConfig.getPort());
        ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword());
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        ftpClient.enterLocalPassiveMode();
        ftpClient.setBufferSize(1024 * 1024); // 设置缓冲区大小
        
        // 检查连接是否成功
        int replyCode = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(replyCode)) {
            ftpClient.disconnect();
            throw new IOException("FTP服务器拒绝连接");
        }
        
        return ftpClient;
    }

    /**
     * 上传文件到FTP服务器
     * @param remotePath 远程路径
     * @param fileName 文件名
     * @param inputStream 输入流
     * @return 是否上传成功
     */
    public boolean uploadFile(String remotePath, String fileName, InputStream inputStream) {
        FTPClient ftpClient = null;
        try {
            ftpClient = connect();
            
            // 切换目录
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                // 如果目录不存在,则创建
                String[] dirs = remotePath.split("/");
                String tempPath = "";
                for (String dir : dirs) {
                    if (dir.length() > 0) {
                        tempPath += "/" + dir;
                        if (!ftpClient.changeWorkingDirectory(tempPath)) {
                            if (!ftpClient.makeDirectory(tempPath)) {
                                return false;
                            }
                        }
                    }
                }
            }
            
            // 上传文件
            boolean success = ftpClient.storeFile(fileName, inputStream);
            return success;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (ftpClient != null && ftpClient.isConnected()) {
                try {
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 从FTP服务器下载文件
     * @param remotePath 远程路径
     * @param fileName 文件名
     * @param outputStream 输出流
     * @return 是否下载成功
     */
    public boolean downloadFile(String remotePath, String fileName, OutputStream outputStream) {
        FTPClient ftpClient = null;
        try {
            ftpClient = connect();
            
            // 切换目录
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                return false;
            }
            
            // 下载文件
            boolean success = ftpClient.retrieveFile(fileName, outputStream);
            return success;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (ftpClient != null && ftpClient.isConnected()) {
                try {
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除FTP服务器上的文件
     * @param remotePath 远程路径
     * @param fileName 文件名
     * @return 是否删除成功
     */
    public boolean deleteFile(String remotePath, String fileName) {
        FTPClient ftpClient = null;
        try {
            ftpClient = connect();
            
            // 切换目录
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                return false;
            }
            
            // 删除文件
            boolean success = ftpClient.deleteFile(fileName);
            return success;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (ftpClient != null && ftpClient.isConnected()) {
                try {
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 检查文件是否存在
     * @param remotePath 远程路径
     * @param fileName 文件名
     * @return 文件是否存在
     */
    public boolean fileExists(String remotePath, String fileName) {
        FTPClient ftpClient = null;
        try {
            ftpClient = connect();
            
            // 切换目录
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                return false;
            }
            
            FTPFile[] files = ftpClient.listFiles();
            for (FTPFile file : files) {
                if (file.getName().equals(fileName)) {
                    return true;
                }
            }
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (ftpClient != null && ftpClient.isConnected()) {
                try {
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4. 使用示例

创建一个控制器来测试FTP功能:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

@RestController
@RequestMapping("/ftp")
public class FtpController {

    @Autowired
    private FtpUtil ftpUtil;

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            boolean success = ftpUtil.uploadFile("/upload", file.getOriginalFilename(), inputStream);
            if (success) {
                return "文件上传成功";
            } else {
                return "文件上传失败";
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传异常";
        }
    }

    @GetMapping("/download")
    public byte[] downloadFile(@RequestParam String fileName) {
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            boolean success = ftpUtil.downloadFile("/upload", fileName, outputStream);
            if (success) {
                return outputStream.toByteArray();
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @DeleteMapping("/delete")
    public String deleteFile(@RequestParam String fileName) {
        boolean success = ftpUtil.deleteFile("/upload", fileName);
        if (success) {
            return "文件删除成功";
        } else {
            return "文件删除失败";
        }
    }

    @GetMapping("/check")
    public String checkFile(@RequestParam String fileName) {
        boolean exists = ftpUtil.fileExists("/upload", fileName);
        if (exists) {
            return "文件存在";
        } else {
            return "文件不存在";
        }
    }
}

5. 注意事项

  1. 连接管理:每次操作都新建连接,操作完成后关闭连接。对于高频操作,可以考虑使用连接池。
  2. 异常处理:实际应用中需要更完善的异常处理和日志记录。
  3. 性能优化:对于大文件传输,可以考虑分块上传/下载。
  4. 安全性:确保FTP服务器配置了适当的安全措施,如使用SFTP/FTPS代替普通FTP。
  5. 被动模式:示例中使用的是被动模式(PASV),适用于大多数防火墙/NAT环境。

6. 高级功能扩展

如果需要更高级的功能,可以考虑:

  1. 断点续传:记录已传输的字节位置,支持中断后继续传输
  2. 目录操作:添加创建目录、删除目录、列出目录等功能
  3. 批量操作:支持批量上传/下载/删除
  4. 进度监控:添加传输进度回调接口

以上实现提供了SpringBoot集成FTP的基本功能,可以根据实际需求进行扩展和优化。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。