web 应用常用功能文件下载(新思路)

文章目录

web 应用常用功能文件下载

文件下载的原理分析图

● 文件下载原理分析图

代码应用实例

● 需求:演示文件下载,如图

download.jsp

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件下载</title>
    <base href="<%=request.getContextPath()+"/"%>>">
</head>
<body>
<h1>文件下载</h1>
<a href="fileDownLoadServlet?name=1.jpg">点击下载小狗图片</a><br/><br/>
<a href="fileDownLoadServlet?name==笔记.pdf">点击下载Java笔记.pdf</a><br/><br/>
<a href="fileDownLoadServlet?name=高山流水.mp3">点击下载 高山流水.mp3</a><br/><br/>
</body>
</html>

FileDownloadServlet

  1. 先准备要下载的文件[假定这些文件是公共的资源]

    重要: 保证当我们的tomcat启动后,在工作目录out下有download文件夹, 并且有可供下载的文件!!

    再次说明,如果你没有看到你创建的download在工作目录out下 rebuild project -> restart, 就OK

  2. 获取到要下载的文件的名字

  3. 给http响应,设置响应头 Content-Type , 就是文件的MIME

    通过servletContext 来获取

  4. 给http响应,设置响应头 Content-Disposition

    这里考虑的细节比较多,比如不同的浏览器写法不一样,考虑编码

    ff 是 文件名中文需要 base64, 而 ie/chrome 是 URL编码 只需知道原理

(1)如果是Firefox 则中文编码需要 base64

(2)Content-Disposition 是指定下载的数据的展示形式 , 如果attachment 则使用文件下载方式

(3)如果是其他(主流ie/chrome) 中文编码使用URL编码

  1. 读取下载的文件数据,返回给客户端/浏览器

(1) 创建一个和要下载的文件,关联的输入流

(2) 得到返回数据的输出流

(3) 使用工具类,将输入流关联的文件,对拷到输出流,并返回给客户端/浏览器

java 复制代码
import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

public class FileDownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("FileDownloadServlet 被调用...");
        //1. 先准备要下载的文件[假定这些文件是公共的资源]
        //   重要: 保证当我们的tomcat启动后,在工作目录out下有download文件夹, 并且有可供下载的文件!!
        //   再次说明,如果你没有看到你创建的download在工作目录out下 rebuild project -> restart, 就OK

        //2. 获取到要下载的文件的名字
        request.setCharacterEncoding("utf-8");
        String downLoadFileName = request.getParameter("name");
        //System.out.println("downLoadFileName= " + downLoadFileName);

        //3. 给http响应,设置响应头 Content-Type , 就是文件的MIME
        //   通过servletContext 来获取
        ServletContext servletContext = request.getServletContext();
        String downLoadPath = "/download/"; //下载目录从 web工程根目录计算 /download/1.jpg
        String downLoadFileFullPath = downLoadPath + downLoadFileName;
        String mimeType = servletContext.getMimeType(downLoadFileFullPath);
        System.out.println("mimeType= " + mimeType);
        response.setContentType(mimeType);

        //4. 给http响应,设置响应头 Content-Disposition
        //   这里考虑的细节比较多,比如不同的浏览器写法不一样,考虑编码
        //   ff 是 文件名中文需要 base64, 而 ie/chrome 是 URL编码
        //   只需知道原理
        //   解读
        //(1)如果是Firefox 则中文编码需要 base64
        //(2)Content-Disposition 是指定下载的数据的展示形式 , 如果attachment 则使用文件下载方式
        //(3)如果是其他(主流ie/chrome) 中文编码使用URL编码
        if (request.getHeader("User-Agent").contains("Firefox")) {
            // 火狐 Base64编码
            response.setHeader("Content-Disposition", "attachment; filename==?UTF-8?B?" +
                    new BASE64Encoder().encode(downLoadFileName.getBytes("UTF-8")) + "?=");
        } else {
            // 其他(主流ie/chrome)使用URL编码操作
            response.setHeader("Content-Disposition", "attachment; filename=" +
                    URLEncoder.encode(downLoadFileName, "UTF-8"));
        }

        //5. 读取下载的文件数据,返回给客户端/浏览器
        //(1) 创建一个和要下载的文件,关联的输入流
        InputStream resourceAsStream =
                servletContext.getResourceAsStream(downLoadFileFullPath);
        //(2) 得到返回数据的输出流 [因为返回文件大多数是二进制(字节), IO java基础]
        ServletOutputStream outputStream = response.getOutputStream();

        //(3) 使用工具类,将输入流关联的文件,对拷到输出流,并返回给客户端/浏览器
        IOUtils.copy(resourceAsStream, outputStream);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

总结

  1. 文件下载,比较麻烦的就是文件名中文处理

  2. 因此,在代码中,针对不同浏览器做了处理

  3. 对于网站的文件,很多文件使用另存为即可下载,对于大文件(文档,视频),会使用专业的下载工具(迅雷、百度,腾讯,华为网盘等)

  4. 对于不同的浏览器, 在把文件下载完毕后,处理的方式不一样, 有些是直接打开文件,有些是将文件下载到 本地/下载目

相关推荐
毕设十刻9 小时前
基于Vue的养老服务平台85123(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
青衫折扇9 小时前
执行 npm 安装命令时,包被装到了 C 盘用户目录下,而非项目根目录
前端·npm·node.js
XiaoYu20029 小时前
第2章 Nest.js入门
前端·ai编程·nestjs
2501_946244789 小时前
Flutter & OpenHarmony OA系统下拉刷新组件开发指南
开发语言·javascript·flutter
没事多睡觉6669 小时前
零基础React + TypeScript 教程
前端·react.js·typescript
liliangcsdn9 小时前
MySQL存储字节类数据的方案示例
java·前端·数据库
_Kayo_9 小时前
React useState setState之后获取到的数据一直是初始值
前端·javascript·react.js
谷哥的小弟9 小时前
HTML5新手练习项目—生命体征监测(附源码)
前端·源码·html5·项目
黎明初时9 小时前
react基础框架搭建3-配置 Redux:react+router+redux+axios+Tailwind+webpack
前端·react.js·webpack
yang9yun9 小时前
PostMan加载三方JS
javascript·测试工具·postman