[转]【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页面里怎么改

猜你喜欢

转载自www.cnblogs.com/musecho/p/11202097.html
今日推荐