文件下载(下载文件名乱码解决方法)
1. 下载就是向客户端响应字节数据!
原来我们响应的都是html的字符数据!
把一个文件变成字节数组,使用response.getOutputStream()来各应给浏览器!!!
2. 下载的要求
* 两个头一个流!
> Content-Type:你传递给客户端的文件是什么MIME类型,例如:image/pjpeg
* 通过文件名称调用ServletContext的getMimeType()方法,得到MIME类型!
> Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开!attachment;filename=xxx
* 在filename=后面跟随的是显示在下载框中的文件名称!
> 流:要下载的文件数据!
* 自己new一个输入流即可!
3、下载的细节
显示在下载框中的中文名称时,会出现乱码。
* FireFox:Base64编码。
*Safari:ISO8859-1编码
* 其他大部分浏览器:URL编码。
通用方案:
1 public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException { 2 String agent = request.getHeader("User-Agent"); //获取浏览器 3 if (agent.contains("Firefox")) { 4 BASE64Encoder base64Encoder = new BASE64Encoder(); 5 filename = "=?utf-8?B?" 6 + base64Encoder.encode(filename.getBytes("utf-8")) 7 + "?="; 8 } else if(agent.contains("MSIE")) { 9 filename = URLEncoder.encode(filename, "utf-8"); 10 } else if(agent.contains ("Safari")) { 11 filename = new String (filename.getBytes ("utf-8"),"ISO8859-1"); 12 } else { 13 filename = URLEncoder.encode(filename, "utf-8"); 14 } 15 return filename; 16 }
4、演示:
1 package web.servlet; 2 3 import org.apache.commons.io.IOUtils; 4 import sun.misc.BASE64Encoder; 5 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 import java.net.URLEncoder; 15 16 @WebServlet(name = "Download1Servlet",urlPatterns = "/Download1Servlet") 17 public class Download1Servlet extends HttpServlet { 18 public void doGet(HttpServletRequest request, HttpServletResponse response) 19 throws ServletException, IOException { 20 /* 21 * 两个头一个流 22 * 1、Content-Type 23 * 2、Content-Disposition 24 * 3、流:下载文件的数据 25 * */ 26 String filename = "/Users/Shared/薛之谦-一半.mp3"; 27 String framename = filenameEncoding("薛之谦-一半.mp3",request); 28 String contentType = this.getServletContext() 29 .getMimeType(filename);//通过文件名获取MIME类型 30 String contentDisposition = "attachment;filename="+framename; 31 //一个流 32 FileInputStream input = new FileInputStream("/Users/Shared/薛之谦-一半.mp3"); 33 //设置头 34 response.setHeader("content-Type",contentType); 35 response.setHeader("content-Disposition",contentDisposition); 36 //获取绑定了响应端的流 37 ServletOutputStream output = response.getOutputStream(); 38 IOUtils.copy(input,output);//把输出流中的数据写入到输出流中 39 input.close(); 40 } 41 public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException { 42 String agent = request.getHeader("User-Agent"); //获取浏览器 43 if (agent.contains("Firefox")) { 44 BASE64Encoder base64Encoder = new BASE64Encoder(); 45 filename = "=?utf-8?B?" 46 + base64Encoder.encode(filename.getBytes("utf-8")) 47 + "?="; 48 } else if(agent.contains("MSIE")) { 49 filename = URLEncoder.encode(filename, "utf-8"); 50 } else if(agent.contains ("Safari")) { 51 filename = new String (filename.getBytes ("utf-8"),"ISO8859-1"); 52 } else { 53 filename = URLEncoder.encode(filename, "utf-8"); 54 } 55 return filename; 56 } 57 }