本文在上篇搭建了fastDFS服务的基础上,基于其javaClient,实现文件的上传、下载、删除和信息获取、展示等功能。
maven依赖引入
在常用的maven仓库中,搜索不到仓库信息,只能down源码后自己构建并导入:
先从官方库(https://gitee.com/fastdfs100/fastdfs-client-java)down源码
导入到idea后,执行mvn clean install将依赖安装到本地
在pom.xml正常引入如下依赖:
org.csource
fastdfs-client-java
1.29-SNAPSHOT
fdfs_client.properties配置
具体配置如下:
fastdfs.connect_timeout_in_seconds=5
fastdfs.network_timeout_in_seconds=30
fastdfs.charset=UTF-8
fastdfs.http_anti_steal_token=false
#http_secret_key等要与服务端配置保持一致
fastdfs.http_secret_key=goodFS
fastdfs.http_tracker_http_port=8080
fastdfs.tracker_servers=192.168.0.124:22122
fastdfs.connection_pool.enabled=true
fastdfs.connection_pool.max_count_per_entry=500
fastdfs.connection_pool.max_idle_time=3600
fastdfs.connection_pool.max_wait_time_in_ms=1000
服务端功能实现
首先,定义一个FastDfsFile类
@Data
@AllArgsConstructor
@Builder
public class FastDfsFile {
private String name;
private byte[] content;
/** 文件扩展名,不包含. */
private String extName;
}
对配置进行管理:
@Configuration
@Slf4j
public class FastDfsConfig {
public FastDfsConfig() {
// 进行属性初始化
try {
ClientGlobal.initByProperties("fdfs_client.properties");
} catch (IOException | MyException e) {
log.error("fdfs_client属性文件初始化出错", e);
}
}
@Bean
public StorageClient storageClient() throws IOException {
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getTrackerServer();
return new StorageClient(trackerServer, null);
}
}
编写文件上传下载客户端类:
@Component
@Slf4j
public class FastDfsClient {
@Autowired
private StorageClient storageClient;
public Optional upload(FastDfsFile file) {
log.info("start update {}", file.getName());
NameValuePair[] metaList = new NameValuePair[1];
metaList[0] = new NameValuePair("fileName", file.getName());
try {
return Optional.ofNullable(storageClient.upload_file(file.getContent(), file.getExtName(), metaList));
} catch (IOException | MyException e) {
log.error("上传文件出错", e);
return Optional.empty();
}
}
public Optional getFileInfo(String groupName, String remoteFileName) {
try {
return Optional.ofNullable(storageClient.get_file_info(groupName, remoteFileName));
} catch (IOException | MyException e) {
log.error("获取文件信息错误", e);
return Optional.empty();
}
}
public String getFileUrl(String groupName, String remoteFileName) {
Optional fileInfo = getFileInfo(groupName, remoteFileName);
if (fileInfo.isPresent()) {
String url = "http://" + fileInfo.get().getSourceIpAddr() + "/" + remoteFileName;
log.info("file url:{}", url);
return url;
} else {
return "";
}
}
public Optional download(String groupName, String remoteFileName) {
try {
return Optional.ofNullable(storageClient.download_file(groupName, remoteFileName));
} catch (IOException | MyException e) {
log.error("下载文件出错", e);
return Optional.empty();
}
}
语言
方法
8232
2010.02.13 20-32-46
public boolean deleteFile(String groupName, String remoteFileName) {
try {
return storageClient.delete_file(groupName, remoteFileName) == 0;
} catch (IOException | MyException e) {
log.error("删除文件出错", e);
return false;
}
}
}
编写控制器类,实现对请求的处理:
@Controller
@RequestMapping("/file")
@Slf4j
public class FileController {
@Autowired
private FastDfsClient fastDfsClient;
@GetMapping("/")
public String index() {
return "fileIndex";
}
@PostMapping("/upload")
public String fileUpload(@RequestParam("upFile") MultipartFile file, RedirectAttributes reAttrib) {
if (file.isEmpty()) {
reAttrib.addFlashAttribute("msg", "请上传一个文件");
return "redirect:/file/fileMsg";
}
String fileName = file.getOriginalFilename();
String extName = fileName.substring(fileName.lastIndexOf('.') + 1);
try {
byte[] content = file.getBytes();
//构建上传文件对象
FastDfsFile fastDfsFile = FastDfsFile.builder().content(content).extName(extName).name(fileName).build();
// 进行文件上传
Optional result = fastDfsClient.upload(fastDfsFile);
String msg = "";
String url = "";
if (result.isPresent()) {
String[] results = result.get();
msg = Arrays.toString(results);
log.info("上传返回结果:{}", msg);
log.info("文件详细信息:{}", fastDfsClient.getFileInfo(results[0], results[1]));
url = fastDfsClient.getFileUrl(results[0], results[1]);
}
reAttrib.addFlashAttribute("msg", msg);
reAttrib.addFlashAttribute("url", url);
return "redirect:/file/fileMsg";
} catch (IOException e) {
log.error("获取文件内容出错", e);
reAttrib.addFlashAttribute("msg", "获取文件内容出错");
return "redirect:/file/fileMsg";
}
}
@GetMapping("/fileMsg")
public String fileMsg() {
return "fileMsg";
}
}
前端功能实现
主要是基于 thymeleaf进行简单内容展示:
fileIndex.html文件:
请上传文件
fileMsg.html文件展示结果:
文件上传结果展示
功能测试
启动服务以后,可通过 http://localhost:8080/file/ 来访问首页
上传图片文件后即可进入详情页:
除了直接通过前端页面来测试之外,也可以通过test用例来验证结果:
@SpringBootTest
@Slf4j
public class FastDfsClientTest {
@Autowired
private FastDfsClient client;
@Test
void fullTest() throws IOException, InterruptedException {
//上传测试
Path path = Paths.get("D:\\test\\love.png");
byte[] content = Files.readAllBytes(path);
FastDfsFile dfsFile = FastDfsFile.builder().content(content).name("love.png").extName("png").build();
String[] result = client.upload(dfsFile).get();
log.info("uploaded result:{}", Arrays.toString(result));
String groupName = result[0];
String remoteFileName = result[1];
//获取文件信息测试
log.info("fileinfo:{}", client.getFileInfo(groupName, remoteFileName));
// 下载测试
Optional bytes = client.download(groupName, remoteFileName);
if (bytes.isPresent()) {
String outFileName = System.currentTimeMillis() + ".png";
Path outFile = Paths.get("D:\\test\\" + outFileName);
if (Files.notExists(outFile)) {
Files.createFile(outFile);
}
Files.write(outFile, bytes.get(), StandardOpenOption.WRITE);
}
// 删除测试
log.info("delete:{}", client.deleteFile(groupName, remoteFileName));
//注意删除后,还是可以通过getFileInfo获取到信息,只是无法再下载到,所以此处以download来验证删除结果
log.info("fileinfo:{}", client.download(groupName, remoteFileName).isPresent());
}
}