vue + springboot 文件下载,笔记

本文详细介绍了如何在前端Vue项目中实现文件的上传与下载功能,后端采用SpringBoot进行文件流处理,确保文件安全下载,避免直接链接暴露。通过Java NIO技术下载文件并临时保存,再将文件流返回前端,实现文件的安全下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

前言:

前端项目基于vue的,后端是springboot,文件上传后保存在文件服务器,同时文件服务器返回文件的访问路径,

当需要下载时,为了不让每个人都能通过页面a标签点击链接直接保存到本地,所以采用后台临时下载,返回文件流给前端,前端解析文件流,通过浏览器下载到浏览器存储目录中

1.用户点击请求下载文件

2.后端根据请求中的URL路径使用Java NIO下载文件,临时保存到下载服务器本地

3.通过文件流读取服务器本地文件,创建输出流,响应给前端

1.前端代码

<a @dblclick="downloadFile(item.url)" title="双击下载文件" v-else class="pointer"
           style="display:block;width: 76px;height: 76px;overflow:hidden;word-wrap:break-word;line-height: 14px;background: #dedede;">
          {{item.url.substring(item.url.lastIndexOf('/')+1,item.url.length)}}</a>

 

<script>
  import {postFileDownload} from '../../../api/api'
  export default {
    methods:{
        downloadFile(url){// 下载文件
        postFileDownload({url:url})
      }
    }
}
</script>

 api.js

import axios from '../assets/js/http'

export const postFileDownload = params =>{return axios.get('/fileAPI/downloadFile',{params:params},{responseType:'blob'}).then(res=>{
  if(res.data && res.data.code === '-1')return;
  let blob = new Blob([res.data]);
  let fileName = res.headers.contentfilename;
  if ('download' in document.createElement('a')) { // 非IE下载
    let elink = document.createElement('a');
    elink.download = fileName;
    elink.style.display = 'none';
    elink.href = URL.createObjectURL(blob);
    document.body.appendChild(elink);
    elink.click();
    URL.revokeObjectURL(elink.href); // 释放URL
    document.body.removeChild(elink)
  } else {
    navigator.msSaveBlob(blob, fileName)
  }
})};

2.后端代码

控制层 , 权限这里只是测试,因为项目中有权限控制类,对接就好

@RequestMapping(value = "/downloadFile",method = RequestMethod.GET)
	public Map downloadByURL(String url,HttpServletResponse res, HttpServletRequest req) throws IOException{
		System.out.println("url:::::::::"+url);
		Map map = new HashMap();
		String auth = "Y";
		if(auth.equals("N")){// 如果没有权限 只返回
			map.put("code", "-1");
			map.put("desc", "没有权限");
			return map;
		}
		try {
			fileDownloadUtil.downloadFile(url,res,req);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

下载工具类

/**
     * 下载文件
     * @param path 文件的位置
     * @param fileName 自定义下载文件的名称
     * @param resp http响应
     * @param req http请求
	 * @throws Exception 
     */
    public static void downloadFile(String url, HttpServletResponse res, HttpServletRequest req) throws Exception{
    	String charsetCode = "utf-8";
    	String fileName = url.substring(url.lastIndexOf('\\')+1,url.length());
    	FileInputStream in = null;
		OutputStream out = null;
        try {
        	// 获取文件路径后先下载到服务器本地,返回服务器文件地址
        	String path = downloadFileByNIO(url);
        	System.out.println(path);
            File file = new File(path);
            /**
             * 文件名中文乱码处理
             */
            System.out.println("fileName:::::" + fileName);
            String type = req.getHeader("User-Agent").toLowerCase();
            if(type.indexOf("firefox")>0 || type.indexOf("chrome")>0){// 非IE
              
                fileName = new String(fileName.getBytes(charsetCode), "iso8859-1");
            }else{
                fileName = URLEncoder.encode(fileName, charsetCode);
            }
            // 设置响应的头部信息
            res.setHeader("contentfileName", fileName);
            // 设置响应内容的类型
            res.setContentType("application/json;charset=" + charsetCode);
            // 设置响应内容的长度
            res.setContentLength((int) file.length());
            //读取要下载的文件,保存到文件输入流
			 in= new FileInputStream(file);
			//创建输出流
			 out= res.getOutputStream();
			//缓存区
			 byte[] buffer = new byte[1024];
	         int length = -1;
	         while ((length = in.read(buffer)) != -1) {
	           out.write(buffer, 0, length);
	           out.flush();
	         }
            // 删除文件
            delFile(file);
        } catch (Exception e) {
        	e.printStackTrace(); 
        	throw e;
        }finally{
        	try {
        		out.close();
            } catch (IOException e) {
            }
            try {
            	in.close();
            } catch (IOException e) {
            }
        }
    }


  /**
     * 使用NIO下载文件
     * @param url 下载的文件路径
     */
    public static String downloadFileByNIO(String url) {
    	String saveDir = "E:\\HZ\\";
    	String fileName = url.substring(url.lastIndexOf('/') > (url.startsWith("http:") ? 6 :7)
    			? url.lastIndexOf('/') + 1 : url.lastIndexOf('\\') + 1,url.length());
    	url = url.replace('\\', '/');
        try (InputStream ins = new URL(url).openStream()) {
            Path targetPath = Paths.get(saveDir, fileName);
            Files.createDirectories(targetPath.getParent());
            Files.copy(ins, targetPath, StandardCopyOption.REPLACE_EXISTING);
//            System.out.println(saveDir + fileName);
            return saveDir + fileName;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } 
        
    }


	/**
	 * 删除文件
	 * @param file
	 * @return
	 */
    public static boolean delFile(File file) {
    	System.out.println("删除文件:" + file);
    	if (!file.exists()) {
    	    return false;
    	}
    	boolean flag = file.delete();
    	System.out.println(flag);
    	return flag;
 	 }

完结,存在的问题,删除文件失败,用main方法测试是可以的,返回true,但是请求调用时false,有谁找出问题所在,请留言,万分谢谢

附上main方法测试代码,郁闷中

	public static void main(String args[]){
		delFile(new File("E:\\HZ1\\hz1577340815468.exe"));
		
	}

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值