zoukankan      html  css  js  c++  java
  • 2.6学习总结 之 文件下载

    一、说在前面

    昨天 数据库非一般操作总结
    今天 学习文件下载相关知识

    二、问题:

    1、什么情况下回文件下载?

    1)操作实践

     

     2)分析:使用a标签直接指向服务器上的资源,浏览器能解析的文件就直接解析,浏览器不能解析的文件才下载。

    3)总结:浏览器不能解析的文件就下载。

    2、什么情况下需要在服务器端编写文件下载代码?

    1)理论上,浏览器能解析的文件就编写文件下载代码。

    2)实际中,只要是需要下载的文件都编写文件下载代码。(浏览器不断更新,维护代码麻烦)

    三、文件下载的实现

    1、相关知识:

    文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需 IO技术将服务器端的文件使用InputStream读取到,在使用 ServletOutputStream写到response缓冲区中

    2、要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型 

    1)mime实质Tomcatconf下的web.xml将文件后缀名映射为mime

     2)代码获取文件的mime

    response.setContentType(this.getServletContext().getMimeType(filename));

    3、告示浏览器文件的打开方式是下载:

    response.setHeader("Content-Disposition","attachment;filename=文件名称");

    4、文件下载的代码

    1)前台页面

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <h1>1、使用a标签直接指向服务器上的资源</h1>
        <a href="download/a.flv">a.flv</a><br>
        <a href="download/a.jpg">a.jpg</a><br>
        <a href="download/a.mp3">a.mp3</a><br>
        <a href="download/a.mp4">a.mp4</a><br>
        <a href="download/a.txt">a.txt</a><br>
        <a href="download/a.zip">a.zip</a><br>
        <h1>2、使用服务器端编码的方式实现文件下载</h1>
        <a href="downloadServlet?filename=a.flv">a.flv</a><br>
        <a href="downloadServlet?filename=a.jpg">a.jpg</a><br>
        <a href="downloadServlet?filename=a.mp3">a.mp3</a><br>
        <a href="downloadServlet?filename=a.mp4">a.mp4</a><br>
        <a href="downloadServlet?filename=a.txt">a.txt</a><br>
        <a href="downloadServlet?filename=a.zip">a.zip</a><br>
    </body>
    </html>

    2)后台servlet

    package com.me.servlet;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    @WebServlet("/downloadServlet")
    public class DownloadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        public DownloadServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 获得要下载的文件的名称
            String filename = request.getParameter("filename");// a.flv
    
            // 要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
            response.setContentType(this.getServletContext().getMimeType(filename));
            // 告诉客户端该文件不是直接解析 而是以附件形式打开(下载)
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
    
            // 获取文件的绝对路径
            String path = this.getServletContext().getRealPath("download/" + filename);
            // 获得该文件的输入流
            InputStream in = new FileInputStream(path);
            // 获得输出流---通过response获得的输出流 用于向客户端写内容
            ServletOutputStream out = response.getOutputStream();
            // 文件拷贝的模板代码
            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
    
            in.close();
            // out.close();
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }

    3)测试

     4、中文乱码问题

    但是,如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况, 原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐 浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题,解决浏览器兼容 性问题的首要任务是要辨别访问者是ie还是火狐(其他),通过Http请求体中的一 个属性可以辨别

    解决乱码方法如下(不要记忆--了解):

    if (agent.contains("MSIE")) {
    
    // IE浏览器
    
    filename = URLEncoder.encode(filename, "utf-8");
    
    filename = filename.replace("+", " ");
    
    } else if (agent.contains("Firefox")) {
    
    // 火狐浏览器
    
    BASE64Encoder base64Encoder = new BASE64Encoder();
    
    filename = "=?utf-8?B?"
    
    + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
    
    } else {
    
    // 其它浏览器
    
    filename = URLEncoder.encode(filename, "utf-8");
    
    }

    其中agent就是请求头User-Agent的值

  • 相关阅读:
    Django测试开发-4-django3.0.3报错:/mysql ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3
    Django测试开发-3-新建一个Django工程
    Django测试开发-2-创建虚拟环境
    Django测试开发-1-MVC/MVT的概念
    sqlserver中复合索引和include索引到底有多大区别?
    PLSQL开发笔记和小结(转载)
    PL/sql语法单元
    jquery 获取下拉框值与select text
    jquery 事件
    jquery dom操作
  • 原文地址:https://www.cnblogs.com/20183544-wangzhengshuai/p/12267851.html
Copyright © 2011-2022 走看看