1.引言
像图片或者HTML这类【静态资源】,只要在浏览器中打开正确的网址,就可以下载,只要资源放在应用程序目录或者其子目录中,但不在WEB_INF下,Servlet/JSP容器就会将其资源发送到浏览器;但是,有的时候,静态资源被保存在应用程序目录之外,或者是保存在数据库中,或者有时候,你需要控制让某些人能够看到资源,同时又要防止其它网站跨站引用,遇到这种情况,必须通过编程来发送资源;
总之,通过编程实现的文件下载让你有选择地将某一个文件发送到浏览器;
2.概述
为了将资源发送到浏览器,需要Servlet中完成以下工作,一般不用JSP页面,因为发送的是二进制代码,浏览器上不会显示这些内容;
2.1将响应的内容类型设置为文件的内容类型。表头Content-Type用来规定实体主体中的数据类型,包含媒体类型和子类型标识符;关于标准内容类型,可以查[看这里](http://www.iana.org/assignments/media-types),如果你不了解什么是内容类型,或者希望浏览器总是显示为另存为(Save as)对话框,那么就将它设为APPLICATION/OCTET-STREAM。这个值不区分大小写。
2.2添加一个名为Content-Disposition的Http响应标头,给它赋值为attachment;filename=filename,这里的fileName是指在文件下载(File Download)对话框中显示出来的默认文件名,它通常与文件名相同,但是也可以不同;
下面,就是一个将文件发送到浏览器的代码规范:
FileInputStream fis = new FileInputStream(file);//文件数据流
BufferedInputStream bis = new BufferedInputStream(fis);//把文件流放入buffered流中
byte [] bytes= new byte[bis.available];//创建一个bytes数组;
response.setContentType(contentType);//设置请求内容类型标头
OutputStream os = response.getOutputStream();//请求内容变为输出流
bis.read(bytes);//bis读取字节流
os.write(bytes);//os书写字节流
如果想要将一个文件中的部分内容通过编程的方式发送到浏览器,那么首先要将该文件当成是一个FileInputStream,并将内容添加到一个字符数组中。然后,获取HttpServletResponse的OutputStream,并且调用write方法时,传递字节数组给它;
警告:
一定要确保你没有无意中发送超过实际文件内容以外的任何字符;这有可能在你毫无不知情的情况下发生,例如,如果在JSP页面使用page指令,可以这么写:
<%@ page import="java.io.FileInputStream"%>
<jsp:useBean id="DBBeanId" scope="page" class="MyBean"/>
在你毫不察觉的情况下,page指令后面的回车换行符就会被发送给浏览器,为了防止发送多余的字符,需要像下面一样编辑这个指令:
<%@ page import="java.io.FileInputStream"
%><jsp:useBean id="DBBeanId" scope="page" class="Mybean"/>
这些代码看起来不太常见,但是很有帮助;