JavaWeb15.5【response:案例-文件下载】
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <!--<a href="/day15/img/1.jpg">图片</a> 9 <a href="/day15/img/1.avi">视频</a> 10 <hr> 11 <a href="/day15/downloadServlet?filename=1.jpg">图片</a> 12 <a href="/day15/downloadServlet?filename=1.avi">视频</a>--> 13 14 <a href="/day15/downloadServlet?filename=九尾.jpg">图片</a> 15 </body> 16 </html>
1 package com.haifei.download; 2 3 import com.haifei.util.DownLoadUtils; 4 5 import javax.servlet.ServletContext; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletOutputStream; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.FileInputStream; 13 import java.io.IOException; 14 15 /** 16 * 案例-文件下载 17 * 1. 获取文件名称 18 * 2. 使用字节输入流加载文件进内存 19 * 3. 指定response的响应头: content-disposition:attachment;filename=xxx 20 * 4. 将数据写出到response输出流 21 * 22 * 中文文件问题 23 * * 解决思路: 24 * 1. 获取客户端使用的浏览器版本信息 25 * 2. 根据不同的版本信息,设置filename的编码方式不同 26 */ 27 @WebServlet("/downloadServlet") 28 public class DownloadServlet extends HttpServlet { 29 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 30 //1 获取请求参数,即文件名称 31 String filename = request.getParameter("filename"); 32 33 //2 使用字节输入流加载文件进内存 34 //2.1 找到文件所在服务器路径 35 ServletContext servletContext = this.getServletContext(); 36 String realPath = servletContext.getRealPath("/img/" + filename); 37 //2.2 用字节流关联 38 FileInputStream fis = new FileInputStream(realPath); 39 40 41 //3 设置response的响应头 42 //3.1 设置响应头类型content-type 43 String mimeType = servletContext.getMimeType(filename); //获取文件的MIME类型 44 response.setHeader("content-type", mimeType); 45 46 //--------------------------------------------------- 47 //解决中文文件名问题 48 //1 获取user-agent请求头 49 String agent = request.getHeader("user-agent"); 50 //2 使用工具类方法编码文件名 51 filename = DownLoadUtils.getFileName(agent, filename); 52 //--------------------------------------------------- 53 54 //3.2 设置响应头打开方式content-disposition 55 response.setHeader("content-disposition", "attachment;filename=" + filename); 56 57 58 //4 将输入流中的数据写出到输出流中 59 ServletOutputStream sos = response.getOutputStream(); 60 byte[] buff = new byte[1024 * 8]; //缓冲区 61 int len = 0; //读到的字节个数 62 while ((len = fis.read(buff)) != -1){ //=-1时读到文件末尾 63 sos.write(buff, 0, len); 64 //因为是字节流,所以此处不用手动刷新 65 } 66 fis.close(); //输出流不用关闭,输入流建议释放资源 67 } 68 69 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 70 this.doPost(request, response); 71 } 72 }
1 package com.haifei.util; 2 3 import sun.misc.BASE64Encoder; 4 import java.io.UnsupportedEncodingException; 5 import java.net.URLEncoder; 6 7 8 public class DownLoadUtils { 9 10 public static String getFileName(String agent, String filename) throws UnsupportedEncodingException { 11 if (agent.contains("MSIE")) { 12 // IE浏览器 13 filename = URLEncoder.encode(filename, "utf-8"); 14 filename = filename.replace("+", " "); 15 } else if (agent.contains("Firefox")) { 16 // 火狐浏览器 17 BASE64Encoder base64Encoder = new BASE64Encoder(); 18 filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; 19 } else { 20 // 其它浏览器 21 filename = URLEncoder.encode(filename, "utf-8"); 22 } 23 return filename; 24 } 25 }