zoukankan      html  css  js  c++  java
  • 03010_案例:完成文件下载

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

      浏览器不能解析的文件就下载;

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

      (1)理论上,浏览器可以解析的代码需要编写文件下载代码;

      (2)实际开发中,只要是下载文件都编写文件下载代码。

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

    4、需要设置两个响应头,告知浏览器文件的类型和文件的打开方式

      (1)告知浏览器文件的类型:response.setContentType(文件的MIME类型); ;

      (2)告示浏览器文件的打开方式是下载

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

      (3)download.html

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="UTF-8">
     5 <title>Insert title here</title>
     6 </head>
     7 <body>
     8     <h1>使用服务器端编码的方式实现文件下载</h1>
     9     <a href="/WEB13/downloadServlet?filename=a.flv">a.flv</a>
    10     <br />
    11     <a href="/WEB13/downloadServlet?filename=a.jpg">a.jpg</a>
    12     <br />
    13     <a href="/WEB13/downloadServlet?filename=a.mp3">a.mp3</a>
    14     <br />
    15     <a href="/WEB13/downloadServlet?filename=a.mp4">a.mp4</a>
    16     <br />
    17     <a href="/WEB13/downloadServlet?filename=a.txt">a.txt</a>
    18     <br />
    19     <a href="/WEB13/downloadServlet?filename=a.zip">a.zip</a>
    20     <br />
    21 </body>
    22 </html>

      (4)DownloadServlet.java

     1 package com.gzdlh.contex;
     2 
     3 import java.io.FileInputStream;
     4 import java.io.IOException;
     5 import java.io.InputStream;
     6 
     7 import javax.servlet.ServletException;
     8 import javax.servlet.ServletOutputStream;
     9 import javax.servlet.http.HttpServlet;
    10 import javax.servlet.http.HttpServletRequest;
    11 import javax.servlet.http.HttpServletResponse;
    12 
    13 public class DownloadServlet extends HttpServlet {
    14 
    15     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16         // 获得要下载的文件的名称
    17         String filename = request.getParameter("filename");
    18 
    19         // 要下载的这个文件的类型---客户端通过文件的MIME类型取区分类型
    20         response.setContentType(this.getServletContext().getMimeType(filename));
    21 
    22         // 告诉客户端,该文件不是直接解析,而是以附件形式打开(下载)
    23         response.setHeader("Content-Disposition", "attachment;filename=" + filename);
    24 
    25         // 获取文件的绝对路径
    26         String path = this.getServletContext().getRealPath("download/" + filename);
    27 
    28         // 获得该文件的输入流
    29         InputStream in = new FileInputStream(path);
    30 
    31         // 获得输出流---通过response获得的输出流,用于向客户端写内容
    32         ServletOutputStream out = response.getOutputStream();
    33 
    34         // 文件拷贝的模板代码
    35         int len = 0;
    36         byte[] buffer = new byte[1024];
    37         while ((len = in.read(buffer)) > 0) {
    38             out.write(buffer, 0, len);
    39         }
    40         in.close();
    41         out.close();
    42     }
    43 
    44     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    45         doGet(request, response);
    46     }
    47 }

    5、文件下载的文件名中文乱码

     1 if (agent.contains("MSIE")) {
     2         // IE浏览器
     3         filename = URLEncoder.encode(filename, "utf-8");
     4         filename = filename.replace("+", " ");
     5 } else if (agent.contains("Firefox")) {
     6         // 火狐浏览器
     7 BASE64Encoder base64Encoder = new BASE64Encoder();
     8         filename = "=?utf-8?B?"
     9                 + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
    10 } else {
    11         // 其它浏览器
    12         filename = URLEncoder.encode(filename, "utf-8");                
    13 }
    14 
    15 其中agent就是请求头User-Agent的值

      如,  

    <a href="/WEB13/downLoadServlet2?filename=美女.jpg">美女.jpg</a>

      DownLoadServlet2.java

     1 package com.gzdlh.contex;
     2 
     3 import java.io.FileInputStream;
     4 import java.io.IOException;
     5 import java.io.InputStream;
     6 import java.net.URLEncoder;
     7 
     8 import javax.servlet.ServletException;
     9 import javax.servlet.ServletOutputStream;
    10 import javax.servlet.http.HttpServlet;
    11 import javax.servlet.http.HttpServletRequest;
    12 import javax.servlet.http.HttpServletResponse;
    13 
    14 import sun.misc.BASE64Encoder;
    15 
    16 public class DownLoadServlet2 extends HttpServlet {
    17 
    18     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    19 
    20         // 文件名是中文名
    21 
    22         // 获得要下载的文件的名称
    23         String filename = request.getParameter("filename");// ???.jpg
    24         // 解决获得中文参数的乱码
    25         filename = new String(filename.getBytes("ISO8859-1"), "UTF-8");// 美女.jpg
    26 
    27         // 获得请求头中的User-Agent
    28         String agent = request.getHeader("user-Agent");
    29 
    30         // 根据就不同浏览器进行不同的编码
    31         String filenameEncoder = "";
    32         if (agent.contains("MSIE")) {
    33             // IE浏览器
    34             filenameEncoder = URLEncoder.encode(filename, "utf-8");
    35             filenameEncoder = filenameEncoder.replace("+", " ");
    36         } else if (agent.contains("Firefox")) {
    37             // 火狐浏览器
    38             BASE64Encoder base64Encoder = new BASE64Encoder();
    39             filenameEncoder = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
    40         } else {
    41             // 其它浏览器
    42             filenameEncoder = URLEncoder.encode(filename, "utf-8");
    43         }
    44 
    45         // 要下载的这个文件的类型---客户端通过文件的MIME类型取区分类型
    46         response.setContentType(this.getServletContext().getMimeType(filename));
    47 
    48         // 告诉客户端,该文件不是直接解析,而是以附件形式打开(下载)------filename="+filename 客户端默认对名字进行解码
    49         response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoder);
    50 
    51         // 获取文件的绝对路径
    52         String path = this.getServletContext().getRealPath("download/" + filename);
    53 
    54         // 获得该文件的输入流
    55         InputStream in = new FileInputStream(path);
    56 
    57         // 获得输出流---通过response获得的输出流,用于向客户端写内容
    58         ServletOutputStream out = response.getOutputStream();
    59 
    60         // 文件拷贝的模板代码
    61         int len = 0;
    62         byte[] buffer = new byte[1024];
    63         while ((len = in.read(buffer)) > 0) {
    64             out.write(buffer, 0, len);
    65         }
    66         in.close();
    67         out.close();
    68     }
    69 
    70     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    71         doGet(request, response);
    72     }
    73 }

      运行结果:

      

    6、response细节点

      (1)response获得的流不需要手动关闭,Tomcat容器会帮助我们关闭;

      (2)getWriter和getOutputStream不能同时调用。

      

      

  • 相关阅读:
    Mysql的join语句
    Excel的VLOOKUP函数
    python求极值点(波峰波谷)
    python多项式拟合:np.polyfit 和 np.polyld
    hdfs显示、查看、下载、上传、删除文件操作
    pip备份、安装requirements.txt中的包和anaconda的安装(linux)
    spark-submit提交任务到集群,分发虚拟环境和第三方包
    VLAN实验3:理解Hybrid接口的应用
    VLAN实验2:配置Trunk接口
    WLAN实验1:划分不同VLAN及Acess配置
  • 原文地址:https://www.cnblogs.com/gzdlh/p/8203077.html
Copyright © 2011-2022 走看看