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的值

原文地址:https://www.cnblogs.com/20183544-wangzhengshuai/p/12267851.html