文件下载
情景:在一些网络系统中,需要隐藏下载文件的真实地址,或者下载的文件需要一个程序来动态的确定后在传送给客户端。
方案:利用程序编码实现下载
作用:可以增加安全访问控制,只对经过授权认证的用户提供下载,可以从任意位置提供下载的数据。
利用程序实现下载需要设置 2 个报头:
Web 服务器需要告诉浏览器其所输出的内容的类型不是普通的文本文件或 HTML 文件,而是一个要保存到本地的下载文件。设置Content-Type 的值为:application/x-msdownload.
Exp: response.setContentType("application/x-msdownload");
Or response.setHeader("content-type", "application/x-msdownload");
Web 服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置Content-Disposition 报头。该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在 attachment 后面还可以指定 filename 参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。在设置 Content-Dispostion 之前一定要指定 Content-Type.
Exp: response.setHeader("Content-Disposition", "attachment; filename=a.jpg");
因为要下载的文件可以是各种类型的文件,所以要将文件传送给客户端,其相应内容应该被当做二进制来处理,所以应该调用方法返回 ServeltOutputStream 对象来向客户端写入文件内容。
Exp:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String filename = request.getParameter("filename");
System.out.println(filename);
if (filename != null && !"".equals(filename)) {
// 文件下载需要设置响应头信息
// 告诉浏览器这是一个下载文件
response.setContentType("application/x-msdownload");
// 设置web浏览器不直接处理文件内容,并提供一个文件建议名称,注意文件名称的编码避免出现中文乱码
response.setHeader("Content-Disposition", "attachment; filename="
+ new String(filename.getBytes("utf-8"), "iso-8859-1"));
// 获取需要下载的文件
File file = new File(this.getServletContext().getRealPath(
"/WEB-INF/upload/" + filename));
if (file.exists()) {
// 获取输出流,将文件写出到客户端
OutputStream os = response.getOutputStream();
// 将下载文件读入
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[1024];
while (fis.read(b) != -1) {
os.write(b);
}
fis.close();
os.flush();
os.close();
}
}
}
关于中文文件名的下载,需要在设置文件名时进行编码。编码的两种方式
Exp:
(1)response.setHeader("Content-Disposition",
"attachment;filename="+new String(filename.getBytes("utf-8"),"ISO-8859-1"));
(2)response.setHeader("Content-Disposition",
"attachment;filename="+URLEncoder.encode("斯蒂芬", "utf-8")+".jpg");
|