客户一个需求,要求可以下载每天生成的系统日志文件,在这个系统中当天生成的日志为system.log,前一天的是system.log.2010-6-9, 现在要求,把他们显示到页面,并且选择文件名后,可以下载,我现在遇到的问题是,只要一选择文件名,直接就在IE中打开了,而没有出现下载框,网上查了都不对路子,请大虾们帮忙!!!!

解决方案 »

  1.   

    这是我的代码
    <a href='/system/logs/<bean:write name="listId" property="fileName"/>' target="_blank"><bean:write name="listId" property="fileName"/></a>
    这个就直接在页面中显示内容了,后来查了一段代码我把上面改为
    <a href='system/monitor/downLog.jsp?fileName=<bean:write name="listId" property="fileName"/>' target="_blank"><bean:write name="listId" property="fileName"/></a>
    其中downLog.jsp为<%@ page contentType="text/html;charset=gbk"%><%    
         
         String fileName=request.getParameter("fileName").trim();
         String fullname =request.getContextPath()+"/logs/" + fileName; 
          String filename = fullname.substring(fullname.lastIndexOf('/'));   
         int i = 0;   
         response.setContentType("application/octet-stream");  
     
         // 关键是设置这个Header,否则还是会直接在浏览器中打开的
         response.setHeader("Content-Disposition","attachment;filename = " + filename);    
         java.io.FileInputStream fileInputStream = new java.io.FileInputStream(fullname);   
         while((i= fileInputStream.read()) != -1){   
             out.write(i);   
         }   
    %>  
    结果总是报说系统找不到指定的路径,郁闷中……
      

  2.   

    <a href='system/monitor/downLog.jsp?fileName=<bean:write name="listId" property="fileName"/>system前面少了个/,是不是因为这个。另外,out没有close
      

  3.   

    文件下载时采用文件流输出的方式处理 不要用PrintWriter(JSP里面的out)<%-- 
    有些朋友询问使用 JSP Smart 下载文件的时候报错, 这里给出一个测试过的不
    需要使用 JSP Smart 的 JSP 页面中进行文件下载的代码(改 Servlet 或者
    JavaBean 的话自己改吧), 支持中文附件名(做了转内码处理). 事实上只要向
    out 输出字节就被认为是附件内容, 不一定非要从文件读取原始数据, 从数据
    库中读取也可以的.
    --%> 
    <% @ page contentType = " text/html; charset=GBK "  pageEncoding = " GBK "   %> 
    <% @ page  import = " java.io.*, java.util.*, java.text.* "   %> <%! 
         /** 
         *  If returns true, then should return a 304 (HTTP_NOT_MODIFIED)
          */ 
         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( " 测试文档.htm " );
         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 );
    %> 
      

  4.   


    function callDownloadServlet(filename, reqNo) {  
    //alert(filename);
    var andOpt = '&amp;&amp;';
    var path = '/itsr/DownloaderServlet?action=MaintAttach' + andOpt + 'filename=' + filename + andOpt + 'requestNo=' + reqNo;
    OpenWindow=window.open(path, 'web', 'status=1,width=350,height=150');
    return true;
    } 以上是下载页面的js调用。具体DownloaderServlet要自己完成了,反正就是到指定的目录下读取文件名,然后就是提取了。