求助,jsp形成的超链接,如何直接形成下载框?

toss2000 2010-06-10 12:35:48
客户一个需求,要求可以下载每天生成的系统日志文件,在这个系统中当天生成的日志为system.log,前一天的是system.log.2010-6-9, 现在要求,把他们显示到页面,并且选择文件名后,可以下载,我现在遇到的问题是,只要一选择文件名,直接就在IE中打开了,而没有出现下载框,网上查了都不对路子,请大虾们帮忙!!!!
...全文
109 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

function callDownloadServlet(filename, reqNo) {
//alert(filename);
var andOpt = '&&';
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要自己完成了,反正就是到指定的目录下读取文件名,然后就是提取了。
huanghaiman 2010-06-10
  • 打赏
  • 举报
回复
应该是下载文件的后缀的问题~ 也有可能是IE版本 这个我也遇到~时好是坏 学习中
weihao9939 2010-06-10
  • 打赏
  • 举报
回复
文件下载时采用文件流输出的方式处理 不要用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 );
%>
Java技术栈 2010-06-10
  • 打赏
  • 举报
回复
有代码有真相。。
gifted1982 2010-06-10
  • 打赏
  • 举报
回复
<a href='system/monitor/downLog.jsp?fileName=<bean:write name="listId" property="fileName"/>

system前面少了个/,是不是因为这个。

另外,out没有close
toss2000 2010-06-10
  • 打赏
  • 举报
回复
这是我的代码
<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);
}
%>
结果总是报说系统找不到指定的路径,郁闷中……

81,090

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