整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Java 實現 FastDFS 實現文件的上傳、下載

          Java 實現 FastDFS 實現文件的上傳、下載、刪除

          一個成功人士的背后,必定曾經做出過勇敢而又孤獨的決定。

          放棄不難,但堅持很酷~

          最近在項目上完成了附件上傳和下載功能,是用的 fastdfs 來實現的。好記性不如爛筆頭,今天把關鍵代碼記錄下來,方便以后復用。

          一、Base64 轉 圖片url

          1)在 pom.xml 中添加依賴:

          <!--fastdfs-->
          <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-fastdfs</artifactId>
          <version>1.0-SNAPSHOT</version>
          </dependency>

          2)在 application.yml 中添加 fastdfs 相關配置:

          fdfsIp: http://fastdfs:8880/

          fastdfs:
          connecttimeout-in-seconds: 5
          network-timeout-in-seconds: 10
          charset: UTF-8
          # token 防盜鏈功能
          http-anti-steal-token: false
          # 密鑰
          http-secret-key: FastDFS1234567890
          # TrackerServer port
          http-tracker-http-port: 8888
          # 測試環境
          tracker-server-list:
          - fastdfs:22122

          示例代碼:

          上述方法就是將圖片的 base64 碼進行轉換并上傳到了 fastdfs 上。以下是可復制粘貼的源碼:

          import org.springframework.fasfdfs.exception.FdfsException;
          import org.springframework.fasfdfs.server.FastDFSClient;

          @Slf4j
          @Service
          @RequiredArgsConstructor
          public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

          @Value("${fdfsIp}")
          private String fdfsIp;

          @Autowired
          private FastDFSClient fastDFSClient;

          /**
          * 保存用戶信息
          *
          * @param userDto DTO 對象
          * @return success/fail
          */
          @Override
          @Transactional(rollbackFor=Exception.class)
          public Boolean saveUser(UserDTO userDto) {

          // 圖片base64轉換為圖片url
          String imgBase64=userDto.getAvatar;
          if (!StrUtil.isBlank(imgBase64)) {
          String imageUri=;
          try {
          imageUri=fdfsIp + fastDFSClient.uploadFileWithBase64(imgBase64, ".jpg");
          } catch (FdfsException e) {
          log.error("圖片上傳fastdfs異常", e);
          }
          if (StrUtil.isBlank(imageUri)) {
          log.info("圖片轉換失敗!");
          return false;
          }
          userDto.setAvatar(imageUri);
          }

          // ...
          }
          }

          二、文件(word、pdf)上傳到 fastdfs

          關于像 word、pdf 這樣的文件上傳到 fastdfs,我是通過 fastdfs-client-java 這個 jar 包來實現:

          1)在 pom.xml 文件中添加依賴:

          <dependency>
          <groupId>org.csource</groupId>
          <artifactId>fastdfs-client-java</artifactId>
          <version>1.27-SNAPSHOT</version>
          </dependency>

          2)添加 fastdfs_client.conf 文件

          #jar中使用時需要將此文件名修改為fastdfs_client.conf 。
          #也可以在jar被調用方resource下加入fastdfs_client.conf 內容如下
          connect_timeout=60
          network_timeout=120
          charset=UTF-8
          http.tracker_http_port=8888
          http.anti_steal_token=no
          http.secret_key=FastDFS1234567890

          tracker_server=fastdfs:22122

          3)相關代碼實現

          fastdfs 文件屬性相關:

          @Data
          public class FastDFSFile implements Serializable {

          private static final long serialVersionUID=2637755431406080379L;

          /**
          * 文件二進制
          */
          private byte content;

          /**
          * 文件名稱
          */
          private String name;

          /**
          * 文件長度
          */
          private Long size;

          public FastDFSFile(byte[] content, String name, Long size){
          this.content=content;
          this.name=name;
          this.size=size;
          }
          }

          fastdfs 工具類相關(包含初始化 fatdfs 連接,上傳、下載、刪除文件):

          import lombok.extern.slf4j.Slf4j;
          import org.apache.commons.io.FilenameUtils;
          import org.csource.common.MyException;
          import org.csource.common.NameValuePair;
          import org.csource.fastdfs.ClientGlobal;
          import org.csource.fastdfs.StorageClient1;
          import org.csource.fastdfs.TrackerClient;
          import org.csource.fastdfs.TrackerServer;
          import org.springframework.core.io.ClassPathResource;
          import org.springframework.http.HttpHeaders;
          import org.springframework.http.HttpStatus;
          import org.springframework.http.MediaType;
          import org.springframework.http.ResponseEntity;

          import java.io.IOException;
          import java.io.Serializable;

          /**
          * @author liuyzh
          * @description fastdfs上傳文件,參考鏈接:https://blog.wuwii.com/fsds-java.html
          * @date 2020-03-03
          */
          @Slf4j
          public class FastDFSUtils implements Serializable {

          private static final long serialVersionUID=-4462272673174266738L;
          private static TrackerClient trackerClient;
          private static TrackerServer trackerServer;
          private static StorageClient1 storageClient1;

          static {
          try {
          //clientGloble讀配置文件
          ClientGlobal.init("fastdfs_client.conf");
          //trackerclient
          trackerClient=new TrackerClient;
          trackerServer=trackerClient.getConnection;
          //storageclient
          storageClient1=new StorageClient1(trackerServer, );
          } catch (Exception e) {
          e.printStackTrace;
          }
          }

          /**
          * fastDFS文件上傳
          *
          * @param file 上傳的文件 FastDFSFile
          * @return String 返回文件的絕對路徑
          */
          public static String uploadFile(FastDFSFile file) {
          String path=;
          try {
          //文件擴展名
          String ext=FilenameUtils.getExtension(file.getName);
          //mata list是表文件的描述
          NameValuePair mata_list=new NameValuePair[3];
          mata_list[0]=new NameValuePair("fileName", file.getName);
          mata_list[1]=new NameValuePair("fileExt", ext);
          mata_list[2]=new NameValuePair("fileSize", String.valueOf(file.getSize));
          path=storageClient1.upload_file1(file.getContent, ext, mata_list);
          } catch (Exception e) {
          e.printStackTrace;
          }
          return path;
          }

          /**
          * fastDFS文件下載
          *
          * @param groupName 組名
          * @param remoteFileName 文件名
          * @param specFileName 真實文件名
          * @return ResponseEntity<byte >
          */
          public static ResponseEntity<byte> downloadFile(String groupName, String remoteFileName, String specFileName) {
          byte content=;
          HttpHeaders headers=new HttpHeaders;
          try {
          content=storageClient1.download_file(groupName, remoteFileName);
          headers.setContentDispositionFormData("attachment", new String(specFileName.getBytes("UTF-8"), "iso-8859-1"));
          headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
          } catch (Exception e) {
          e.printStackTrace;
          }
          return new ResponseEntity<byte>(content, headers, HttpStatus.CREATED);
          }

          /**
          * 刪除fastdfs文件
          * @param storagePath 文件的全部路徑 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
          * @return -1失敗,0成功
          * @throws IOException
          * @throws Exception
          */
          public static Boolean deleteFile(String storagePath) {
          int result=-1;
          try {
          result=storageClient1.delete_file1(storagePath);
          } catch (IOException | MyException e) {
          log.error("fastdfs刪除文件異常:", e);
          }
          if (result==-1) {
          return false;
          } else {
          return true;
          }
          }

          /**
          * 根據fastDFS返回的path得到文件的組名
          * @param path fastDFS返回的path
          * @return
          */
          public static String getGroupFormFilePath(String path){
          return path.split("/")[0];
          }

          /**
          * 根據fastDFS返回的path得到文件名
          * @param path fastDFS返回的path
          * @return
          */
          public static String getFileNameFormFilePath(String path) {
          return path.substring(path.indexOf("/")+1);
          }
          }

          上傳代碼示例:

          @Override
          @SneakyThrows
          public R uploadFile(MultipartFile file) {

          JSONObject jsonObject=new JSONObject;
          try {
          Long fileSize=file.getSize;
          // 檢查文件大小,不能超過5M
          if (fileSize >=5 * 1024 * 1024) {
          return R.failed("附件大小不允許超過5M");
          }
          String attachmentName=file.getOriginalFilename;
          FastDFSFile fastDFSFile=new FastDFSFile(file.getBytes, file.getOriginalFilename, file.getSize);
          String attachmentPath=FastDFSUtils.uploadFile(fastDFSFile);

          jsonObject.put("attachmentPath", attachmentPath);
          jsonObject.put("attachmentName", attachmentName);
          jsonObject.put("attachmentSize", OtherUtil.getFileSizeUnit(fileSize));
          return R.ok(jsonObject);
          } catch (IOException e) {
          log.info("上傳附件異常:", e);
          }
          return R.failed("附件上傳異常");
          }

          下載代碼示例(兩種):

          • 方式一:

          /**
          * 案件所屬附件下載
          * 接口 demo:http://192.168.166.189:7700/case/download?path=group1/M00/03/CF/wKinzF5d-EOAWPuEAAGjUNtaNqM02.docx
          *
          * @param path fastdfs返回的路徑
          * @return
          */
          @RequestMapping(value="/download")
          public ResponseEntity<byte> download(String path) {

          // 根據附件url獲取附件名稱
          AttachmentInfo attachmentInfo=attachmentInfoService.getAttachmentInfoByUrl(path);
          // 下載后的文件名稱
          String specFileName=attachmentInfo.getFileName;

          String filename=FastDFSUtils.getFileNameFormFilePath(path);
          String group=FastDFSUtils.getGroupFormFilePath(path);
          return FastDFSUtils.downloadFile(group, filename, specFileName);
          }

          這樣就可以實現瀏覽器下載了。不過還可以用 nginx 的方式來完成文件的下載:

          • 方式二:

          在 nginx 的 fastdfs 相關 server 配置里面添加:

          if ($arg_attname ~* .(doc|docx|txt|pdf|zip|rar|xls|xlsx|png|jpeg|jpg)$) {
          add_header Content-Disposition "attachment;filename=$arg_attname";
          }

          如下圖所示:

          重啟 nginx 后,這樣就可以通過訪問 url 來進行文件下載了。

          比如:http://fastdfs:8880/group1/M00/03/CF/wKinzF5d-EOAWPuEAAGjUNtaNqM02.docx?attname=測試.docx

          刪除代碼示例:

          /**
          * @param storagePath 文件的全部路徑 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
          * @return -1失敗,0成功
          * @throws IOException
          * @throws Exception
          */
          public static Boolean deleteFile(String storagePath) {
          int result=-1;
          try {
          result=storageClient1.delete_file1(storagePath);
          } catch (IOException | MyException e) {
          log.error("fastdfs刪除文件異常:", e);
          }
          if (result==-1) {
          return false;
          } else {
          return true;
          }
          }

          三、小結

          關于 fastdfs 的文件上傳、下載、刪除的示例代碼上面都已經介紹清楚了,如果有小伙伴遇到了 fastdfs jar 包的依賴問題,也不要慌,我已經踩過坑了,出坑記錄:實操:Could not autowire No beans of 'FastDFS Client' type found 的解決方法 ,可以看這篇。

          點關注,不迷路

          好了各位,以上就是這篇文章的全部內容了,能看到這里的人呀,都是人才

          白嫖不好,創作不易。也感謝各位的支持和認可,給予我最大的創作動力吧,我們下篇文章見!

          如果本篇博客有任何錯誤,請批評指教,不勝感激 !

          ? Ambari 2.7.3.0 安裝部署 hadoop 3.1.0.0 集群視頻完整版

          ? 【實戰】使用 Kettle 工具將 mysql 數據增量導入到 MongoDB 中

          ? 都快2020年了,ambari自定義服務集成,你還沒掌握嗎?文末有福利

          ? HBase原理(一):架構理解

          ? HBase二次開發之搭建HBase調試環境,如何遠程debug HBase源代碼

          ? Kafka消費者 之 指定位移消費

          ? Kylin配置Spark并構建Cube(修訂版)

          ? 看完您如果還不明白 Kerberos 原理,算我輸!

          歡迎大家留言討論

          朕已閱

          Flask中,文件上傳通常涉及創建一個表單,用戶可以通過這個表單上傳文件。然后,后端代碼會處理接收到的文件。以下是實現文件上傳功能的步驟:

          創建HTML表單 - 使用標簽創建一個表單,設置enctype="multipart/form-data"屬性以支持文件上傳。

          File Upload


          創建Flask路由 - 定義一個處理文件上傳的路由。

          from flask import Flask, request, redirect, url_for, send_from_directory

          app=Flask(__name__)

          @app.route('/upload', methods=['GET', 'POST'])

          def upload_file():

          if request.method=='POST':

          file=request.files['file']

          if file and '.jpg' in file.filename:

          # 保存上傳的文件

          filename='uploads/' + file.filename

          file.save(filename)

          # 重定向到文件上傳后的頁面

          return redirect(url_for('success', filename=filename))

          return '''

          '''

          @app.route('/success/')

          def success(filename):

          # 返回上傳成功的頁面,顯示文件名和下載鏈接

          return f'File uploaded successfully: Download {filename}'

          @app.route('/download_file/')

          def download_file(filename):

          return send_from_directory(app.root_path + '/uploads', filename)

          if __name__=="__main__":

          app.run()


          處理上傳的文件 - 在Flask視圖函數中,通過request.files字典訪問上傳的文件。

          保存上傳的文件 - 將上傳的文件保存到服務器的指定目錄中。

          重定向或返回上傳結果 - 一旦文件被保存,可以重定向用戶到一個新頁面,顯示上傳成功的信息,或者直接在原頁面顯示上傳結果。

          提供下載鏈接 - 為了讓用戶能夠下載上傳的文件,可以創建一個路由來提供文件的下載服務。在示例中,使用了send_from_directory函數來實現。

          確保服務器上的目標目錄對于Web服務是可寫的,并且處理上傳的代碼要考慮安全性,比如檢查文件類型、大小,防止上傳惡意文件。此外,對于生產環境,應該使用更高級的文件上傳處理方案,比如文件存儲在外部服務上,以及設置適當的權限和安全措施。

          于網頁的上傳組件比較常用的webuploader ,jQuery File Upload等,切圖網在做前端項目切圖的時候,不乏有一些后臺或者前臺需要用到上傳組件的,雖然做前端開發不需要實現上傳到服務器的功能,但是前臺的功能還是需要做出來的,特別簡單的可以jquery手寫 基本能夠用了,而復雜的時候就需要上一些插件,而選擇插件的時候也比較講究,插件盡可能要靈活 參數夠多 或者一些擴展方法多, 可以滿足不同的復雜情況,而jQuery File Upload則是相比之下比較不錯的一款。

          jQuery File Upload 是一個Jquery文件上傳組件,支持多文件上傳、取消、刪除,上傳前縮略圖預覽、列表顯示圖片大小,支持上傳進度條顯示;支持各種動態語言開發的服務器端。

          官網鏈接:https://github.com/blueimp/jQuery-File-Upload/wiki

          特點:拖放支持;上傳進度條;圖像預覽;可定制和可擴展的;兼容任何服務器端應用平臺(PHP, Python, Ruby on Rails, Java, Node.js, Go etc.)。

          演示地址 https://blueimp.github.io/jQuery-File-Upload/

          使用方法:

          1. 需要加載的js文件:

          jquey-1.8.3.min.js

          jquery-ui-widget.js

          jquery.iframe-transport.js

          jquery.fileupload.js

          2. html代碼:

          1. <input id=“fileupload” type=“file” name=“files[]” data-url=“server/php/” multiple>

          3. js代碼:

          1. $(function () {
          2. $(‘#fileupload’).fileupload({
          3. dataType: ‘json’,
          4. done: function (e, data) {
          5. $.each(data.result.files, function (index, file) {
          6. $(‘<p/>’).text(file.name).appendTo(document.body);
          7. });
          8. }
          9. });
          10. });

          3.1 顯示上傳進度條:

          1.  $(‘#fileupload’).fileupload({
          2.   progressall: function (e, data) {
          3.   var progress=parseInt(data.loaded / data.total * 100, 10);
          4.   $(‘#progress .bar’).css(
          5.   ‘width’,
          6.   progress + ‘%’
          7.   );
          8.   }
          9.   });

          3.2 需要一個<div>容器用來顯示進:

          1.  <div id=“progress”>
          2.   <div class=“bar” style=“width: 0%;“></div>
          3.   </div>

          4. API

          4.1 Initialization:

          在上傳按鈕上調用fileupload()方法;

          示例:

          $('#fileupload').fileupload();

          4.2 Options :

          1: url:請求發送的目標url

          Type: string

          Example: ‘/path/to/upload/handler.json’

          2.Type: 文件上傳HTTP請求方式,可以選擇“POST”,“PUT”或者”PATCH”,

          默認”POST”

          Type: string

          Example: ‘PUT’

          3. dataType:希望從服務器返回的數據類型,默認”json”

          Type: string

          Example: ‘json’

          4. autoUpload:默認情況下,只要用戶點擊了開始按鈕被添加至組件的文件會立即上傳。將autoUpload值設為true可以自動上傳。

          Type: boolean

          Default: true

          5. acceptFileTypes:允許上傳的的文件類型

          Example: /(\.|\/)(gif|jpe?g|png|xlsx)$/i

          6. maxFileSize: 最大上傳文件大小

          Example: 999000 (999KB) //單位:B

          7. minFileSize:最小上傳文件大小

          Example: 100000 (100KB) //單位:B

          8.previewMaxWidth : 圖片預覽區域最大寬度

          Example: 100 //單位:px

          4.3 Callback Options:

          使用方法一:函數屬性

          實例:

          1. $(‘#fileupload’).fileupload({
          2.   drop: function (e, data) {
          3.   $.each(data.files, function (index, file) {
          4.   alert(‘Dropped file: ‘ + file.name);
          5.   });
          6.   },
          7.   change: function (e, data) {
          8.   $.each(data.files, function (index, file) {
          9.   alert(‘Selected file: ‘ + file.name);
          10.   });
          11.   }
          12.   });

          使用方法二:綁定事件監聽函數

          實例:

          1. $(‘#fileupload’)
          2.     .bind(‘fileuploaddrop’, function (e, data) {/* … */})
          3.     .bind(‘fileuploadchange’, function (e, data) {/* … */});

          每個事件名稱都添加前綴:”fileupload”;

          注意推薦使用第二種方法。

          常用的回調函數:

          1. add: 當文件被添加到上傳組件時被觸發

          1. $(‘#fileupload’).bind(‘fileuploadadd’, function (e, data) {/* … */});

          或者$(‘#fileupload’).on(‘fileuploadadd’, function (e, data) {/* … */});

          2. processalways: 當一個單獨的文件處理隊列結束(完成或失敗時)觸發

          3. progressall: 全局上傳處理事件的回調函數

          Example:

          1. $(‘#fileupload’).on(‘fileuploadprogressall’, function (e, data) { //進度條顯示
          2. var progress=parseInt(data.loaded / data.total * 100, 10);
          3. $(‘#progress .progress-bar’).css(
          4. ‘width’,
          5. progress + ‘%’
          6. );
          7. });

          4. fail : 上傳請求失敗時觸發的回調函數,如果服務器返回一個帶有error屬性的json響應這個函數將不會被觸發。

          5. done : 上傳請求成功時觸發的回調函數,如果服務器返回一個帶有error屬性的json響應這個函數也會被觸發。

          6. always : 上傳請求結束時(成功,錯誤或者中止)都會被觸發。


          主站蜘蛛池模板: AV无码精品一区二区三区| 国产精品亚洲高清一区二区| 国产一区二区三区免费看| 在线播放一区二区| 亚洲色精品三区二区一区| 国产中文字幕一区| 久久99国产一区二区三区| 2014AV天堂无码一区| 亚洲视频在线一区二区三区| 亚洲中文字幕久久久一区| 一级特黄性色生活片一区二区| 青娱乐国产官网极品一区| 高清一区二区三区| 精品久久一区二区| 在线观看日本亚洲一区| 一区二区三区四区在线视频| 秋霞午夜一区二区| 成人欧美一区二区三区在线视频| 色一乱一伦一区一直爽| 人妻无码久久一区二区三区免费 | 免费播放一区二区三区| 成人精品一区二区三区电影| 日本精品高清一区二区| 黑巨人与欧美精品一区| 国产乱码一区二区三区爽爽爽| 亚洲熟女乱色一区二区三区| 国产精品被窝福利一区| 好吊妞视频一区二区| 久久久无码精品国产一区| 国产伦精品一区二区三区在线观看| 国产伦理一区二区| 一区二区三区免费高清视频| 亚洲av无码一区二区三区在线播放 | 日韩精品无码一区二区三区四区| 激情内射亚洲一区二区三区爱妻| 日本一区二区三区在线视频 | 人妻少妇精品一区二区三区| 婷婷亚洲综合一区二区| 91一区二区三区四区五区| 中文字幕一区二区三区乱码| 在线观看国产一区亚洲bd|