SpringBoot实现文件下载功能的方式分享

1. 将文件以流的形式一次性读取到内存,通过响应输出流输出到前端

/**
 * @param path     想要下载的文件的路径
 * @param response
 * @功能描述 下载文件:
 */
@RequestMapping("/download")
public void download(String path, HttpServletResponse response) {
    try {
        // path是指想要下载的文件的路径
        File file = new File(path);
        log.info(file.getPath());
        // 获取文件名
        String filename = file.getName();
        // 获取文件后缀名
        String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
        log.info("文件后缀名:" + ext);

        // 将文件写入输入流
        FileInputStream fileInputStream = new FileInputStream(file);
        InputStream fis = new BufferedInputStream(fileInputStream);
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();

        // 清空response
        response.reset();
        // 设置response的Header
        response.setCharacterEncoding("UTF-8");
        //Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
        //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
        // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        // 告知浏览器文件的大小
        response.addHeader("Content-Length", "" + file.length());
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        outputStream.write(buffer);
        outputStream.flush();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

2. 将输入流中的数据循环写入到响应输出流中,而不是一次性读取到内存,通过响应输出流输出到前端

/**
* @param path     指想要下载的文件的路径
* @param response
* @功能描述 下载文件:将输入流中的数据循环写入到响应输出流中,而不是一次性读取到内存
*/
@RequestMapping("/downloadLocal")
public void downloadLocal(String path, HttpServletResponse response) throws IOException {
   // 读到流中
   InputStream inputStream = new FileInputStream(path);// 文件的存放路径
   response.reset();
   response.setContentType("application/octet-stream");
   String filename = new File(path).getName();
   response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
   ServletOutputStream outputStream = response.getOutputStream();
   byte[] b = new byte[1024];
   int len;
   //从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1
   while ((len = inputStream.read(b)) > 0) {
       outputStream.write(b, 0, len);
   }
   inputStream.close();
}

3. 下载网络文件到本地

/**
* @param path       下载后的文件路径和名称
* @param netAddress 文件所在网络地址
* @功能描述 网络文件下载到服务器本地
*/
@RequestMapping("/netDownloadLocal")
public void downloadNet(String netAddress, String path) throws IOException {
	  URL url = new URL(netAddress);
	  URLConnection conn = url.openConnection();
	  InputStream inputStream = conn.getInputStream();
	  FileOutputStream fileOutputStream = new FileOutputStream(path);

	  int bytesum = 0;
	  int byteread;
	  byte[] buffer = new byte[1024];
	  while ((byteread = inputStream.read(buffer)) != -1) {
	      bytesum += byteread;
	      System.out.println(bytesum);
	      fileOutputStream.write(buffer, 0, byteread);
	  }
	  fileOutputStream.close();
}

4. 网络文件获取到服务器后,经服务器处理后响应给前端

/**
 * @param netAddress
 * @param filename
 * @param isOnLine
 * @param response
 * @功能描述 网络文件获取到服务器后,经服务器处理后响应给前端
 */
@RequestMapping("/netDownLoadNet")
public void netDownLoadNet(String netAddress, String filename, boolean isOnLine, HttpServletResponse response) throws Exception {

    URL url = new URL(netAddress);
    URLConnection conn = url.openConnection();
    InputStream inputStream = conn.getInputStream();

    response.reset();
    response.setContentType(conn.getContentType());
    if (isOnLine) {
        // 在线打开方式 文件名应该编码成UTF-8
        response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(filename, "UTF-8"));
    } else {
        //纯下载方式 文件名应该编码成UTF-8
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
    }

    byte[] buffer = new byte[1024];
    int len;
    OutputStream outputStream = response.getOutputStream();
    while ((len = inputStream.read(buffer)) > 0) {
        outputStream.write(buffer, 0, len);
    }
    inputStream.close();
}

5. 常见异常和问题

(1)响应对象无需通过return返回

原因:  响应对象是可以不用作为方法返回值返回的,其在方法执行时已经开始输出,且其无法与@RestController配合,以JSON格式返回给前端

解决办法: 删除return语句

(2)返回前端的文件名必须进行URL编码

原因: 网络传输只能传输特定的几十个字符,需要将汉字、特殊字符等经过Base64等编码来转化为特定字符,从而进行传输,而不会乱码

URLEncoder.encode(fileName, "UTF-8")

(3)IO流有待学习

1:read() : 从输入流中读取数据的下一个字节,返回0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。

2:read(byte[] b) : 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1

以上就是SpringBoot实现文件下载功能的方式分享的详细内容,更多关于SpringBoot文件下载的资料请关注我们其它相关文章!

(0)

相关推荐

  • springboot各种下载文件的方式汇总

    目录 一.使用response输出流下载 二.使用ResponseEntity 三.注意 总结 一.使用response输出流下载 注意第一种方式返回值必须为void @GetMapping("/t1") public void down1(HttpServletResponse response) throws Exception { response.reset(); response.setContentType("application/octet-stream;ch

  • SpringBoot实现文件上传与下载功能的示例代码

    目录 Spring Boot文件上传与下载 举例说明 1.引入Apache Commons FileUpload组件依赖 2.设置上传文件大小限制 3.创建选择文件视图页面 4.创建控制器 5.创建文件下载视图页面 6.运行 Spring Boot文件上传与下载 在实际的Web应用开发中,为了成功上传文件,必须将表单的method设置为post,并将enctype设置为multipart/form-data.只有这种设置,浏览器才能将所选文件的二进制数据发送给服务器. 从Servlet 3.0开

  • SpringBoot后台实现文件上传下载

    SpringBoot后台如何实现文件上传下载? 最近做的一个项目涉及到文件上传与下载.前端上传采用百度webUploader插件.有关该插件的使用方法还在研究中,日后整理再记录.本文主要介绍SpringBoot后台对文件上传与下载的处理. 单文件上传 // 单文件上传 @RequestMapping(value = "/upload") @ResponseBody public String upload(@RequestParam("file") Multipar

  • SpringBoot上传和下载文件的原理解析

    技术概述 我们的项目是实现一个论坛.在论坛上发布博客时应该要可以上传文件,用户阅读博客是应该要可以下载文件.于是我去学习了SpringBoot的上传和下载文件,我感觉技术的难点在于使用图床并隐藏文件真实的存放地址. 技术详述 针对使用自己的服务器作为图床, 首先配置WebMvcConfigurer,SpringBoot2.0以后的版本可以使用WebMvcConfigurer实现类方式来进行配置 即创建一个实体类实现WebMvcConfigurer接口 public class WebConfig

  • SpringBoot下载文件的实现及速度对比

    目录 前言 文件来源 文件下载 1.OutputStream形式 2.ResponseEntity形式 两种方式下载速度比较 后话 前言 承上篇上传文件之后,本文就主要介绍下SpringBoot下下载文件的方式,大致有两种Outputstream与ResponseEntity,并大概看一下速度对比 文件来源 这里还是以GridFS为例,主要演示的还是从mongo下载下来的文件,如果是本地服务器上的文件,前端传以文件路径直接获取流即可,如下: InputStream in = new FileIn

  • 从Springboot项目中下载文件的具体过程

    最近在做一个临时的项目,APP端在检测到程序有更新时,需要去后台下载新的安装包.具体过程如下: controller层: /** * 下载app * @param response */ @RequestMapping("downApp") @ResponseBody public void Download(HttpServletResponse response) { String fileName ="wuye.apk"; String result = Fi

  • SpringBoot实现文件下载功能的方式分享

    1. 将文件以流的形式一次性读取到内存,通过响应输出流输出到前端 /** * @param path 想要下载的文件的路径 * @param response * @功能描述 下载文件: */ @RequestMapping("/download") public void download(String path, HttpServletResponse response) { try { // path是指想要下载的文件的路径 File file = new File(path);

  • vue+element+springboot实现文件下载进度条展现功能示例

    目录 1. 需求背景 2. 优化方案 3. 具体实现 3.1 前端代码 3.2 后台代码 4. 总结 本文主要介绍了vue+element+springboot实现文件下载进度条展现功能示例,分享给大家,具体如下 最终效果图 1. 需求背景 最近接到一个优化需求,原系统文件下载功能体验不友好,特别是下载一些比较耗时的文件,用户在页面上傻等不知道下载的进度是怎么样的,总以为是系统卡死了. 2. 优化方案 后台优化下载速度(可以研究一下分片下载,这里不做展开) 改造前端用户体验(比如点击下载后你要显

  • Springboot打印接口的三种方式分享

    目录 1 aop切面的方式 1.1 实现思路 1.2 代码实现 1.3 功能测试 2 过滤器的方式 3 拦截器的方式 1 aop切面的方式 1.1 实现思路 引入aop依赖 自定义注解 定义切面,采用环绕通知 1.2 代码实现 1)引入依赖 xml <!--aop--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-

  • Struts2实现文件下载功能代码分享(文件名中文转码)

    struts2文件下载功能实现代码如下所示: Action文件 public class DownLoadAction extends ActionSupport { /** * */ private static final long serialVersionUID = 5879762231742395104L; private String fileName;//用户请求的文件名 private String inputPath;//下载资源的路径(在struts配置文件中设置) publ

  • PHP使用header方式实现文件下载功能

    先给大家介绍下PHP header() 函数 定义和用法 header() 函数向客户端发送原始的 HTTP 报头. 认识到一点很重要,即必须在任何实际的输出被发送之前调用 header() 函数(在 PHP 4 以及更高的版本中,您可以使用输出缓存来解决此问题): <html> <?php // 结果出错 // 在调用 header() 之前已存在输出 header('Location: http://www.example.com/'); ?> 语法 header(string

  • springboot + mybatis-plus实现多表联合查询功能(注解方式)

    第一步:加入mybatis-plus依赖 第二步:配置数据源 spring: thymeleaf: cache: false encoding: utf-8 prefix: classpath:/templates/ suffix: .html enabled: true datasource: url: jdbc:mysql://192.168.1.152:3306/timo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&

  • jsp文件下载功能实现代码

    本文实例为大家分享了jsp实现文件下载功能的3种方法,供大家参考,具体内容如下 第一种.采用转发的方式: package cn.jbit.download.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.serv

  • php实现支持中文的文件下载功能示例

    前言 本文主要给大家介绍了关于php实现支持中文的文件下载功能的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 问题说明 文件下载,通常有一种最为简单的方法,那就是将url直接指向服务器上文件的所在位置.但是这个方法存在很大的安全隐患. 暴露了服务器文件目录结构 无法禁止非法请求来源,无法对文件下载请求做安全验证 解决方案 一.将文件下载请求映射到后端程序url 借助http服务器(apache/nginx)实现映射功能 这里以apache为例进行说明 借助apach

  • php使用curl实现ftp文件下载功能

    本文实例为大家分享了php实现ftp文件下载功能,供大家参考,具体内容如下 不知道为什么用正常的ftp_get函数下载文件速度特别慢,但是用ftp的客户端下载很快,所以换了curl的下载方式,速度正常 function file_upload($ftpIp,$ftpUser,$ftpPwd,$path,$fileSavePath){ $curlobj = curl_init();//初始化 //传入ftp的目标文件,如'ftp://192.168.3.1/test/1.jpg' curl_set

  • Android编程使用WebView实现文件下载功能的两种方法

    本文实例讲述了Android编程使用WebView实现文件下载功能的两种方法.分享给大家供大家参考,具体如下: 在应用中,通常会使用到文件下载功能,一般我们都是写一个下载操作工具类,在异步任务中执行下载功能. 今天我们来看下如何使用WebView的文件下载功能! 方法1,自定义下载操作 1. 先来布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&qu

随机推荐