前言

本文主要实现了以下功能:
1、 单文件上传以及多文件上传功能
2、 输入文件名下载文件功能
3、 输入音频文件名在线播放音频功能

一、项目基础部分搭建

1.1 前端项目搭建

1.1.1 新建前端项目

打开命令行输入以下命令,使用Vue CLI创建前端项目,Vue CLI安装教程

vue create file-demo

SpringBoot+Vue实现文件上传下载功能

1.1.2 引入axios

输入以下命令在项目中引入axios

npm install axios --save

SpringBoot+Vue实现文件上传下载功能

1.1.3 解决跨域问题

打开vue.config.js添加以下配置,修改启动端口,以及配置代理解决跨域问题

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true
})
module.exports = {
  devServer: {
    // 修改前端项目启动端口号
    port: 8081,
    proxy: {
      '^/file': {
        // 此处配置对应的后端端口
        target: "http://localhost:8080",
        // 如果是https接口,需要配置这个参数为true
        secure: false,
        // 此处配置路径重写
        pathRewrite: {
          '^/file': '/file'
        }
      }
    }
  }
}

1.2 后端项目搭建

1.2.1 新建后端项目

打开IDEA,按照以下步骤创建一个新的SpringBoot项目
SpringBoot+Vue实现文件上传下载功能
SpringBoot+Vue实现文件上传下载功能

1.2.2 编辑配置文件

打开项目,编辑application.properties配置文件,输入以下配置
SpringBoot+Vue实现文件上传下载功能

#可以选择性的修改或选择以下配置
#配置服务端口
server.port=8080
#是否开启文件上传支持,默认是true
spring.servlet.multipart.enabled=true
#文件写入磁盘的阈值,默认是0
spring.servlet.multipart.file-size-threshold=0
#单个文件的最大值,默认是50MB
spring.servlet.multipart.max-file-size=50MB
#多个文件上传时的总大小 值,默认是100MB
spring.servlet.multipart.max-request-size=100MB
#是否延迟解析,默认是false
spring.servlet.multipart.resolve-lazily=false
#自定义文件访问路径
myfile.path=E:\\test\\dir

二、文件上传功能

2.1 单文件上传功能实现

2.1.1 前端代码

App.vue中添加如下代码,使用form标签实现文件上传功能

<template>
  <p>单文件上传</p>
  <form action="/file/uploadSingleFile" method="post" enctype="multipart/form-data">
    文件:
    <input type="file" name="file">
    <input type="submit">
  </form>
</template>

2.1.2 后端代码

com.example.springbootdemo.controller包下创建UploadFileController.java文件

package com.example.springbootdemo.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Slf4j
@RestController
@RequestMapping("/file")
public class UploadFileController {
    @Value("${myfile.path}")
    private String filePath;
    // 单文件上传功能
    @PostMapping("/uploadSingleFile")
    public void uploadSingleFile(@RequestParam("file") MultipartFile multipartFile) {
        String fileName = multipartFile.getOriginalFilename();
        File file = new File(filePath + '\\' + fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
            log.info("父级文件目录不存在,已创建目录");
        }
        try {
            multipartFile.transferTo(file);
        } catch (IOException e) {
            log.error("{}",e);
            log.error("程序错误,请重新上传");
            e.printStackTrace();
        } finally {
            log.info("文件上传成功,文件全路径名称为:{}",file.getPath());
        }
    }
}

2.2 多文件上传功能实现

2.2.1 前端代码

App.vue中添加如下代码,使用form标签实现文件上传功能

<template>
  <p>多文件上传</p>
  <form action="/file/uploadMultipleFile" method="post" enctype="multipart/form-data">
    文件:
    <input type="file" name="files" multiple="multiple">
    <input type="submit">
  </form>
</template>

2.2.2 后端代码

com.example.springbootdemo.controller包下创建UploadFileController.java文件

package com.example.springbootdemo.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Slf4j
@RestController
@RequestMapping("/file")
public class UploadFileController {
    @Value("${myfile.path}")
    private String filePath;
    // 多文件上传功能实现
    @PostMapping("/uploadMultipleFile")
    public void uploadMultipleFile(@RequestParam("files") MultipartFile multipartFiles[]) {
        for (MultipartFile multipartFile : multipartFiles) {
            String fileName = multipartFile.getOriginalFilename();
            File file = new File(filePath + '\\' + fileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
                log.info("父级文件目录不存在,已创建目录");
            }
            try {
                multipartFile.transferTo(file);
            } catch (IOException e) {
                log.error("{}",e);
                log.error("程序错误,请重新上传");
                e.printStackTrace();
            } finally {
                log.info("文件上传成功,文件全路径名称为:{}",file.getPath());
            }
        }
    }
}

三、文件下载功能

3.1 普通文件下载功能实现

3.1.1 前端代码

App.vue中添加如下代码,使用form标签实现文件上传功能

<template>
  <p>文件下载{{inputData.fileName}}</p>
  <input type="text" placeholder="请输入全文件名" v-model="inputData.fileName">
  <button @click="downloadFile">下载</button>
