目录:
(1)常用API介绍
(2)Demo环境初始化
(3)FastDFS文件工具类
(4)文件上传

(1)常用API介绍
现在使用Java操作一下FastDFS

FastDFS JavaAPI里面有几个常用类:
CLientGlobal:加载配置文件的
TranckerServer:是连接FastDFS里面的trackerServer,是通过TrackerClient创建的
是一个连接对象
StorageServer:是连接FastDFS中的Storage Server它是通过trackerClient并通过传入trackerServer构建的
所以构建存储服务对象的时候需依赖跟踪器服务对象
是一个存储服务类型
StorageClient:真正的操作文件的客户端类型,构建的时候通过TrackerServer和StorageSeerver
常规操作:比如上传啊,下载啊或者删除

(2)Demo环境初始化



删除没用的文件:

在pom.xml中引入FastDFS依赖:

创建conf的配置文件,去初始化ClientGlobal对象

fast.client.conf:配置文件
- #连接超时
- connect_timeout = 2
- #网络超时
- network_timeout = 30
- #编码格式
- charset = UTF-8
- #tracker端口号
- http.tracker_http_port = 8080
- #防盗链功能
- http.anti_steal_token = no
- #秘钥
- http.secret_key = FastDFS1234567890
- #tracker ip:端口号
- tracker_server = 192.168.23.129:22122
- #连接池配置
- connection_pool.enabled = true
- connection_pool.max_count_per_entry = 500
- connection_pool.max_idle_time = 3600
- connection_pool.max_wait_time_in_ms = 1000
准备一个FastDFS的对象:

