Integrate FastDFS with Spring Boot for File Upload, Download, and Management
This tutorial shows how to integrate the FastDFS distributed file system into a Spring Boot application, covering Maven dependencies, configuration files, utility classes, core client initialization, and controller code for uploading, downloading, retrieving, and deleting files, with complete code examples and a GitHub source link.
Client
Official Java client for FastDFS is hosted at https://github.com/happyfish100/fastdfs-client-java. A forked version (groupId com.github.secbr, artifactId fastdfs-client-plus, version 1.1.1-RELEASE) fixes naming, adds Maven Central publishing and improves exception handling.
Maven Dependency
<dependency>
<groupId>com.github.secbr</groupId>
<artifactId>fastdfs-client-plus</artifactId>
<version>1.1.1-RELEASE</version>
</dependency>Spring Boot web and Thymeleaf starters are also required:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>Configuration
Copy fdfs_client.conf.sample from the client source to src/main/resources/fdfs_client.conf and adjust the parameters as needed:
# connection timeout (seconds)
connect_timeout = 60
# network timeout (seconds)
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 8888
http.anti_steal_token = no
http.secret_key = 123456
tracker_server = 192.168.43.143:22122The library also accepts a .properties file with the fastdfs. prefix; multiple tracker servers can be listed separated by commas.
Utility Classes
FastDFSFile
public class FastDFSFile {
private String name;
private byte[] content;
private String ext;
private String md5;
private String author;
// getters and setters omitted for brevity
}FastDFSClient Initialization
private static final String CONF_FILE = "fastdfs.conf";
private static TrackerClient trackerClient;
private static TrackerServer trackerServer;
private static StorageServer storageServer;
private static StorageClient1 storageClient;
static {
try {
ClientGlobal.init(CONF_FILE);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getTrackerServer();
storageServer = null; // optional explicit IP configuration
storageClient = new StorageClient1(trackerServer, storageServer);
System.out.println("Init config: " + ClientGlobal.configInfo());
} catch (Exception e) {
logger.error("FastDFSClient init error", e);
}
}Upload Method
public static String[] upload(FastDFSFile file) {
NameValuePair[] metaList = new NameValuePair[1];
metaList[0] = new NameValuePair("author", file.getAuthor());
String[] uploadResults = null;
try {
uploadResults = storageClient.uploadFile(file.getContent(), file.getExt(), metaList);
} catch (Exception e) {
logger.error("Upload error for file: " + file.getName(), e);
}
if (uploadResults == null && storageClient != null) {
logger.error("Upload error, code: " + storageClient.getErrorCode());
}
return uploadResults;
}Get File Info
public static FileInfo getFile(String groupName, String remoteFileName) {
try {
return storageClient.getFileInfo(groupName, remoteFileName);
} catch (Exception e) {
logger.error("Get file error", e);
}
return null;
}Download File
public static InputStream downFile(String groupName, String remoteFileName) {
try {
byte[] fileBytes = storageClient.downloadFile(groupName, remoteFileName);
return new ByteArrayInputStream(fileBytes);
} catch (Exception e) {
logger.error("Download error", e);
}
return null;
}Delete File
public static void deleteFile(String groupName, String remoteFileName) throws Exception {
storageClient.deleteFile(groupName, remoteFileName);
}Controller Layer
Upload endpoint handling multipart file and redirecting to a result page:
@PostMapping("/upload")
public String singleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
try {
String path = saveFile(file);
redirectAttributes.addFlashAttribute("message", "Upload successful");
redirectAttributes.addFlashAttribute("path", "File URL: " + path);
} catch (Exception e) {
logger.error("upload file failed", e);
}
return "redirect:/result";
}File‑saving logic that builds a FastDFSFile, uploads it, and returns the accessible URL:
private String saveFile(MultipartFile multipartFile) throws IOException {
String fileName = multipartFile.getOriginalFilename();
assert fileName != null;
String ext = fileName.substring(fileName.lastIndexOf('.') + 1);
FastDFSFile file = new FastDFSFile(fileName, multipartFile.getBytes(), ext);
String[] fileAbsolutePath = FastDFSClient.upload(file);
if (fileAbsolutePath == null) {
logger.error("Upload failed, please retry");
throw new RuntimeException("Upload failed");
}
return FastDFSClient.getTrackerUrl()
+ fileAbsolutePath[0] + "/" + fileAbsolutePath[1];
}Running the Spring Boot application makes the upload page available; after a successful upload the returned URL can be opened in a browser to view the stored file.
Full source code for this integration: https://github.com/secbr/springboot-all/tree/master/springboot-fastdfs
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Senior Brother's Insights
A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