</template>
<script>
import axios from 'axios';
import { reactive } from 'vue';
export default{
  setup() {
    let inputData = reactive({
      fileName:""
    })
    // 下载文件函数
    async function downloadFile() {
      let BASE_URL = "/file";
      let data = {
        ...inputData
      }
      console.log(inputData);
      await axios({
        url: `${BASE_URL}/downloadFile`,
        method: "post" ,
        data: data,
        headers: {
          'Content-Type': 'application/json'
        },
        responseType: 'blob',
      }).then((resp) => {
        const blob = new Blob([resp.data]);
        var downloadElement = document.createElement("a");
        var href = window.URL.createObjectURL(blob);
        downloadElement.href = href;
        downloadElement.download = decodeURIComponent(inputData.fileName);
        document.body.appendChild(downloadElement);
        downloadElement.click();
        document.body.removeChild(downloadElement);
        window.URL.revokeObjectURL(href);
      });
    }
    return {
      inputData,
      downloadFile
    }
  }
}
</script>

3.1.2 后端代码

com.example.springbootdemo.controller包下建立DownloadFileController

package com.example.springbootdemo.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/file")
public class DownloadFileController {
    @Value("${myfile.path}")
    private String filePath;
    @PostMapping("/downloadFile")
    public void downloadFile(@RequestBody Map<String, String> params, HttpServletRequest request, HttpServletResponse response) {
        log.info("文件名为:{}",params.get("fileName"));
        if (!params.containsKey("fileName") || params.get("fileName") == null || "".equals(params.get("fileName"))) {
            log.info("文件名不存在");
            return;
        }
        if (filePath == null || "".equals(filePath)) {
            log.info("文件路径不存在");
            return;
        }
        String fileName = params.get("fileName");
        String fullPath = filePath + "\\" + fileName;
        try {
            download(request,response, fullPath, fileName);
        } catch (Exception e) {
            log.error("{}",e);
            log.error("文件下载失败");
            e.printStackTrace();
        }
    }
    // 下载文件方法:
    public static void download(HttpServletRequest request, HttpServletResponse response, String filePath, String realName) throws Exception {
        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        long fileLength = (new File(filePath)).length();
        response.setContentType("application/octet-stream;charset=GBK");
        response.setHeader("Content-disposition", "attachment; filename=" + new String(realName.getBytes("GB2312"), "ISO-8859-1"));
        response.setHeader("Content-Length", String.valueOf(fileLength));
        bis = new BufferedInputStream(new FileInputStream(filePath));
        bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buff = new byte[2048];
        int bytesRead;
        while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
            bos.write(buff, 0, bytesRead);
        }
        bis.close();
        bos.close();
    }
}

3.2 音频文件在线播放功能实现

3.2.1 前端代码

App.vue中添加如下代码,使用form标签实现文件上传功能

<template>
  <p>文件下载{{inputData.fileName}}</p>
  <input type="text" placeholder="请输入全文件名" v-model="inputData.fileName">
  <button @click="downloadFile">下载</button>
  <p>音乐在线播放{{}}</p>
  <input type="text" placeholder="请输入音乐文件名" v-model="inputData.fileName">
  <button @click="playMusic">播放音乐</button>
  <br>
  <audio controls currentTime autoplay :src='audioSrc.data'></audio>
</template>
<script>
import axios from 'axios';
import { reactive } from 'vue';
export default{
  setup() {
    let inputData = reactive({
      fileName:""
    })
    let audioSrc = reactive({
      data:""
    });
    // 在线播放音乐函数
    async function playMusic() {
      let BASE_URL = "/file";
      let data = {
        ...inputData
      }
      console.log(inputData);
      await axios({
        url: `${BASE_URL}/downloadFile`,
        method: "post" ,
        data: data,
        headers: {
          'Content-Type': 'application/json'
        },
        responseType: 'blob',
      }).then((Blobdata) => {
        audioSrc.data = window.URL.createObjectURL(Blobdata.data);
      });
    }
    return {
      inputData,
      audioSrc,
      playMusic
    }
  }
}
</script>

3.2.2 后端代码

com.example.springbootdemo.controller包下建立DownloadFileController

package com.example.springbootdemo.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/file")
public class DownloadFileController {
    @Value("${myfile.path}")
    private String filePath;
    @PostMapping("/downloadFile")
    public void downloadFile(@RequestBody Map<String, String> params, HttpServletRequest request, HttpServletResponse response) {
        log.info("文件名为:{}",params.get("fileName"));
        if (!params.containsKey("fileName") || params.get("fileName") == null || "".equals(params.get("fileName"))) {
            log.info("文件名不存在");
            return;
        }
        if (filePath == null || "".equals(filePath)) {
            log.info("文件路径不存在");
            return;
        }
        String fileName = params.get("fileName");
        String fullPath = filePath + "\\" + fileName;
        try {
            download(request,response, fullPath, fileName);
        } catch (Exception e) {
            log.error("{}",e);
            log.error("文件下载失败");
            e.printStackTrace();
        }
    }
    // 下载文件方法:
    public static void download(HttpServletRequest request, HttpServletResponse response, String filePath, String realName) throws Exception {
        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        long fileLength = (new File(filePath)).length();
        response.setContentType("application/octet-stream;charset=GBK");
        response.setHeader("Content-disposition", "attachment; filename=" + new String(realName.getBytes("GB2312"), "ISO-8859-1"));
        response.setHeader("Content-Length", String.valueOf(fileLength));
        bis = new BufferedInputStream(new FileInputStream(filePath));
        bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buff = new byte[2048];
        int bytesRead;
        while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
            bos.write(buff, 0, bytesRead);
        }
        bis.close();
        bos.close();
    }
}