2020年12月23日星期三

实战 FastDFS Java 客户端实现分布式文件上传

FastDFS 服务端安装参考文章:分布式文件系统之 FastDFS

安装 FastDFS Java 客户端

先从 GitHub 上将项目源码克隆下来:

$ git clone https://github.com/happyfish100/fastdfs-client-java.git

然后不要忘了部署到 Nexus 依赖私服:

$ mvn clean install deploy

最后在需要用到的项目中添加 POM 依赖即可:

<!-- FastDFS Begin --><dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27-SNAPSHOT</version></dependency><!-- FastDFS End -->

引入依赖以后在 application.yml 中添加 FastDFS 服务端配置:

fastdfs: base: # 一般为 Nginx 代理地址 url: ip}/storage: type: fastdfs fastdfs: tracker_server: {tracker_server ip}

创建 FastDFS 工具类

定义文件存储接口

package com.antoniopeng.fastdfs.service.upload;/** * 文件存储服务接口 */public interface StorageService {  /**  * 上传文件  *  * @param data 文件的二进制内容  * @param extName 扩展名  * @return 上传成功后返回生成的文件 id;失败返回 null  */ public String upload(byte[] data, String extName); /**  * 删除文件  *  * @param fileId 被删除的文件id  * @return 删除成功后返回 0,失败后返回错误代码  */ public int delete(String fileId);}

实现文件存储接口

