注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

JAVA咖啡屋

 
 
 

日志

 
 
关于我

秋天,叶子落了。秋风卷着落叶不知吹向何方,我在秋风中寻找着属于我的落叶。当我找到的时候,又不知该怎样将它留下。

网易考拉推荐

JAVA实现的Weblogic文件下载  

2009-05-12 11:55:59|  分类: 技术讨论 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

直接在JSP页面中进行文件下载的代码(改 Servlet 或者JavaBean 的话自己改吧), 支持中文附件名(做了转内码处理). 事实上只要向out 输出字节就被认为是附件内容, 不一定非要从文件读取原始数据, 从数据库中读取也可以的

测试结果:Tomcate5.0,5.5, Resin3.0, Weblogic 8.1,9.2 无异常产生

<%@ page contentType="text/html; charset=GBK" pageEncoding="GBK" %>
<%@ page import="java.io.*, java.util.*, java.text.*" %>
<%!

public static boolean 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());
            String eTag = req.getHeader( "If-None-Match" );
            if( eTag != null )
            {
                if( eTag.equals(thisTag) )
                {
                    return true;
                }
            }
            //
            //  Next, try if-modified-since
            //
            DateFormat rfcDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
            Date lastModified = new Date(file.lastModified());
            try
            {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                //log.info("ifModifiedSince:"+ifModifiedSince);
                if( ifModifiedSince != -1 )
                {
                    long lastModifiedTime = lastModified.getTime();
                    //log.info("lastModifiedTime:" + lastModifiedTime);
                    if( lastModifiedTime <= ifModifiedSince )
                    {
                        return true;
                    }
                }
                else
                {
                    try
                    {
                        String s = req.getHeader("If-Modified-Since");
                        if( s != null )
                        {
                            Date ifModifiedSinceDate = rfcDateFormat.parse(s);
                            //log.info("ifModifiedSinceDate:" + ifModifiedSinceDate);
                            if( lastModified.before(ifModifiedSinceDate) )
                            {
                                return true;
                            }
                        }
                    }
                    catch (ParseException e)
                    {
                        //log.warn(e.getLocalizedMessage(), e);
                    }
                }
            }
            catch( IllegalArgumentException e )
            {
                // Illegal date/time header format.
                // We fail quietly, and return false.
                // FIXME: Should really move to ETags.
            }
        }
        return false;
    }
%>
<%
 // String filePath = "c:/文档.doc";
 // 如果是 WEB APP 下的相对路径文件, 请使用下列代码:
 String filePath = application.getRealPath(path+"/"+newname);  
 boolean isInline = false;// 是否允许直接在浏览器内打开(如果浏览器能够预览此文件内容,
 // 那么文件将被打开, 否则会提示下载)
 // 清空缓冲区, 防止页面中的空行, 空格添加到要下载的文件内容中去
 // 如果不清空的话在调用 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;
            }
   // 从服务器的配置来读取文件的 contentType 并设置此contentType, 不推荐设置为
   // application/x-download, 因为有时候我们的客户可能会希望在浏览器里直接打开,
   // 如 Excel 报表, 而且 application/x-download 也不是一个标准的 mime type,
   // 似乎 FireFox 就不认识这种格式的 mime type
   String mimetype = null;
   mimetype = application.getMimeType( filePath );
   if( mimetype == null )
   {
       mimetype = "application/octet-stream;charset=ISO8859-1";
   }
   response.setContentType( mimetype );
   // IE 的话就只能用 IE 才认识的头才能下载 HTML 文件, 否则 IE 必定要打开此文件!
   String ua = request.getHeader("User-Agent");// 获取终端类型
   if(ua == null) ua = "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0;)";
   boolean isIE = ua.toLowerCase().indexOf("msie") != -1;// 是否为 IE
   if(isIE && !isInline) {
    mimetype = "application/x-msdownload";
   }
   // 下面我们将设法让客户端保存文件的时候显示正确的文件名, 具体就是将文件名
   // 转换为 ISO8859-1 编码
   String downFileName = new String(f.getName().getBytes(), "ISO8859-1");
   String inlineType = isInline ? "inline" : "attachment";// 是否内联附件
   // or using this, but this header might not supported by FireFox
   //response.setContentType("application/x-download");
   response.setHeader ("Content-Disposition", inlineType + ";filename=\""
   + downFileName + "\"");
   response.setContentLength((int) f.length());// 设置下载内容大小
         byte[] buffer = new byte[4096];// 缓冲区
         BufferedOutputStream output = null;
         BufferedInputStream input = null;
         //
         try {
             output = new BufferedOutputStream(response.getOutputStream());
             input = new BufferedInputStream(new FileInputStream(f));
             int n = (-1);
             while ((n = input.read(buffer, 0, 4096)) > -1) {
                 output.write(buffer, 0, n);
             }
             response.flushBuffer();
         }
         catch (Exception e) {
         } // 用户可能取消了下载
         finally {
             if (input != null) input.close();
             if (output != null) output.close();
         }
  }
  return;
 } catch (Exception ex) {
   //ex.printStackTrace();
 }
 // 如果下载失败了就告诉用户此文件不存在
 response.sendError(404);

%>

  评论这张
 
阅读(2781)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017