1、文件下载
下载:向客户端响应字节数据。(原来响应的是html的字符数据)
做法:把一个文件变成字节数组,使用response.getOutputStream();来响应给浏览器
要求:两个头、一个流
Content-Type头:传递给客户端的MIME类型
使用 this.ServletContext.getMimeType("文件路径名")方法,得到MIME类型! 传参为文件路径名
Content-Disposition头:设置是否弹出下载框。
默认值为inline,表示在浏览器窗口打开
设置值为:attachment;filename=xxx; 表示弹出现在框
filename=后面跟随的是显示在下载框中的文件名称!
流:要下载的文件数据
new一个输入流即可
下载步骤:
1)得到两个头
Content-Type头:
使用 this.ServletContext.getMimeType("文件路径名")方法,得到MIME类型! 传参为文件路径名
Content-Disposition头 (设置为弹窗下载,弹窗中显示处理过编码的名称)
String contentDisposition = "attachment;filename="+framname;
2)得到数据流
FileInputStream input = new FileInputStream(filename);
3)将两个头设置给响应
response.setHeader("Content-Type", contentType);
response.setHeader("Content-Disposition", contentDisposition);
4)将流绑定客户端地址(流往到客户端)
ServletOutputStream output = response.getOutputStream();
5)把输入流中的数据写入到输出流中
IOUtils.copy(input, output);
下载细节
乱码问题:当下载框显示中文名称时,会出现乱码
FireFox:Base64编码
其他浏览器:URL编码。
通用解决方案:
filename = new String("需要处理的文件名".getBytes("GBK"),"IOS-8859-1");
上述方案存在个别特殊字符不能正确显示
解决:使用方法filenameEncoding
2、代码演示:
public class Download1Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 下载歌曲:
* 两个头、一个流
* 1.Content-Type
* 2.Content-Disposition
* 3.流:文件数据流
*/
//得到Content-Type头
//得到文件路径名
String filename = "C:/Users/11316/Music/思疆调.mp3";
//处理文件名乱码问题
// String newfilename = new String("思疆调.mp3".getBytes("GBK"),"ISO-8859-1");
String framname = filenameEncoding("思疆调.mp3",request);
//通过文件路径名称获取MIME类型
String contentType = this.getServletContext().getMimeType(filename);
//得到 Content-Disposition头 (设置为弹窗下载,弹窗中显示处理过编码的名称)
String contentDisposition = "attachment;filename="+framname;
//流 通过文件路径名的得到数据流
FileInputStream input = new FileInputStream(filename);
//为响应设置两个头: Content-Type、Content-Disposition
response.setHeader("Content-Type", contentType);
response.setHeader("Content-Disposition", contentDisposition);
//获取绑定了客户端的流(流往到客户端)
ServletOutputStream output = response.getOutputStream();
//把输入流中的数据写入到输出流中
IOUtils.copy(input, output);
//关闭流
input.close();
}
// 用来对下载的文件名称进行编码的! 根据不同浏览器不同编码处理
public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
String agent = request.getHeader("User-Agent"); //获取浏览器
if (agent.contains("Firefox")) {
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8"))
+ "?=";
} else if(agent.contains("MSIE")) {
filename = URLEncoder.encode(filename, "utf-8");
} else {
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
知识点: enctype属性