当前位置: 首页 > news >正文

Ruoyi若依框架下载流程详细解读(SpringBoot-Vue)

图解:

前端设计:

前端设计一个link文字连接或者按钮(ElementUI)Element - The world's most popular Vue UI framework

前端请求设计:

import request from '@/utils/request'
//下载示例模型定义语言的JSON
export const publishExportTemplateFile = (res, name, type = false) => {let url;if (type) {url = window.URL.createObjectURL(new Blob([res], {type: 'application/json5'}));//application后短语相应类型,// Important blob类型接收} else {url = window.URL.createObjectURL(new Blob([res]));}// const url = window.URL.createObjectURL(new Blob([res]));const link = document.createElement('a');link.style.display = 'none';link.href = url;link.setAttribute('download', name);document.body.appendChild(link);link.click();document.body.removeChild(link);
}export function downloadFile(filePath) {return request({url: '/configuration/download',method: 'get',params: { fileName: filePath, delete: false },responseType: 'blob' // 设置响应类型为 blob})
}

其中 publishExportTemplateFile 函数用于处理文件下载的前端逻辑,而 downloadFile 函数用于发起后端请求获取文件。

前端Vue组件

<template>
      <el-link type="primary" @click="download(filename)">下载示例配置文件</el-link>
</template>

<script>
import {downloadFile,publishExportTemplateFile } from "@/api/register/register";
export default {
  data() {
      return {
           filename:"template.json5"
      }
    },
methods(){
    download(filename){
      downloadFile(filename).then(response => {
        publishExportTemplateFile(response, filename);
      }).catch(error => {
        console.error('Download file failed:', error);
      });
    },
}
};
</script>

<style>

</style>

后端Controller:

@GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) {try {if (!FileUtils.checkAllowDownload(fileName)) {throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 " , fileName));}String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);System.out.println("realFileName = " + realFileName);String filePath = RuoYiConfig.getDownloadPath() + fileName; //注意这里的路径要和你下载的路径对应response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);FileUtils.setAttachmentResponseHeader(response, realFileName);FileUtils.writeBytes(filePath, response.getOutputStream());if (delete) {FileUtils.deleteFile(filePath);}} catch (Exception e) {log.error("下载文件失败", e);}
}

后端Utils:

//从全局配置文件获取下载文件所在目录(src/main/java/com/ruoyi/common/config/RuoYiConfig.java)
@Component
@ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig{public static String getProfile(){return profile;}public void setProfile(String profile){RuoYiConfig.profile = profile;}
/*** 获取下载路径*/public static String getDownloadPath(){return getProfile() + "/download/";}/** 上传路径 */private static String profile
//文件相关操作
public class FileUtils extends FileUtil {/*** 下载文件名重新编码** @param response     响应对象* @param realFileName 真实文件名*/public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {String percentEncodedFileName = percentEncode(realFileName);StringBuilder contentDispositionValue = new StringBuilder();contentDispositionValue.append("attachment; filename=").append(percentEncodedFileName).append(";").append("filename*=").append("utf-8''").append(percentEncodedFileName);response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");response.setHeader("Content-disposition", contentDispositionValue.toString());response.setHeader("download-filename", percentEncodedFileName);}
public static void writeBytes(String filePath, OutputStream os) throws IOException
{FileInputStream fis = null;try{File file = new File(filePath);if (!file.exists()){throw new FileNotFoundException(filePath);}fis = new FileInputStream(file);byte[] b = new byte[1024];int length;while ((length = fis.read(b)) > 0){os.write(b, 0, length);}}catch (IOException e){throw e;}finally{IOUtils.close(os);IOUtils.close(fis);}
}

http://www.lryc.cn/news/325335.html

相关文章:

  • 【深度学习】Pytorch中实现交叉熵损失计算的方式总结
  • 机器学习:处理jira工单的分类问题
  • 后端常问面经之操作系统
  • RK3568平台 iperf3测试网络性能
  • Spring Boot中实现对特定URL的权限验证:拦截器、切面和安全框架的比较
  • 【能源数据分析-00】能源领域数据集集锦(动态更新)
  • 数据挖掘与机器学习 1. 绪论
  • Matlab实现序贯变分模态分解(SVMD)
  • 云安全与云计算的关系
  • WPF 界面变量绑定(通知界面变化)
  • eclipse导入svn项目
  • Prompt提示工程上手指南:基础原理及实践(四)-检索增强生成(RAG)策略下的Prompt
  • 阿里云倚天云服务器怎么样?如何收费?
  • 海外社交营销为什么用云手机?不用普通手机?
  • 【Mysql数据库基础05】子查询 where、from、exists子查询、分页查询
  • 在Linux/Debian/Ubuntu上通过 Azure Data Studio 管理 SQL Server 2019
  • Java代码基础算法练习-搬砖问题-2024.03.25
  • Tomcat调优
  • 每日OJ题_栈①_力扣1047. 删除字符串中的所有相邻重复项
  • SQLServer SEQUENCE用法
  • Java中的代理模式(动态代理和静态代理)
  • 强化学习之父Richard Sutton:通往AGI的另一种可能
  • 【智能算法】秃鹰搜索算法(BES)原理及实现
  • 前端并发控制
  • 基于YOLOv8深度学习的橙子病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类
  • Java中的多线程详解(超级简单理解)(上篇)
  • Elastic-Job 分布式任务调度
  • YZ系列工具之YZ09: VBA_Excel之读心术
  • Python下载音乐
  • PCL ICP配准高阶用法——统计每次迭代的配准误差并可视化