下载就是向客户端响应字节数据,原来响应的都是html的字符数据,现在 把一个文件变成字节数组,使用response.getOutputStream()来各应给浏览器!
下载的要求
* 两个头一个流!
> Content-Type:你传递给客户端的文件是什么MIME类型,例如:image/pjpeg
* 通过文件名称调用ServletContext的getMimeType()方法,得到MIME类型!
> Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开!attachment;filename=xxx
* 在filename=后面跟随的是显示在下载框中的文件名称!
> 流:要下载的文件数据!
* 自己new一个输入流即可!
代码如下:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得请求文件名
String filename = request.getParameter("filename");
System.out.println(filename);
//设置文件的MIME类型
response.setContentType(this.getServletContext().getMimeType(filename));
//设置Content-Disposition
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//读取目标文件,通过response将目标文件写到客户端
//获取目标文件的绝对路径
String fullFileName = this.getServletContext().getRealPath("/upload/"+filename);
//读取文件
InputStream in = new FileInputStream(fullFileName);
OutputStream out = response.getOutputStream();
//写文件
int b;
while((b=in.read())!=-1){
out.write(b);
}
in.close();
out.close();
}
注意:下载的文件名称是中文的话,会在弹出的下载框出现乱码的情况。因为火狐浏览器使用的是base64编码方式,而其他部分浏览器则是URL编码。解决方法如下:
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;
}