前两篇整体上介绍了通过 Nginx 和 FastDFS 的整合来实现文件服务器。但是,在实际开发中对图片或文件的操作都是通过应用程序来完成的,因此,本篇将介绍 Spring Boot 整合 FastDFS 客户端来实现对图片/文件服务器的访问。
如果有不了解 FastDFS 的读者可以先浏览《FastDFS 环境搭建》 和 《Nginx 整合 FastDFS 实现文件服务器》 来普及内容,或是另行查阅网上相关资料。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
上边的 fastdfs-client 是并非 FastDFS Client 原作者编写的整合包,具体详情可以访问 https://github.com/tobato/FastDFS_Client。
server.port=8080
# fastDFS 配置
fdfs.so-timeout=1501
fdfs.connect-timeout=601
fdfs.thumb-image.width=150
fdfs.thumb-image.height=150
fdfs.web-server-url=192.168.10.110/
fdfs.tracker-list[0]=192.168.10.110:22122
@Configuration
@Import(FdfsClientConfig.class)
// 解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class ComponetImport {
// 导入依赖组件
}
@Component
public class FastDFSClient {
private final Logger logger = LoggerFactory.getLogger(FastDFSClient.class);
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private FdfsWebServer fdfsWebServer;
/**
* 上传文件
* @param file 文件对象
* @return 文件访问地址
* @throws IOException
*/
public String uploadFile(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
return getResAccessUrl(storePath);
}
/**
* 上传文件
* @param file 文件对象
* @return 文件访问地址
* @throws IOException
*/
public String uploadFile(File file) throws IOException {
FileInputStream inputStream = new FileInputStream (file);
StorePath storePath = storageClient.uploadFile(inputStream,file.length(), FilenameUtils.getExtension(file.getName()),null);
return getResAccessUrl(storePath);
}
/**
* 将一段字符串生成一个文件上传
* @param content 文件内容
* @param fileExtension
* @return
*/
public String uploadFile(String content, String fileExtension) {
byte[] buff = content.getBytes(Charset.forName("UTF-8"));
ByteArrayInputStream stream = new ByteArrayInputStream(buff);
StorePath storePath = storageClient.uploadFile(stream,buff.length, fileExtension,null);
return getResAccessUrl(storePath);
}
// 封装图片完整URL地址
private String getResAccessUrl(StorePath storePath) {
String fileUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
return fileUrl;
}
/**
* 下载文件
* @param fileUrl 文件url
* @return
*/
public byte[] download(String fileUrl) {
String group = fileUrl.substring(0, fileUrl.indexOf("/"));
String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
byte[] bytes = storageClient.downloadFile(group, path, new DownloadByteArray());
return bytes;
}
/**
* 删除文件
* @param fileUrl 文件访问地址
* @return
*/
public void deleteFile(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
return;
}
try {
StorePath storePath = StorePath.praseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
} catch (FdfsUnsupportStorePathException e) {
logger.warn(e.getMessage());
}
}
}
@RestController
@RequestMapping("/fdfs")
public class FastDFSController {
@Autowired
private FastDFSClient fdfsClient;
/**
* 文件上传
* @param file
* @return
* @throws Exception
*/
@RequestMapping("/upload")
public Map<String,Object> upload(MultipartFile file) throws Exception{
String url = fdfsClient.uploadFile(file);
Map<String,Object> result = new HashMap<>();
result.put("code", 200);
result.put("msg", "上传成功");
result.put("url", url);
return result;
}
/**
* 文件下载
* @param fileUrl url 开头从组名开始
* @param response
* @throws Exception
*/
@RequestMapping("/download")
public void download(String fileUrl, HttpServletResponse response) throws Exception{
byte[] data = fdfsClient.download(fileUrl);
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("test.jpg", "UTF-8"));
// 写出
ServletOutputStream outputStream = response.getOutputStream();
IOUtils.write(data, outputStream);
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<style>
form {
margin-top: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-sm-4"></div>
<div class="col-md-4 col-sm-4">
<h2> FastDFS 文件上传</h2>
<form th:action="@{/fdfs/upload}" method="post" enctype="multipart/form-data">
<div class="form-group">
<input type="file" name="file" id="exampleInputFile">
</div>
<button type="submit" class="btn btn-default">上传</button>
</form>
</div>
<div class="col-md-4 col-sm-4"></div>
</div>
</div>
</body>
</html>
本篇只测试文件上传和访问的效果,演示图如下:
整合成功~~
注意:测试下载文件时,文件名从 group_name 开始。如:“http://192.168.10.110/light/M00/00/00/wKgKblvIHsCAaz0YAAISssL81hU232.jpg” ,文件名路径只需要设置为 light/M00/00/00/wKgKblvIHsCAaz0YAAISssL81hU232.jpg 即可。
转自:https://www.extlight.com/2018/10/21/Spring-Boot-整合-FastDFS-客户端/