记录springboot+vue+fastdfs实现简易的文件(上传、下载、删除、预览)操作

前言说明:springboot + vue + FastDFS实现文件上传(支持预览)升级版

FASTDFS部分

FASTDFS安装过程:基于centos 7安装FastDFS文件服务器

SpringBoot部分

springboot源码实现

package com.core.doc.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.doc.entity.FileInfo;
import com.core.doc.mapper.FileInfoMapper;
import com.core.doc.response.Result;
import com.core.doc.until.FastUtils;
//import org.openimaj.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;


@RestController
@RequestMapping("/upload")
@CrossOrigin
public class UploadController {

    @Autowired
    FileInfoMapper fileInfoMapper;


    /**
    * 文件上传
    **/
    @PostMapping("/import")
    public String importData(MultipartFile file, HttpServletRequest req) throws IOException {

        System.out.println("file = " + file);
        String name = file.getOriginalFilename();
        String realPath = req.getSession().getServletContext().getRealPath("/");
        System.out.println("realPath = " + realPath);
        String fileId = FastUtils.upload(file);
//        String url = "http://xx.xx.x.xx/" + fileId;
        String url =  fileId;
        System.out.println(url);
        return url;
    }
    /**
    * 文件下载
    **/
    @GetMapping("/downloadFile")
    public void downloadFile(HttpServletResponse response,String  filePath) throws UnsupportedEncodingException {
//        String filePath = "group1/M00/00/00/wKg4CmP7OiaAUzIvAADA8Mf85m8974.pdf";
//        String fileName = "xxx.pdf";
//        File file = new File(filePath);
//        if(file.exists()) {
        if(filePath == null)return;
        QueryWrapper<FileInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("filePath",filePath);
        List<FileInfo> fileInfos = fileInfoMapper.selectList(wrapper);
        String filename = "未知文档.pdf";
        if(fileInfos != null && fileInfos.size() > 0 && fileInfos.get(0).getFilename() != null ){
            filename = fileInfos.get(0).getFilename() ;
            if(!fileInfos.get(0).getFilename().contains(".pdf")){
                filename = fileInfos.get(0).getFilename() +".pdf";
            }
        }

        response.setContentType("application/force-download;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Disposition", "attachment;fileName="  + new String(filename.getBytes("gb2312"), "ISO-8859-1"));


        byte[] bytes = FastUtils.testDownload(filePath);
        FileInputStream fis = null;
        System.out.println(filePath);


        OutputStream outputStream = null;
        int len = 0;
        try {
            outputStream = response.getOutputStream();
            System.out.println(bytes);
            if(bytes == null){
                return;
            }
            outputStream.write(bytes);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

	 /**
    * 文件删除
    **/
    @PostMapping("/del")
    @ResponseBody
    public Result delFile(@RequestParam String fileName) {
        
        int i = FastUtils.delFile(fileName);
        if(i != -1){
            return Result.ok().data("msg", "删除成功");
        } else {
            return Result.error().data("msg", "失败");
        }
    }


    @PostMapping("/downlaod")
    @ResponseBody
    public byte[] upload(HttpServletResponse response, @RequestParam String fileName) {

        byte[] bytes = FastUtils.testDownload(fileName);
        response.setContentType("application/octet-stream;charset=UTF-8");
// 设置返回的文件类型
        OutputStream toClient = null; // 得到向客户端输出二进制数据的对象
        try {

            response.setCharacterEncoding("UTF-8");
            //使用setHeader方法设置浏览器使用UTF-8进行解码
            response.setHeader("Content-Type", "text/html;charset=UTF-8");
            toClient = response.getOutputStream();

            toClient.write(bytes); // 输出数据
            toClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            return bytes;
        }
    }


  

    private void genCode(HttpServletResponse response, byte[] data) throws IOException {
        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=\"declare.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
//        IOUtils.write(data, (DataOutput) response.getOutputStream());
    }


}

FastUtils工具类

package com.core.doc.until;

import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.junit.Test;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件上传工具类
 */
public class FastUtils {

    private static StorageClient1 client1;

    static {
        try {
            ClientGlobal.initByProperties("fastdfs-client.properties");
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            client1 = new StorageClient1(trackerServer, null);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }

    }


    public static int delFile(String filename) {

        int count = 0;

        try {
            count = client1.delete_file1(filename);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }finally {
            return count;
        }

    }

    public static String upload(MultipartFile file) {
        String oldName = file.getOriginalFilename();

        try {
            return client1.upload_file1(file.getBytes(), oldName.substring(oldName.lastIndexOf(".") + 1), null);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static byte[] download(String filepath, HttpServletResponse response) throws IOException {
        byte[] bytes = null;
        try {
            //1.初始化fastdfs客户端配置文件
            ClientGlobal.initByProperties("fastdfs-client.properties");// 加载properties配置文件
            System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms");//输出properties中配置的参数,检测properties文件是否生效
            System.out.println("charset=" + ClientGlobal.g_charset);

            // 2.获取trackerServer
            TrackerClient tracker = new TrackerClient();// 创建tracker客户端对象
            TrackerServer trackerServer = tracker.getConnection();//获得tracker连接对象

            //3.获取storageClient(通过trackerServer 和 storageServer:null)
            StorageServer storageServer = null;
            StorageClient1 client = new StorageClient1(trackerServer, storageServer);//通过tracker服务器返回storage服务器对象(客户端)
            String name = "wKg4CmP7btCAZpAmAADA8Mf85m8679.pdf";
            //4.下载操作
            //方式一 文件id下载
            bytes = client.download_file1("group1/M00/00/00/wKg4CmP7btCAZpAmAADA8Mf85m8679.pdf");//记得要传文件id返回字节流
            File file=new File("D:\\KM\\"+name);// 给定文件路径 和 名称
            FileOutputStream fileOutputStream=new FileOutputStream(file);//窗机输出流
            fileOutputStream.write(bytes);//写入数据
            fileOutputStream.close();//关闭输出流

            //方式二 组名+文件路径
            byte[] bytes2 = client.download_file("group1","/M00/00/00/"+name);//记得修改
            File file2=new File("D:\\KM\\1"+name);// 给定文件路径 和 名称
            FileOutputStream fileOutputStream2=new FileOutputStream(file2);//窗机输出流
            fileOutputStream2.write(bytes);//写入数据
            fileOutputStream2.close();//关闭输出流

            trackerServer.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }finally {
            return bytes;
        }
    }



    public static byte[] testDownload(String filename) {
        byte[] bytes = null;
        try {
            //1.初始化fastdfs客户端配置文件
            ClientGlobal.initByProperties("fastdfs-client.properties");// 加载properties配置文件
            System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms");//输出properties中配置的参数,检测properties文件是否生效
            System.out.println("charset=" + ClientGlobal.g_charset);

            // 2.获取trackerServer
            TrackerClient tracker = new TrackerClient();// 创建tracker客户端对象
            TrackerServer trackerServer = tracker.getConnection();//获得tracker连接对象

            //3.获取storageClient(通过trackerServer 和 storageServer:null)
            StorageServer storageServer = null;
            StorageClient1 client = new StorageClient1(trackerServer, storageServer);//通过tracker服务器返回storage服务器对象(客户端)
            String name = "wKg4CmP7btCAZpAmAADA8Mf85m8679.pdf";
            //4.下载操作
            //方式一 文件id下载
             bytes = client.download_file1(filename);//记得要传文件id返回字节流
//            File file=new File("D:\\KM\\"+name);// 给定文件路径 和 名称
//            FileOutputStream fileOutputStream=new FileOutputStream(file);//窗机输出流
//            fileOutputStream.write(bytes);//写入数据
//            fileOutputStream.close();//关闭输出流

            //方式二 组名+文件路径
//            byte[] bytes2 = client.download_file("group1","/M00/00/00/"+name);//记得修改
//            File file2=new File("D:\\KM\\1"+name);// 给定文件路径 和 名称
//            FileOutputStream fileOutputStream2=new FileOutputStream(file2);//窗机输出流
//            fileOutputStream2.write(bytes);//写入数据
//            fileOutputStream2.close();//关闭输出流


            trackerServer.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        finally {
            return bytes;
        }
    }



}

Vue部分

vue预览功能参考:vue-pdf实现pdf文件在线预览

vue预览功能结合实现(以下代码为案例代码:核心代码)
一、本地测试环境,需要配置跨域
在vue.config.js中配置需要跨域的IP地址

 'pdf': {
              target: 'http://xxx.xxx.xx.x/',
              changOrigin: true,  
              pathRewrite: {
                  '^/pdf': ''  
              } 
          }

其中 pdfUrl 只需赋值 后缀即可如下所示

group1/M00/00/01/wKg4CmQVuuiAZRYnAALX0oge5B8291.pdf

在这里插入图片描述

 <el-dialog title="查看" :visible.sync="showVisible" :width="hxi+'%'">
           <div class="pdf" :visible.sync="showVisible">
            
                <div class="pdf-tab">
                <!-- <div class="btn-def"
                    @click.stop="clock">顺时针</div>
                <div class="btn-def"
                    @click.stop="counterClock">逆时针</div> -->
                </div>
              
                <el-button type="success" :class="{select:idx==0}"
                        @touchstart="idx=0"
                        @touchend="idx=-1"
                        @click="scaleD">
                放大
               </el-button>
               <el-button type="success" :class="{select:idx==1}"
                        @touchstart="idx=1"
                        @touchend="idx=-1"
                        @click="scaleX">
                缩小
              </el-button>
               
                <!-- <div>进度:{{loadedRatio}}</div> -->
                <!-- <div>页面加载成功: {{curPageNum}}</div> -->
                 <div class="main">
                    <pdf ref="pdf"
                        :src="pdfUrl"
                        :page="pageNum"
                        :rotate="pageRotate"
                        @password="password"
                        @progress="loadedRatio = $event"
                        @page-loaded="pageLoaded($event)"
                        @num-pages="pageTotalNum=$event"
                        @error="pdfError($event)"
                        @link-clicked="page = $event">
                    </pdf>
                     <div style="float:right">{{pageNum}}/{{pageTotalNum}}</div>
                </div> 
                 <div>
                 
                   <el-button class="btn-def btn-pre" type="success"
                        @click.stop="prePage" style="mar">上一页</el-button>
                    <el-button class="btn-def btn-next" type="primary"`在这里插入代码片`
                        @click.stop="nextPage">下一页 </el-button>
                        
                 </div>
              
            </div>
         </el-dialog>

二、若是部署上线,无法预览需要配置nginx进行地址映射,比如部署的tomcat服务器地址为 8080端口,而安装的DFS服务器为80端口,那就将tomcat的8080端口,配置代理为

location /pdf/{
            proxy_pass   http://xxx.xxx.xx.xx:8080/;
 }

在这里插入图片描述

下载功能,目前实现就是结合后端,通过io流的形式,进行跳转下载
,vue处理代码如下:

 window.location.href = 'http://xxx.xxx.xx.xx:8082/upload/downloadFile?filePath='+this.FileData.filepath;

在这里插入图片描述

在这里插入图片描述
文件上传功能,结合 element ui
只需将action 改为自己的接口即可,springboot的源码在上面

<el-upload
  class="upload-demo"
  action="https://localhost:8082/upload/file"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :before-remove="beforeRemove"
  multiple
  :limit="3"
  :on-exceed="handleExceed"
  :file-list="fileList">
  <el-button size="small" type="primary">点击上传</el-button>
  <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/3664.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot集成RocketMQ实现普通、延时、事务消息发送接收、PULL消费模式及开启ACL | Spring Cloud 30

一、前言 在前面我们通过以下章节对RocketMQ有了基础的了解&#xff1a; docker-compose 搭建RocketMQ 5.1.0 集群&#xff08;双主双从模式&#xff09; | Spring Cloud 28 docker-compose 搭建RocketMQ 5.1.0 集群开启ACL权限控制 | Spring Cloud 29 现在开始我们正式学习…

LORA: LOW-RANK ADAPTATION OF LARGE LAN-GUAGE MODELS

Paper name LORA: LOW-RANK ADAPTATION OF LARGE LAN-GUAGE MODELS Paper Reading Note Paper URL: https://arxiv.org/pdf/2106.09685.pdf Code URL: huggingface 集成&#xff1a; https://github.com/huggingface/peft官方代码&#xff1a; https://github.com/microsof…

C++11新特性

C11新特性 1统一列表初始化 1.1{} 在C98中&#xff0c;标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。 C11扩大了用大括号括起的列表(初始化列表)的使用范围&#xff0c;使其可用于所有的内置类型和用户自定义的类型&#xff0c;**使用初始化列表时&…

安全防御之入侵检测篇

目录 1.什么是IDS&#xff1f; 2.IDS和防火墙有什么不同&#xff1f;3.IDS的工作原理&#xff1f; 4.IDS的主要检测方法有哪些&#xff1f;请详细说明 5.IDS的部署方式有哪些&#xff1f; 6.IDS的签名是什么意思&#xff1f;签名过滤器有什么用&#xff1f;例外签名的配置作…

【数据结构】栈与队列:后进先出与先进先出到底是啥?

&#x1f451;专栏内容&#xff1a;数据结构⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;日拱一卒&#xff0c;功不唐捐 文章目录一、前言二、栈的概念1、定义2、操作三、栈的实现1、定义2、栈的初始化3、栈的销毁4、栈的判空5、查看栈顶元素6、入栈与…

vue3 解决各场景 loading过度 ,避免白屏尴尬!

Ⅰ、前言 当我们每次打卡页面&#xff0c;切换路由&#xff0c;甚至于异步组件&#xff0c;都会有一个等待的时间 &#xff1b;为了不白屏&#xff0c;提高用户体验&#xff0c;添加一个 loading 过度动画是 非常 常见的 &#xff1b;那么这几种场景我们应该把 loading 加在哪…

C语言番外-------《函数栈帧的创建和销毁》知识点+基本练习题+完整的思维导图+深入细节+通俗易懂建议收藏

绪论 书接上回&#xff0c;上回我们已经将C语言的所有知识点进行了总结归纳到同一个思维导图中&#xff0c;而本章是一个番外篇&#xff0c;将具体讲述一些更深入的知识。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 附&#xff1a;红色&…

软件架构常用设计

一、分层架构1.四层架构&#xff1a;分层架构&#xff08;layered architecture&#xff09;是最常见的软件架构&#xff0c;也是事实上的标准架构。如果你不知道要用什么架构&#xff0c;那就用它。这种架构将软件分成若干个水平层&#xff0c;每一层都有清晰的角色和分工&…

【c++】:list模拟实现“任意位置插入删除我最强ƪ(˘⌣˘)ʃ“

文章目录 前言一.list的基本功能的使用二.list的模拟实现总结前言 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。2. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0…

【Linux】进程理解与学习Ⅲ-环境变量

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习Ⅰ-进程概念浅谈Linux下的shell--BASH【Linux】进程理解与学习…

【李宏毅】-各种各样的self-attention

如何使自注意力机制变得高效&#xff1f; 在这篇博客中有讲关于注意力机制&#xff0c;其中&#xff0c;我们需要计算三个矩阵——Q&#xff0c;K&#xff0c;V &#xff0c;如果序列长度为N&#xff0c;那么三个矩阵的大小都是NxN&#xff0c;这将导致注意力机制计算量很大&a…

Linux上搭建Discuz论坛

一.准备工作 1.下载php*&#xff0c;mariadb-server 2.上传Discuz3.5压缩包并解压 二.搭建过程 基于redhat 9 版本和Discuz3.5&#xff0c;php8.0&#xff0c;mariadb10.5演示 一.准备工作 1.下载php*&#xff0c;mariadb-server [rootredhat9 aaa]# yum install -y php*…

软件测试基础篇

一、软件测试的生命周期 需求分析计划阶段&#xff1a;范围、时间、人员、工具&#xff1b;测试设计/开发&#xff1a;编写测试用例&#xff1b;测试执行&#xff1a;执行并补充测试用例&#xff1b;测试评估&#xff1a;覆盖范围&#xff08;测试了哪些功能&#xff0c;哪些没…

QCefView编译配置(Windows-MSVC)(11)

QCefView编译配置&#xff08;Windows-MSVC&#xff09; 文章目录QCefView编译配置&#xff08;Windows-MSVC&#xff09;1、概述2、准备工作3、添加环境变量4、更换cef源码版本5、CMake构建6、Visual Studio编译7、安装编译后的文件8、验证编译结果更多精彩内容&#x1f449;个…

jwt 学习笔记

概述 JWT&#xff0c;Java Web Token&#xff0c;通过 JSON 形式作为 Web 应用中的令牌&#xff0c;用于在各方之间安全地将信息作为 JSON 对象传输&#xff0c;在数据传输过程中还可以完成数据加密、签名等相关处理 JWT 的作用如下&#xff1a; 授权&#xff1a;一旦用户登…

ChatGPT常用开源项目汇总

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️&#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

动态代理原理

一、案例分析 1、引出问题 回到Spring之初控制事务繁琐的问题。 回到Spring之初控制事务繁琐的问题. 考虑一个应用场景∶需要对系统中的某些业务方法做事务管理&#xff0c;拿简单的save和update操作举例。没有加上事务控制的代码如下。 加上事务代码&#xff0c;如下&#x…

【备战蓝桥杯】----01背包问题(动态规划)

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

vue3 自定义message弹窗

1、定义一个Message.vue组件其内容如下 <template><Transition name"down"><div class"xtx-message" :style"style[type]" v-show"visible"><!-- 上面绑定的是样式 --><!-- 不同提示图标会变 :class"…

【数据结构】千字深入浅出讲解栈(附原码 | 超详解)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;C语言实现数据结构 &#x1f4ac;总结&#xff1a;希望你看完…
最新文章