FastDFSFile:
- package com.xxxx.fastdfsdemo.pojo;
-
- public class FastDFSFile {
- private String name;
- private byte[] content;
- private String ext;
- private String md5;
- private String author;
- private String height;
-
- public FastDFSFile() {
- }
-
- public FastDFSFile(String name, byte[] content, String ext) {
- this.name = name;
- this.content = content;
- this.ext = ext;
- }
-
- public FastDFSFile(String name, byte[] content, String ext, String md5, String author, String height) {
- this.name = name;
- this.content = content;
- this.ext = ext;
- this.md5 = md5;
- this.author = author;
- this.height = height;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public byte[] getContent() {
- return content;
- }
-
- public void setContent(byte[] content) {
- this.content = content;
- }
-
- public String getExt() {
- return ext;
- }
-
- public void setExt(String ext) {
- this.ext = ext;
- }
-
- public String getMd5() {
- return md5;
- }
-
- public void setMd5(String md5) {
- this.md5 = md5;
- }
-
- public String getAuthor() {
- return author;
- }
-
- public void setAuthor(String author) {
- this.author = author;
- }
-
- public String getHeight() {
- return height;
- }
-
- public void setHeight(String height) {
- this.height = height;
- }
-
- }
不在去写controller-service了,直接写一个上传文件的工具类,然后再service里面直接调用工具类
FastDFSClient:
- package com.xxxx.fastdfsdemo.utils;
-
- import org.csource.fastdfs.ClientGlobal;
- import org.csource.fastdfs.StorageClient;
- import org.csource.fastdfs.TrackerClient;
- import org.csource.fastdfs.TrackerServer;
- import org.slf4j.LoggerFactory;
-
- import org.slf4j.Logger;
- import org.springframework.core.io.ClassPathResource;
-
- import java.io.IOException;
-
- public class FastDFSClient {
-
- //准备logger日志
- private static Logger logger= LoggerFactory.getLogger(FastDFSClient.class);
-
- //ClientGlobal.init会读取配置文件 并初始化对应的属性
- static {
- try {
- String filePath=new ClassPathResource("fast_client.conf").getFile().getAbsolutePath();
- ClientGlobal.init(filePath);
- } catch (Exception e) {
- logger.error("FastDFS初始化失败!",e.getMessage());
- }
- }
-
- /*
- *
- * 生成Storage客户端
- * */
- private static StorageClient getStorageClient() throws IOException {
- //获取trackerServer
- TrackerServer trackerServer=getTranckerServer();
- return new StorageClient(trackerServer,null);
- }
-
- /*
- * 生成Trancker服务器端
- * */
- //trackerServer可以通过trackerClient拿到
- private static TrackerServer getTranckerServer() throws IOException {
- TrackerClient trackerClient=new TrackerClient();
- return trackerClient.getTrackerServer();
- }
- }
(3)FastDFS文件工具类

- package com.xxxx.fastdfsdemo.utils;
-
- import com.xxxx.fastdfsdemo.pojo.FastDFSFile;
- import org.csource.common.NameValuePair;
- import org.csource.fastdfs.*;
-
- import org.slf4j.LoggerFactory;
-
- import org.slf4j.Logger;
- import org.springframework.core.io.ClassPathResource;
-
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.io.InputStream;
-
- public class FastDFSClient {
-
- //准备logger日志
- private static Logger logger= LoggerFactory.getLogger(FastDFSClient.class);
-
- //ClientGlobal.init会读取配置文件 并初始化对应的属性
- static {
- try {
- String filePath=new ClassPathResource("fast_client.conf").getFile().getAbsolutePath();
- ClientGlobal.init(filePath);
- } catch (Exception e) {
- logger.error("FastDFS初始化失败!",e.getMessage());
- }
- }
-
- //上传文件
- public static String [] upload(FastDFSFile file){
- logger.info("File Name:"+file.getName()+",File length:"+file.getContent().length);
-
- NameValuePair[] meta_list=new NameValuePair[1];
- meta_list[0]=new NameValuePair("author",file.getAuthor());
-
- long startTime=System.currentTimeMillis();//现在的时间
- String[]uploadResults=null;
- StorageClient storageClient=null;
- try {
- //获取storage客户端
- storageClient=getStorageClient();
- //上传
- uploadResults=storageClient.upload_file(file.getContent(),file.getExt(),meta_list);
-
- } catch (Exception e) {
- logger.error("上传失败!,File Name:"+file.getName(),e);
- }
- logger.info("上传时间:"+(System.currentTimeMillis()-startTime)+"ms");
- if (uploadResults==null && storageClient!=null){
- logger.error("上传失败:"+storageClient.getErrorCode());
- }
- //上传成功返回groupName
- logger.info("上传传文件成功!!!" + "group_name:" + uploadResults[0] + ", remoteFileName:" + " " + uploadResults[1]);
- return uploadResults;
- }
-
- //下载文件
- public static InputStream downFile(String groupName, String remoteFileName){
- try {
- StorageClient storageClient = getStorageClient();//客户端
- byte[] bytes = storageClient.download_file(groupName, remoteFileName);//下载
- InputStream inputStream = new ByteArrayInputStream(bytes);//将数组转换为流
- return inputStream;
- }catch (Exception e) {
- logger.error("文件下载失败!!!", e);
- }
- return null;
- }
-
- //删除文件
- public static void deleteFile(String groupName,String remoteFileName) throws Exception {
- StorageClient storageClient = null;
- try{
- storageClient=getStorageClient();
- int i = storageClient.delete_file(groupName, remoteFileName);
- logger.info("文件删除成功" + i);
-
- }catch (Exception e){
- logger.info("文件删除失败" + e.getMessage());
- }
- }
-
-
- //获取文件响应的信息
- public static FileInfo getFileInfo(String groupName, String remoteFileName){
- try {
- StorageClient storageClient = getStorageClient();//客户端
- return storageClient.get_file_info(groupName,remoteFileName);
- }catch (Exception e) {
- logger.error("文件获取失败!!", e);
- }
- return null;
- }
-
-
-
- /*
- * 获取文件路径:先获取IP地址+端口
- * */
- public static String getTrackerUrl() throws Exception {
- TrackerClient trackerClient=new TrackerClient();
- TrackerServer trackerServer=trackerClient.getTrackerServer();
- StorageServer storageServer=trackerClient.getStoreStorage(trackerServer);
- return "http://"+getTranckerServer().getInetSocketAddress().getHostString()+":8888/";
- }
-
- /*
- *
- * 生成Storage客户端
- * */
- private static StorageClient getStorageClient() throws IOException {
- //获取trackerServer
- TrackerServer trackerServer=getTranckerServer();
- return new StorageClient(trackerServer,null);
- }
-
- /*
- * 生成Trancker服务器端
- * */
- //trackerServer可以通过trackerClient拿到
- private static TrackerServer getTranckerServer() throws IOException {
- TrackerClient trackerClient=new TrackerClient();
- return trackerClient.getTrackerServer();
- }
- }
(4)文件上传
编写控制类:FileController
- package com.xxxx.fastdfsdemo.controller;
-
- import com.xxxx.fastdfsdemo.pojo.FastDFSFile;
- import com.xxxx.fastdfsdemo.utils.FastDFSClient;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.multipart.MultipartFile;
- import org.springframework.web.servlet.mvc.support.RedirectAttributes;
-
- import java.io.IOException;
- import java.io.InputStream;
-
- @Controller
- public class FileController {
- //准备logger日志
- private static Logger logger= LoggerFactory.getLogger(FastDFSClient.class);
-
- //上传文件
- @PostMapping("upload")
- public String FileUpLoad(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes){
- if (file.isEmpty()){
- redirectAttributes.addFlashAttribute("message","请选择一个文件上传");
- return "redirect:/uploadStatus";
- }
- try {
- //上传文件拿到返回的文件路径
- String path=saveFile(file);
- redirectAttributes.addFlashAttribute("message","上传成功"+file.getOriginalFilename());
- redirectAttributes.addFlashAttribute("path","路径:"+path);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "redirect:/uploadStatus";
- }
-
- //页面跳转
- @GetMapping("/uploadStatus")
- public String uploadStatus(){
- return "uploadStatus";
- }
- //页面跳转
- @GetMapping("/")
- public String upload(){
- return "upload";
- }
-
-
- public String saveFile(MultipartFile multipartFile) throws Exception {
- //上传之后返回的数组
- String [] fileAbsolutePath={};
- String fileName=multipartFile.getOriginalFilename();
- String ext = fileName.substring(fileName.lastIndexOf(".") + 1);//后缀
- byte[] file_buff=null;
- InputStream inputStream=multipartFile.getInputStream();
- if (inputStream!=null){
- int len1=inputStream.available();
- file_buff=new byte[len1];
- inputStream.read(file_buff);
- }
- inputStream.close();
- FastDFSFile file=new FastDFSFile(fileName,file_buff,ext);
- fileAbsolutePath= FastDFSClient.upload(file);
- if (fileAbsolutePath==null){
- logger.error("上传失败");
- }
- //返回上传后的完整路径
- String path=FastDFSClient.getTrackerUrl()+fileAbsolutePath[0]+"/"+fileAbsolutePath[1];
- return path;
- }
- }
upload.html:
- <!DOCTYPE html>
- <html >
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>Spring Boot file upload example</h1>
- <form method="POST" action="/upload" enctype="multipart/form-data">
- <input type="file" name="file"/><br><br>
- <input type="submit" value="Submit"/>
- </form>
-
- </body>
- </html>
uploadStatus.html:
- <!DOCTYPE html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
-
- <body>
- <h1>Spring Boot-Upload Status</h1>
-
- <div th:if="${message}">
- <h2 th:text="${message}"/>
- </div>
-
-
- <div th:if="${path}">
- <h2 th:text="${path}"/>
- </div>
- </body>
- </html>
运行主启动类
在浏览器输入:

点击选择文件:

storage里面保存的图片:

点击提交:

发现里面多了图片:
通过返回的路径通过Nginx可以在浏览器直接访问:
