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,快去试试吧。

相关推荐
计算机毕设指导615 分钟前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
Gu Gu Study17 分钟前
枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~
java·开发语言
Chris _data19 分钟前
二叉树oj题解析
java·数据结构
牙牙70525 分钟前
Centos7安装Jenkins脚本一键部署
java·servlet·jenkins
paopaokaka_luck33 分钟前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
以后不吃煲仔饭1 小时前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师1 小时前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
The_Ticker1 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法