记录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>

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

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

相关文章

【多线程】CAS

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; 目 录&#x1f40d;一. 什么是 CAS&#x1f98e;二. CAS 是怎么实现的&#x1f996;三. CAS 典型应用场景&#x1f436;1. 实现原子类&#x1f431;2. 实现自旋锁&#x1f995;四. …

进程间通信----信号量

文章目录信号量1. 问题2. 什么是信号量3. 信号量的使用4. 信号量的控制6. 实例信号量 1. 问题 程序中&#xff0c;有时存在一种特殊代码&#xff0c;最多只允许一个进程执行该部分代码。这部分区域&#xff0c;称为“临界区” 然而在多进程并发执行时&#xff0c;当一个进程进…

Pseudo-completeness(前中序遍历确定后序遍历)

题目链接&#xff1a;题目详情 - 7-16 Pseudo-completeness (pintia.cn) 样例1输入&#xff1a; 7 4 2 5 1 6 3 7 1 2 4 5 3 6 7样例1输出&#xff1a; 1 4 5 2 6 7 3 1样例2输入&#xff1a; 10 8 4 9 2 10 5 1 6 3 7 1 2 4 8 9 5 10 3 6 7样例2输出&#xff1a; 2 8 9 4…

启动容器(后台模式)

使用以下命令创建一个以进程方式运行的容器 rootLAPTOP-B38J348H:~# docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world ; sleep 1; done" 在输出中&#xff0c;我们没有看到期望的 "hello world"&#xff0c;而是一串长字符 f7…

IDEA的全新UI可以在配置里启用了,快来试试吧!

刚看到IDEA官方昨天发了这样一条推&#xff1a;IDEA的新UI可以在2022.3版本上直接使用了&#xff01;开启方法如下&#xff1a;打开IDEA的Setting界面&#xff0c;在Appearance & Behavior下有个被标注为Beta标签的New UI菜单&#xff0c;具体如下图&#xff1a;勾选Enable…

ChartGPT多重插补法 填充缺失点

问题描述已知时间戳与对应的值&#xff0c;需要根据时间戳找到缺失的点&#xff0c;然后进行值的填充。例如&#xff1a;源码<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 --><dependency><groupId>org.apache.commons</gr…

【微信小程序】-- uni-app 项目-- 配置 tabBar 效果(五十一)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

【C++进阶】智能指针

文章目录为什么需要智能指针&#xff1f;内存泄漏什么是内存泄漏&#xff0c;内存泄漏的危害内存泄漏分类&#xff08;了解&#xff09;如何避免内存泄漏智能指针的使用及原理smart_ptrauto_ptrunique_ptrshared_ptr线程安全的解决循环引用weak_ptr删除器为什么需要智能指针&am…

HJZS电源监视继电器HJZS-E202 AC220V

系列型号&#xff1a; HJZS-E202断电延时继电器 HJZS-E002断电延时继电器 一 应用 HJZS-E202电源监视继电器用于直流或交流操作的各种保护和自动控制的装置中&#xff0c;用以增加触点数量。 二 安装结构 导轨安装9壳体结构&#xff0c;具体尺寸参阅外型尺寸图。 三 产品型号…

蓝桥杯刷题冲刺 | 倒计时14天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.最长递增2.走迷宫3.解立方根4.回文特判5.修改数组1.最长递增 题目 链接&#xff1a; 最长递增…

【Java版oj 】 day17杨辉三角形的变形、计算某字符出现次数

目录 一、杨辉三角形的变形 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 二、计算某字符出现次数 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代…

Python调用GPT3.5接口的最新方法

GPT3.5接口调用方法主要包括openai安装、api_requestor.py替换、接口调用、示例程序说明四个部分。 1 openai安装 Python openai库可直接通过pip install openai安装。如果已经安装openai&#xff0c;但是后续提示找不到ChatCompletion&#xff0c;那么请使用命令“pip instal…

【ArcGIS Pro二次开发】(18):地理处理工具类【Geoprocessing】补遗

ArcGIS Pro SDK 3.0中的Geoprocessing类是用于执行地理处理工具的核心类。地理处理工具是用于执行空间分析、数据转换、数据管理等任务的工具集&#xff0c;包括常见的空间分析工具、栅格处理工具、矢量处理工具、地图制图工具等。 之前有简单记录了下Geoprocessing工具的用法…

整理了一份github上比较热门的ChatGPT项目,值得收藏

ChatGPT已经火了一段时间了&#xff0c;但是&#xff0c;热度依旧是各大自媒体的热榜。由于&#xff0c;国内不能直接访问ChatGPT,国内的开发者依托OpenAI的接口&#xff0c;开发出一些ChatGPT的应用。今天就整理一下github上最热门的ChatGPT项目。 lencx/ChatGPT 该项目是Cha…

springboot校友社交系统

050-springboot校友社交系统演示录像开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;e…

蓝桥杯第14天(Python版)

并查集的使用# 并查集模板 N400 fa[] def init(): # 初始化&#xff0c;默认自身为根接点for i in range(N):fa.append(i)def merge(x,y): # 发现可以合并&#xff0c;默认选x的根节点为根接点fa[find(x)]find(y)def find(x): # 相等就是根结点&#xff0c;不然就递归查找根…

Vue3监听器使用

watch(监听的对象或值, 回调函数&#xff08;参数新值&#xff0c;旧值&#xff09;, 配置项是对象{ immediate: true//立即监听--进入就会执行一次 deep&#xff1a;true //深度监听 }) 首先引入 import { ref, watch } from vue; 设置响应式数据 const num ref(1) …

【数据结构篇C++实现】- 栈

文章目录&#x1f680;一、栈的原理精讲&#x1f680;二、栈的算法实现⛳栈的顺序存储结构&#x1f389;&#xff08;一&#xff09;顺序栈1.栈的结构体定义2.栈的初始化3.判断空栈4.判断栈满5.元素入栈6.元素出栈7.获取栈顶元素&#x1f389;&#xff08;二&#xff09;共享栈…

冯诺依曼,操作系统以及进程概念

文章目录一.冯诺依曼体系结构二.操作系统&#xff08;operator system&#xff09;三.系统调用和库函数四.进程1.进程控制块&#xff08;PCB&#xff09;2.查看进程3.系统相关的调用4.fork介绍&#xff08;并发引入&#xff09;五.总结一.冯诺依曼体系结构 计算机大体可以说是…

MD5加密竟然不安全,应届生表示无法理解?

前言 近日公司的一个应届生问我&#xff0c;他做的一个毕业设计密码是MD5加密存储的&#xff0c;为什么密码我帮他调试的时候&#xff0c;我能猜出来明文是什么&#xff1f; 第六感&#xff0c;是后端研发的第六感&#xff01; 正文 示例&#xff0c;有个系统&#xff0c;前…