<%! /** * If returns true, then should return a 304 (HTTP_NOT_MODIFIED) */ publicstaticboolean checkFor304( HttpServletRequest req, File file ) { // // We'll do some handling for CONDITIONAL GET (and return a 304) // If the client has set the following headers, do not try for a 304. // // pragma: no-cache // cache-control: no-cache // if( "no-cache".equalsIgnoreCase(req.getHeader("Pragma")) ||"no-cache".equalsIgnoreCase(req.getHeader("cache-control"))) { // Wants specifically a fresh copy } else { // // HTTP 1.1 ETags go first // String thisTag = Long.toString(file.lastModified());
// 清空缓冲区, 防止页面中的空行, 空格添加到要下载的文件内容中去 // 如果不清空的话在调用 response.reset() 的时候 Tomcat 会报错 // java.lang.IllegalStateException: getOutputStream() has already been called for // this response, out.clear();
// {{{ BEA Weblogic 必读 // 修正 Bea Weblogic 出现 "getOutputStream() has already been called for this response"错误的问题 // 关于文件下载时采用文件流输出的方式处理: // 加上response.reset(),并且所有的%>后面不要换行,包括最后一个; // 因为Application Server在处理编译jsp时对于%>和<%之间的内容一般是原样输出,而且默认是PrintWriter, // 而你却要进行流输出:ServletOutputStream,这样做相当于试图在Servlet中使用两种输出机制, // 就会发生:getOutputStream() has already been called for this response的错误 // 详细请见《More Java Pitfill》一书的第二部分 Web层Item 33:试图在Servlet中使用两种输出机制 270 // 而且如果有换行,对于文本文件没有什么问题,但是对于其它格式,比如AutoCAD、Word、Excel等文件 //下载下来的文件中就会多出一些换行符0x0d和0x0a,这样可能导致某些格式的文件无法打开,有些也可以正常打开。 // 同时这种方式也能清空缓冲区, 防止页面中的空行等输出到下载内容里去 response.reset(); // }}} try { java.io.File f =new java.io.File(filePath); if (f.exists() && f.canRead()) { // 我们要检查客户端的缓存中是否已经有了此文件的最新版本, 这时候就告诉 // 客户端无需重新下载了, 当然如果不想检查也没有关系 if( checkFor304( request, f ) ) { // 客户端已经有了最新版本, 返回 304 response.sendError( HttpServletResponse.SC_NOT_MODIFIED ); return; }