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