文件下载理解: 将服务器端资源以流的形式写入到浏览器中
1.通过超链接下载
注意: 如果浏览器可以解析,则会直接在浏览器中打开。例如,在chrome可以直接解析 图片 和 pdf 文件,就不会弹出下载窗口
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = getServletContext().getRealPath("/WEB-INF/classes/秋瓷炫.jpg");
int index = path.lastIndexOf("\\");
String name = path.substring(index+1);
InputStream is = new FileInputStream(path);
ServletOutputStream outputStream = resp.getOutputStream();
int len = 0;
byte[] bys = new byte[1024];
while((len=is.read(bys))!=-1){
outputStream.write(bys,0,len);
}
is.close();
outputStream.close();
}
}
2. 强制弹出下载窗口
在获取输出流之前加上:
response.setHeader("Content-Disposition", "attachment;filename="+filename);
文件名为中文时乱码处理
filename 如果是中文,会导致浏览器解析时乱码, 如下
解决办法:
方法一:
拿到浏览器请求的usreAgent,判断是否包含MSIE, 如果有,URLEncode(filename,"GBK")
没有的话,URLEncoder.encode(filename)
String agent = req.getHeader("User-Agent");
System.out.println(agent);
if(agent.indexOf("MSIE")!=-1){
name =URLEncoder.encode(name,"GBK");
}else{
name=URLEncoder.encode(name,"UTF-8");
}
resp.setHeader("Content-Disposition", "attachment;filename="+name);
方法二:
拿到浏览器请求的usreAgent,判断是否包含MSIE,则将文件名以 gbk 编码(getBytes("GBK")) , 不包含MSIE则以 “UTF-8”编码(getBytes("UTF-8"))
然后将bytes使用ISO-8859-1解码转换为字符串,返回到浏览器。各浏览器基本都支持ISO编码
转换过程
中文 -> UTF-8 编码 ->二进制-> ISO-8859-1编码->发送到客户端 -> 客户端 将字符串 以ISO8859-1 编码->二进制-> 再以UTF-8 解码
String userAgent = request.getHeader("User-Agent");
// name.getBytes("UTF-8")处理safari的乱码问题
byte[] bytes = userAgent.contains("MSIE") ? name.getBytes("GBK") : name.getBytes("UTF-8");
// 各浏览器基本都支持ISO编码
name = new String(bytes, "ISO-8859-1");
// 文件名外的双引号处理firefox的空格截断问题
response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", name));