SpringBoot集成FTP

1.加入核心依赖

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

完整依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


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

2.配置文件

ftp:
    host: 127.0.0.1
    port: 21
    username: root
    password: root

3.FTP配置类

java 复制代码
package com.example.config;

import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author lenovo
 */
@Configuration
public class FTPConfig {

    @Value("${ftp.host}")
    private String host;

    @Value("${ftp.port}")
    private int port;

    @Value("${ftp.username}")
    private String username;

    @Value("${ftp.password}")
    private String password;

    @Bean
    public FTPClient ftpClient() {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect(host, port);
            ftpClient.login(username, password);
            ftpClient.enterLocalPassiveMode();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ftpClient;
    }
}

4.Service层

java 复制代码
package com.example.service;

import cn.hutool.crypto.digest.MD5;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

@Service
public interface FTPService {


    public boolean uploadFile(MultipartFile file) ;


    public boolean downloadFile(String remoteFilePath, String localFilePath);

    public boolean deleteFile(String remoteFilePath);


}

实现类:

java 复制代码
package com.example.service.impl;

import com.example.service.FTPService;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

@Service
public class FTPServiceImpl implements FTPService {

    @Autowired
    private FTPClient ftpClient;

    @Override
    public boolean uploadFile(MultipartFile file) {
        try {
            String remoteFilePath = "/w/n";
            ftpClient.enterLocalPassiveMode(); // 设置Passive Mode
            ftpClient.setBufferSize(1024 * 1024); // 设置缓冲区大小为1MB
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 设置传输模式为二进制
            createRemoteDirectory(ftpClient, remoteFilePath);
            // 切换工作目录
            boolean success = ftpClient.changeWorkingDirectory(remoteFilePath);
            if (!success) {
                System.out.println("切换工作目录失败:" + remoteFilePath);
                return false;
            }

            if (file.isEmpty()) {
                System.out.println("上传的文件为空");
                return false;
            }

            String s = md5(Objects.requireNonNull(file.getOriginalFilename()));
            success = ftpClient.storeFile(s, file.getInputStream());

            if (success) {
                System.out.println("文件上传成功");
            } else {
                System.out.println("文件上传失败");
            }
            return success;
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件上传失败:" + e.getMessage());
            return false;
        }
    }

    @Override
    public boolean downloadFile(String remoteFilePath, String localFilePath) {
        try {
            boolean b = ftpClient.retrieveFile(remoteFilePath, Files.newOutputStream(Paths.get(localFilePath)));
            System.out.println(b);
            return b;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean deleteFile(String remoteFilePath) {
        try {
            return ftpClient.deleteFile(remoteFilePath);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 创建文件夹(多层也可创建) 
    public void createRemoteDirectory(FTPClient ftpClient, String remotePath) throws IOException {
        String[] dirs = remotePath.split("/");
        String tempDir = "";
        for (String dir : dirs) {
            if (dir.isEmpty()) {
                continue;
            }
            tempDir += "/" + dir;
            if (!ftpClient.changeWorkingDirectory(tempDir)) {
                if (!ftpClient.makeDirectory(tempDir)) {
                    throw new IOException("Failed to create remote directory: " + tempDir);
                }
                ftpClient.changeWorkingDirectory(tempDir);
            }
        }
    }

    private static String md5(String fileN) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(fileN.getBytes());
            // 将字节数组转换为十六进制字符串
            StringBuilder str = new StringBuilder();
            for (byte b : digest) {
                str.append(String.format("%02x", b));
            }
            fileN = str.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return fileN;
    }
}

5.Controller层

java 复制代码
package com.example.controller;

import com.example.service.FTPService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

    @Autowired
    private FTPService ftpService;

    @PostMapping("/upload")
    public String uploadFile(MultipartFile file) {
        if (ftpService.uploadFile(file)) {
            return "File uploaded successfully!";
        } else {
            return "Failed to upload file!";
        }
    }

    @GetMapping("/download")
    public String downloadFile(String remoteFilePath, String localFilePath) {
        if (ftpService.downloadFile(remoteFilePath, localFilePath)) {
            return "File downloaded successfully!";
        } else {
            return "Failed to download file!";
        }
    }

    @DeleteMapping("/delete")
    public String deleteFile(@RequestParam String remoteFilePath) {
        if (ftpService.deleteFile(remoteFilePath)) {
            return "File deleted successfully!";
        } else {
            return "Failed to delete file!";
        }
    }
}

6.运行效果

以上就创建好了一个小demo,快去试试吧。

相关推荐
茂桑4 分钟前
MVCC(多版本并发控制)
java·开发语言·数据库
customer0819 分钟前
【开源免费】基于SpringBoot+Vue.JS医疗报销系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
B站计算机毕业设计超人23 分钟前
计算机毕业设计SpringBoot+Vue.jst房屋租赁系统(源码+LW文档+PPT+讲解)
vue.js·spring boot·后端·eclipse·intellij-idea·mybatis·课程设计
barcke28 分钟前
【深度解析】Java接入DeepSeek大模型:从零实现流式对话+多轮会话管理(完整项目实战) —— SpringBoot整合、API安全封装、性能优化全攻略
java·spring boot
zl97989940 分钟前
MybatisPlus-注解
java·spring·maven
杰九1 小时前
【环境配置】maven,mysql,node.js,vue的快速配置与上手
java·vue.js·spring boot·mysql·node.js·maven
wapicn991 小时前
‌挖数据平台对接DeepSeek推出一键云端部署功能:API接口驱动金融、汽车等行业智能化升级
java·人工智能·python·金融·汽车·php
逸狼2 小时前
【JavaEE进阶】Spring DI
java·开发语言
m0_748248652 小时前
SpringBoot整合easy-es
spring boot·后端·elasticsearch
yonuyeung2 小时前
代码随想录算法【Day54】
java·数据结构·算法