package com.antoniopeng.fastdfs.service.upload;import org.csource.common.NameValuePair;import org.csource.fastdfs.ClientGlobal;import org.csource.fastdfs.StorageClient1;import org.csource.fastdfs.StorageServer;import org.csource.fastdfs.TrackerClient;import org.csource.fastdfs.TrackerGroup;import org.csource.fastdfs.TrackerServer;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.InitializingBean;import org.springframework.beans.factory.annotation.Value;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;/** * 文件存储服务实现 */public class FastDFSStorageService implements StorageService, InitializingBean {  private static final Logger logger = LoggerFactory.getLogger(FastDFSStorageService.class); private TrackerClient trackerClient; @Value("${storage.fastdfs.tracker_server}") private String trackerServer; @Override public String upload(byte[] data, String extName) {    TrackerServer trackerServer = null;  StorageServer storageServer = null;  StorageClient1 storageClient1 = null;  try {   NameValuePair[] meta_list = null; // new NameValuePair[0];   trackerServer = trackerClient.getConnection();   if (trackerServer == null) {    logger.error("getConnection return null");   }   storageServer = trackerClient.getStoreStorage(trackerServer);   storageClient1 = new StorageClient1(trackerServer, storageServer);   String fileid = storageClient1.upload_file1(data, extName, meta_list);   logger.debug("uploaded file <{}>", fileid);   return fileid;  } catch (Exception ex) {   logger.error("Upload fail", ex);   return null;  } finally {   if (storageServer != null) {    try {     storageServer.close();    } catch (IOException e) {     e.printStackTrace();    }   }   if (trackerServer != null) {    try {     trackerServer.close();    } catch (IOException e) {     e.printStackTrace();    }   }   storageClient1 = null;  } } @Override public int delete(String fileId) {    TrackerServer trackerServer = null;  StorageServer storageServer = null;  StorageClient1 storageClient1 = null;  int index = fileId.indexOf('/');  String groupName = fileId.substring(0, index);  try {   trackerServer = trackerClient.getConnection();   if (trackerServer == null) {    logger.error("getConnection return null");   }   storageServer = trackerClient.getStoreStorage(trackerServer, groupName);   storageClient1 = new StorageClient1(trackerServer, storageServer);   int result = storageClient1.delete_file1(fileId);   return result;  } catch (Exception ex) {   logger.error("Delete fail", ex);   return 1;  } finally {   if (storageServer != null) {    try {     storageServer.close();    } catch (IOException e) {     e.printStackTrace();    }   }   if (trackerServer != null) {    try {     trackerServer.close();    } catch (IOException e) {     e.printStackTrace();    }   }   storageClient1 = null;  } } @Override public void afterPropertiesSet() throws Exception {    File confFile = File.createTempFile("fastdfs", ".conf");  PrintWriter confWriter = new PrintWriter(new FileWriter(confFile));  confWriter.println("tracker_server=" + trackerServer);  confWriter.close();  ClientGlobal.init(confFile.getAbsolutePath());  confFile.delete();  TrackerGroup trackerGroup = ClientGlobal.g_tracker_group;  trackerClient = new TrackerClient(trackerGroup);  logger.info("Init FastDFS with tracker_server : {}", trackerServer); }}

创建文件存储工厂类

package com.antoniopeng.fastdfs.service.upload;import org.springframework.beans.factory.FactoryBean;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.beans.factory.config.AutowireCapableBeanFactory;import java.util.HashMap;import java.util.Map;/** * 文件存储服务工厂类 */public class StorageFactory implements FactoryBean<StorageService> { @Autowired private AutowireCapableBeanFactory acbf; /**  * 存储服务的类型,目前仅支持fastdfs  */ @Value("${storage.type}") private String type; private Map<String, Class<? extends StorageService>> classMap; public StorageFactory() {  classMap = new HashMap<>();  classMap.put("fastdfs", FastDFSStorageService.class); } @Override public StorageService getObject() throws Exception {  Class<? extends StorageService> clazz = classMap.get(type);  if (clazz == null) {   throw new RuntimeException("Unsupported storage type [" + type + "], valid are " + classMap.keySet());  }  StorageService bean = clazz.newInstance();  acbf.autowireBean(bean);  acbf.initializeBean(bean, bean.getClass().getSimpleName());  return bean; } @Override public Class<?> getObjectType() {  return StorageService.class; } @Override public boolean isSingleton() {  return true; }}

配置文件存储工厂类

package com.antoniopeng.fastdfs.service.upload;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * Java 配置方式定义 StorageFactory 的 Bean 使其可以被依赖注入 */@Configurationpublic class FastDFSConfiguration { @Bean public StorageFactory storageFactory() {  return new StorageFactory(); }}

创建 FastDFS 访问控制器

package com.antoniopeng.fastdfs.controller.upload;import com.antoniopeng.fastdfs.service.upload.StorageService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.CrossOrigin;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;@CrossOrigin(origins = "*", maxAge = 3600)@RestControllerpublic class UploadController {  @Value("${fastdfs.base.url}") private String FASTDFS_BASE_URL; @Autowired private StorageService storageService; /**  * 文件上传  *  * @param dropFile Dropzone  * @param editorFiles wangEditor  * @return  */ @RequestMapping(value = "upload", method = RequestMethod.POST) public Map<String, Object> upload(MultipartFile dropFile, MultipartFile[] editorFiles) {  Map<String, Object> result = new HashMap<>();  // Dropzone 上传  if (dropFile != null) {   result.put("fileName", writeFile(dropFile));  }  // wangEditor 上传  if (editorFiles != null && editorFiles.length > 0) {   List<String> fileNames = new ArrayList<>();   for (MultipartFile editorFile : editorFiles) {    fileNames.add(writeFile(editorFile));   }   result.put("errno", 0);   result.put("data", fileNames);  }  return result; } /**  * 将图片写入指定目录  *  * @param multipartFile  * @return 返回文件完整路径  */ private String writeFile(MultipartFile multipartFile) {  // 获取文件后缀  String oName = multipartFile.getOriginalFilename();  String extName = oName.substring(oName.lastIndexOf(".") + 1);  // 文件存放路径  String url = null;  try {   String uploadUrl = storageService.upload(multipartFile.getBytes(), extName);   url = FASTDFS_BASE_URL + uploadUrl;  } catch (IOException e) {   e.printStackTrace();  }  // 返回文件完整路径  return url; }}
  • 文章作者:彭超
  • 本文首发于个人博客:https://antoniopeng.com
  • 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 彭超的博客!








原文转载:http://www.shaoqun.com/a/502833.html

跨境电商:https://www.ikjzd.com/

邮乐网购物商城:https://www.ikjzd.com/w/1776

一淘比价网:https://www.ikjzd.com/w/1698


FastDFS服务端安装参考文章:分布式文件系统之FastDFS安装FastDFSJava客户端先从GitHub上将项目源码克隆下来:$gitclonehttps://github.com/happyfish100/fastdfs-client-java.git然后不要忘了部署到Nexus依赖私服:$mvncleaninstalldeploy最后在需要用到的项目中添加POM依赖即可:<!--
折扣网站:折扣网站
萌店:萌店
中国多地公布今年前三季度多项外贸"成绩单":中国多地公布今年前三季度多项外贸"成绩单"
全球电商平台市场:全球电商平台市场
什么时候去凤凰古城最好玩?:什么时候去凤凰古城最好玩?

没有评论:

发表评论