• eyb:Java代码通过FastDFS实现文件上传



    目录:

    (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:配置文件 

    1. #连接超时
    2. connect_timeout = 2
    3. #网络超时
    4. network_timeout = 30
    5. #编码格式
    6. charset = UTF-8
    7. #tracker端口号
    8. http.tracker_http_port = 8080
    9. #防盗链功能
    10. http.anti_steal_token = no
    11. #秘钥
    12. http.secret_key = FastDFS1234567890
    13. #tracker ip:端口号
    14. tracker_server = 192.168.23.129:22122
    15. #连接池配置
    16. connection_pool.enabled = true
    17. connection_pool.max_count_per_entry = 500
    18. connection_pool.max_idle_time = 3600
    19. connection_pool.max_wait_time_in_ms = 1000

     准备一个FastDFS的对象:

    FastDFSFile:

    1. package com.xxxx.fastdfsdemo.pojo;
    2. public class FastDFSFile {
    3. private String name;
    4. private byte[] content;
    5. private String ext;
    6. private String md5;
    7. private String author;
    8. private String height;
    9. public FastDFSFile() {
    10. }
    11. public FastDFSFile(String name, byte[] content, String ext) {
    12. this.name = name;
    13. this.content = content;
    14. this.ext = ext;
    15. }
    16. public FastDFSFile(String name, byte[] content, String ext, String md5, String author, String height) {
    17. this.name = name;
    18. this.content = content;
    19. this.ext = ext;
    20. this.md5 = md5;
    21. this.author = author;
    22. this.height = height;
    23. }
    24. public String getName() {
    25. return name;
    26. }
    27. public void setName(String name) {
    28. this.name = name;
    29. }
    30. public byte[] getContent() {
    31. return content;
    32. }
    33. public void setContent(byte[] content) {
    34. this.content = content;
    35. }
    36. public String getExt() {
    37. return ext;
    38. }
    39. public void setExt(String ext) {
    40. this.ext = ext;
    41. }
    42. public String getMd5() {
    43. return md5;
    44. }
    45. public void setMd5(String md5) {
    46. this.md5 = md5;
    47. }
    48. public String getAuthor() {
    49. return author;
    50. }
    51. public void setAuthor(String author) {
    52. this.author = author;
    53. }
    54. public String getHeight() {
    55. return height;
    56. }
    57. public void setHeight(String height) {
    58. this.height = height;
    59. }
    60. }

     不在去写controller-service了,直接写一个上传文件的工具类,然后再service里面直接调用工具类

    FastDFSClient: 

    1. package com.xxxx.fastdfsdemo.utils;
    2. import org.csource.fastdfs.ClientGlobal;
    3. import org.csource.fastdfs.StorageClient;
    4. import org.csource.fastdfs.TrackerClient;
    5. import org.csource.fastdfs.TrackerServer;
    6. import org.slf4j.LoggerFactory;
    7. import org.slf4j.Logger;
    8. import org.springframework.core.io.ClassPathResource;
    9. import java.io.IOException;
    10. public class FastDFSClient {
    11. //准备logger日志
    12. private static Logger logger= LoggerFactory.getLogger(FastDFSClient.class);
    13. //ClientGlobal.init会读取配置文件 并初始化对应的属性
    14. static {
    15. try {
    16. String filePath=new ClassPathResource("fast_client.conf").getFile().getAbsolutePath();
    17. ClientGlobal.init(filePath);
    18. } catch (Exception e) {
    19. logger.error("FastDFS初始化失败!",e.getMessage());
    20. }
    21. }
    22. /*
    23. *
    24. * 生成Storage客户端
    25. * */
    26. private static StorageClient getStorageClient() throws IOException {
    27. //获取trackerServer
    28. TrackerServer trackerServer=getTranckerServer();
    29. return new StorageClient(trackerServer,null);
    30. }
    31. /*
    32. * 生成Trancker服务器端
    33. * */
    34. //trackerServer可以通过trackerClient拿到
    35. private static TrackerServer getTranckerServer() throws IOException {
    36. TrackerClient trackerClient=new TrackerClient();
    37. return trackerClient.getTrackerServer();
    38. }
    39. }

    (3)FastDFS文件工具类 

     

    1. package com.xxxx.fastdfsdemo.utils;
    2. import com.xxxx.fastdfsdemo.pojo.FastDFSFile;
    3. import org.csource.common.NameValuePair;
    4. import org.csource.fastdfs.*;
    5. import org.slf4j.LoggerFactory;
    6. import org.slf4j.Logger;
    7. import org.springframework.core.io.ClassPathResource;
    8. import java.io.ByteArrayInputStream;
    9. import java.io.IOException;
    10. import java.io.InputStream;
    11. public class FastDFSClient {
    12. //准备logger日志
    13. private static Logger logger= LoggerFactory.getLogger(FastDFSClient.class);
    14. //ClientGlobal.init会读取配置文件 并初始化对应的属性
    15. static {
    16. try {
    17. String filePath=new ClassPathResource("fast_client.conf").getFile().getAbsolutePath();
    18. ClientGlobal.init(filePath);
    19. } catch (Exception e) {
    20. logger.error("FastDFS初始化失败!",e.getMessage());
    21. }
    22. }
    23. //上传文件
    24. public static String [] upload(FastDFSFile file){
    25. logger.info("File Name:"+file.getName()+",File length:"+file.getContent().length);
    26. NameValuePair[] meta_list=new NameValuePair[1];
    27. meta_list[0]=new NameValuePair("author",file.getAuthor());
    28. long startTime=System.currentTimeMillis();//现在的时间
    29. String[]uploadResults=null;
    30. StorageClient storageClient=null;
    31. try {
    32. //获取storage客户端
    33. storageClient=getStorageClient();
    34. //上传
    35. uploadResults=storageClient.upload_file(file.getContent(),file.getExt(),meta_list);
    36. } catch (Exception e) {
    37. logger.error("上传失败!,File Name:"+file.getName(),e);
    38. }
    39. logger.info("上传时间:"+(System.currentTimeMillis()-startTime)+"ms");
    40. if (uploadResults==null && storageClient!=null){
    41. logger.error("上传失败:"+storageClient.getErrorCode());
    42. }
    43. //上传成功返回groupName
    44. logger.info("上传传文件成功!!!" + "group_name:" + uploadResults[0] + ", remoteFileName:" + " " + uploadResults[1]);
    45. return uploadResults;
    46. }
    47. //下载文件
    48. public static InputStream downFile(String groupName, String remoteFileName){
    49. try {
    50. StorageClient storageClient = getStorageClient();//客户端
    51. byte[] bytes = storageClient.download_file(groupName, remoteFileName);//下载
    52. InputStream inputStream = new ByteArrayInputStream(bytes);//将数组转换为流
    53. return inputStream;
    54. }catch (Exception e) {
    55. logger.error("文件下载失败!!!", e);
    56. }
    57. return null;
    58. }
    59. //删除文件
    60. public static void deleteFile(String groupName,String remoteFileName) throws Exception {
    61. StorageClient storageClient = null;
    62. try{
    63. storageClient=getStorageClient();
    64. int i = storageClient.delete_file(groupName, remoteFileName);
    65. logger.info("文件删除成功" + i);
    66. }catch (Exception e){
    67. logger.info("文件删除失败" + e.getMessage());
    68. }
    69. }
    70. //获取文件响应的信息
    71. public static FileInfo getFileInfo(String groupName, String remoteFileName){
    72. try {
    73. StorageClient storageClient = getStorageClient();//客户端
    74. return storageClient.get_file_info(groupName,remoteFileName);
    75. }catch (Exception e) {
    76. logger.error("文件获取失败!!", e);
    77. }
    78. return null;
    79. }
    80. /*
    81. * 获取文件路径:先获取IP地址+端口
    82. * */
    83. public static String getTrackerUrl() throws Exception {
    84. TrackerClient trackerClient=new TrackerClient();
    85. TrackerServer trackerServer=trackerClient.getTrackerServer();
    86. StorageServer storageServer=trackerClient.getStoreStorage(trackerServer);
    87. return "http://"+getTranckerServer().getInetSocketAddress().getHostString()+":8888/";
    88. }
    89. /*
    90. *
    91. * 生成Storage客户端
    92. * */
    93. private static StorageClient getStorageClient() throws IOException {
    94. //获取trackerServer
    95. TrackerServer trackerServer=getTranckerServer();
    96. return new StorageClient(trackerServer,null);
    97. }
    98. /*
    99. * 生成Trancker服务器端
    100. * */
    101. //trackerServer可以通过trackerClient拿到
    102. private static TrackerServer getTranckerServer() throws IOException {
    103. TrackerClient trackerClient=new TrackerClient();
    104. return trackerClient.getTrackerServer();
    105. }
    106. }

    (4)文件上传 

    编写控制类:FileController

    1. package com.xxxx.fastdfsdemo.controller;
    2. import com.xxxx.fastdfsdemo.pojo.FastDFSFile;
    3. import com.xxxx.fastdfsdemo.utils.FastDFSClient;
    4. import org.slf4j.Logger;
    5. import org.slf4j.LoggerFactory;
    6. import org.springframework.stereotype.Controller;
    7. import org.springframework.web.bind.annotation.GetMapping;
    8. import org.springframework.web.bind.annotation.PostMapping;
    9. import org.springframework.web.bind.annotation.RequestParam;
    10. import org.springframework.web.multipart.MultipartFile;
    11. import org.springframework.web.servlet.mvc.support.RedirectAttributes;
    12. import java.io.IOException;
    13. import java.io.InputStream;
    14. @Controller
    15. public class FileController {
    16. //准备logger日志
    17. private static Logger logger= LoggerFactory.getLogger(FastDFSClient.class);
    18. //上传文件
    19. @PostMapping("upload")
    20. public String FileUpLoad(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes){
    21. if (file.isEmpty()){
    22. redirectAttributes.addFlashAttribute("message","请选择一个文件上传");
    23. return "redirect:/uploadStatus";
    24. }
    25. try {
    26. //上传文件拿到返回的文件路径
    27. String path=saveFile(file);
    28. redirectAttributes.addFlashAttribute("message","上传成功"+file.getOriginalFilename());
    29. redirectAttributes.addFlashAttribute("path","路径:"+path);
    30. } catch (Exception e) {
    31. e.printStackTrace();
    32. }
    33. return "redirect:/uploadStatus";
    34. }
    35. //页面跳转
    36. @GetMapping("/uploadStatus")
    37. public String uploadStatus(){
    38. return "uploadStatus";
    39. }
    40. //页面跳转
    41. @GetMapping("/")
    42. public String upload(){
    43. return "upload";
    44. }
    45. public String saveFile(MultipartFile multipartFile) throws Exception {
    46. //上传之后返回的数组
    47. String [] fileAbsolutePath={};
    48. String fileName=multipartFile.getOriginalFilename();
    49. String ext = fileName.substring(fileName.lastIndexOf(".") + 1);//后缀
    50. byte[] file_buff=null;
    51. InputStream inputStream=multipartFile.getInputStream();
    52. if (inputStream!=null){
    53. int len1=inputStream.available();
    54. file_buff=new byte[len1];
    55. inputStream.read(file_buff);
    56. }
    57. inputStream.close();
    58. FastDFSFile file=new FastDFSFile(fileName,file_buff,ext);
    59. fileAbsolutePath= FastDFSClient.upload(file);
    60. if (fileAbsolutePath==null){
    61. logger.error("上传失败");
    62. }
    63. //返回上传后的完整路径
    64. String path=FastDFSClient.getTrackerUrl()+fileAbsolutePath[0]+"/"+fileAbsolutePath[1];
    65. return path;
    66. }
    67. }

    upload.html:

    1. <!DOCTYPE html>
    2. <html >
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Title</title>
    6. </head>
    7. <body>
    8. <h1>Spring Boot file upload example</h1>
    9. <form method="POST" action="/upload" enctype="multipart/form-data">
    10. <input type="file" name="file"/><br><br>
    11. <input type="submit" value="Submit"/>
    12. </form>
    13. </body>
    14. </html>

    uploadStatus.html:

    1. <!DOCTYPE html>
    2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
    3. <body>
    4. <h1>Spring Boot-Upload Status</h1>
    5. <div th:if="${message}">
    6. <h2 th:text="${message}"/>
    7. </div>
    8. <div th:if="${path}">
    9. <h2 th:text="${path}"/>
    10. </div>
    11. </body>
    12. </html>

    运行主启动类

    在浏览器输入:

    点击选择文件: 

     

     

     storage里面保存的图片:

    点击提交:

    发现里面多了图片: 

     

     通过返回的路径通过Nginx可以在浏览器直接访问:

     

     

  • 相关阅读:
    项目上线就炸,这谁受得了
    IB学生喜欢申请哪些英国院校?
    【附源码】计算机毕业设计SSM时事新闻管理系统
    vue基础语法
    pyspark连接mysql数据库报错
    一个字符串模式匹配开源库
    基于java的在线答疑网站系统——计算机毕业设计
    OpenCV计算机视觉学习(15)——浅谈图像处理的饱和运算和取模运算
    2022-08-19 mysql/stonedb聚合aggregate多线程并行化-概要设计
    ts中关于path使用RouteLocationRaw报错
  • 原文地址:https://blog.csdn.net/dengfengling999/article/details/126444021