
文件下载需求:
1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载


分析:
1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,
如果不能解析,则弹出下载提示框。不满足需求。
2. 任何资源都必须弹出下载提示框。
3. 使用响应头设置资源的打开方式:
    *content-disposition:attename;filename=xxx;
步骤
1.  定义页面,编辑超链接href属性,属性值指向Servlet,
    传递资源名称filename
2.  定义Servlet
    1. 获取文件的名称
    2. 使用字节输入流去加载文件进去内存(涉及真实路径)
    3. 指定response响应头:
        *content-disposition:attename;filename=xxx;
    4. 将数据写出到response输出流即可
问题
中文文件名的问题
解决思路:
1. 获取客户端浏览器使用的版本信息
2. 根据不同的版本信息,我们设置filename的编码方式不同
代码
结构

DownloadServlet
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 
 | package com.web.download;
 import com.web.utils.DownLoadUtils;
 
 import javax.servlet.ServletContext;
 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;
 import java.io.FileInputStream;
 import java.io.IOException;
 
 @WebServlet(urlPatterns = "/downLoad")
 public class DownloadServlet extends HttpServlet {
 @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
 
 String filename = request.getParameter("filename");
 
 
 
 ServletContext servletContext = this.getServletContext();
 String realPath = servletContext.getRealPath("/img/"+filename);
 
 FileInputStream fis = new FileInputStream(realPath);
 
 
 
 
 
 String mimeType = servletContext.getMimeType(filename);
 response.setHeader("content-type",mimeType);
 
 
 
 String agent = request.getHeader("user-agent");
 
 
 filename = DownLoadUtils.getFileName(agent, filename);
 response.setHeader("content-disposition","attachment;filename="+filename);
 
 
 ServletOutputStream sos = response.getOutputStream();
 byte[] buff = new byte[1024*8];
 int len = 0;
 while((len=fis.read(buff))!=-1){
 sos.write(buff,0,len);
 }
 fis.close();
 }
 
 
 
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 this.doPost(request,response);
 }
 }
 
 | 
中文编码类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | package com.web.utils;
 import sun.misc.BASE64Encoder;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 
 
 public class DownLoadUtils {
 
 public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
 if (agent.contains("MSIE")) {
 
 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");
 }
 return filename;
 }
 }
 
 | 
下载HTML页面
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | <!DOCTYPE html><html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>下载</title>
 </head>
 <body>
 
 <a href="/3_response_war_exploded/img/1.jpg">图片1</a>
 <a href="/3_response_war_exploded/img/2.jpg">图片2</a>
 
 <hr/>
 
 <a href="/3_response_war_exploded/downLoad?filename=1.jpg">图片1</a>
 <a href="/3_response_war_exploded/downLoad?filename=九尾.jpg">图片1(中文)</a>
 <a href="/3_response_war_exploded/downLoad?filename=2.jpg">图片2</a>
 </body>
 </html>
 
 |