博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]【HttpServlet】HttpServletResponse接口 案例:完成文件下载
阅读量:4649 次
发布时间:2019-06-09

本文共 4831 字,大约阅读时间需要 16 分钟。

创建时间: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页面里怎么改

转载于:https://www.cnblogs.com/musecho/p/11202097.html

你可能感兴趣的文章