目录:
(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环境初始化
创建springboot项目:
删除没用的文件:
在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可以在浏览器直接访问: