• [转]【HttpServlet】HttpServletResponse接口 案例:完成文件下载


    创建时间:6.19 & 6.24

     

    1.案例-完成文件下载

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

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

    *使用a标签直接指向服务器上的资源

     

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

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

    实际开发中,只要是下载的文件都编写文件下载代码

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

    代码如下:

    上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上,而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方式。

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

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

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

    代码如下:

    *客户端不是根据文件扩展名来区分文件的类型,而是通过文件的MIME类型(在tomcat的web.xml中对extension进行MIME的映射)

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

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

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

     1 if (agent.contains("MSIE")) {
     2 
     3             // IE浏览器
     4 
     5             filename = URLEncoder.encode(filename, "utf-8");
     6 
     7             filename = filename.replace("+", " ");
     8 
     9 } else if (agent.contains("Firefox")) {
    10 
    11             // 火狐浏览器
    12 
    13 BASE64Encoder base64Encoder = new BASE64Encoder();
    14 
    15             filename = "=?utf-8?B?"
    16 
    17                       + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
    18 
    19 } else {
    20 
    21             // 其它浏览器
    22 
    23             filename = URLEncoder.encode(filename, "utf-8");                    
    24 
    25 }

    完整代码:见WEB14代码DownloadServlet2.java

      1 package com.itheima.content;
      2 
      3  
      4 
      5 import java.io.FileInputStream;
      6 
      7 import java.io.IOException;
      8 
      9 import java.io.InputStream;
     10 
     11 import java.net.URLEncoder;
     12 
     13  
     14 
     15 import javax.servlet.ServletException;
     16 
     17 import javax.servlet.ServletOutputStream;
     18 
     19 import javax.servlet.http.HttpServlet;
     20 
     21 import javax.servlet.http.HttpServletRequest;
     22 
     23 import javax.servlet.http.HttpServletResponse;
     24 
     25  
     26 
     27 import sun.misc.BASE64Encoder;
     28 
     29  
     30 
     31 public class DownLoadServlet2 extends HttpServlet {
     32 
     33  
     34 
     35       protected void doGet(HttpServletRequest request, HttpServletResponse response)
     36 
     37                   throws ServletException, IOException {
     38 
     39  
     40 
     41             //*******文件名称是中文的下载*******
     42 
     43  
     44 
     45  
     46 
     47             //获得要下载的文件的名称
     48 
     49             String filename = request.getParameter("filename");//????.jpg
     50 
     51             //解决获得中文参数的乱码----下节课讲
     52 
     53             filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg
     54 
     55  
     56 
     57            
     58 
     59             //获得请求头中的User-Agent
     60 
     61             String agent = request.getHeader("User-Agent");
     62 
     63             //根据不同浏览器进行不同的编码
     64 
     65             String filenameEncoder = "";
     66 
     67             if (agent.contains("MSIE")) {
     68 
     69                   // IE浏览器
     70 
     71                   filenameEncoder = URLEncoder.encode(filename, "utf-8");
     72 
     73                   filenameEncoder = filenameEncoder.replace("+", " ");
     74 
     75             } else if (agent.contains("Firefox")) {
     76 
     77                   // 火狐浏览器
     78 
     79                   BASE64Encoder base64Encoder = new BASE64Encoder();
     80 
     81                   filenameEncoder = "=?utf-8?B?"
     82 
     83                              + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
     84 
     85             } else {
     86 
     87                   // 其它浏览器
     88 
     89                   filenameEncoder = URLEncoder.encode(filename, "utf-8");                  
     90 
     91             }
     92 
     93  
     94 
     95  
     96 
     97  
     98 
     99             //要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
    100 
    101             response.setContentType(this.getServletContext().getMimeType(filename));
    102 
    103             //告诉客户端该文件不是直接解析 而是以附件形式打开(下载)----filename="+filename 客户端默认对名字进行解码
    104 
    105             response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);
    106 
    107  
    108 
    109             //获取文件的绝对路径
    110 
    111             String path = this.getServletContext().getRealPath("download/"+filename);
    112 
    113             //获得该文件的输入流
    114 
    115             InputStream in = new FileInputStream(path);
    116 
    117             //获得输出流---通过response获得的输出流 用于向客户端写内容
    118 
    119             ServletOutputStream out = response.getOutputStream();
    120 
    121             //文件拷贝的模板代码
    122 
    123             int len = 0;
    124 
    125             byte[] buffer = new byte[1024];
    126 
    127             while((len=in.read(buffer))>0){
    128 
    129                   out.write(buffer, 0, len);
    130 
    131             }
    132 
    133  
    134 
    135             in.close();
    136 
    137             //out.close();
    138 
    139  
    140 
    141       }
    142 
    143  
    144 
    145       protected void doPost(HttpServletRequest request, HttpServletResponse response)
    146 
    147                   throws ServletException, IOException {
    148 
    149             doGet(request, response);
    150 
    151       }
    152 
    153 }

    response细节点:

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

    2)getWritergetOutputStream不能同时调用

     

    验证码案例:不用掌握生成验证码,只要掌握html页面里怎么改

  • 相关阅读:
    Netty优雅退出
    使用FFmpeg切片HLS流
    Golang协程和线程区别
    00 PyTorch 开发环境搭建
    SpringBoot + LibreOffice + Hutool 实现附件预览简单示例
    css 注意事项 BFC
    css 伪类 属性选择器 优先级
    html img 标签图片格区别
    redis集群
    Redis RDB与AOF
  • 原文地址:https://www.cnblogs.com/musecho/p/11202097.html
Copyright © 2020-2023  润新知