struts 1 文件下载时无法获取正确的文件

ThinkCat 2010-10-27 07:40:14
实现一张图片的上传下载。

上传是没有问题的,用plsql dev看了一下,的确已经传到数据库上了。

但是,在下载的时候发生了问题:

为了省事,我在下载时选择了输入名称(在上传的时候一起传到了数据库,不是文件名,但这不是重点),来选择下载的文件。


<!--下载请求-->
<form action="fileDownload.do" method="post">
<input type="text" name="title"/>
<input type="submit" value="下载文件">
</form>



<!--struts-config.xml动态ActionForm配置信息-->
<form-bean name="fileDynaForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="title" type="java.lang.String"/>
<form-property name="file" type="org.apache.struts.upload.FormFile"/>
</form-bean>

<!--struts-config.xml中Action相应的配置信息-->
<action path="/fileDownload"
type="cn.edu.sjzri.title.action.FileDownloadAction"
name="fileDynaForm"
scope="request"
>
<forward name="success" path="/downloadSuccess.jsp"/>
</action>



//下载Action
public class FileDownloadAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {

//获取数据
DynaActionForm daf = (DynaActionForm)form;
String title = (String) daf.get("title");

//下载操作
Connection conn = null;
PreparedStatement pst = null;
ResultSet rst = null;
InputStream ins = null;

conn = ConnectionDB.buildconnection();
try {
pst = conn.prepareStatement("select * from fileInfo where title = ?");
pst.setString(1, title);
rst = pst.executeQuery();
if(rst.next()) {
ins = rst.getBinaryStream("fileinfo");
response.setContentType("application/jpg");
int size = ins.available(); //注释1:size经测试为0
byte[] total = new byte[size];
ins.read(total);
ServletOutputStream souts = response.getOutputStream();
souts.write(total);
souts.flush();
souts.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}



--数据库中存储文件表的信息
create table fileinfo
(
title varchar2(40) not null,
fileinfo blob not null
)


现在的问题是:输完名称,一点下载文件,显示的却是fileDownLoad.do的下载对话框。这是为什么?

我在测试size的时候(见注释1),发现size为0,这正常吗?文档上倒是说“当调用 available 方法时,不管是否存在可用数据,流都可能返回 0”。

先谢过大家了。
...全文
227 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ThinkCat 2010-10-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jxsryecheng 的回复:]

response.setContentType("Application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);

换掉试试!
[/Quote]fileName如何获取?是不是可以手动填写文件名呢?如果是这样的话,那么获得的文件还是0字节的。
十橙心橙意 2010-10-28
  • 打赏
  • 举报
回复
response.setContentType("Application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);

换掉试试!
ThinkCat 2010-10-28
  • 打赏
  • 举报
回复
顶顶更健康,别沉了
ThinkCat 2010-10-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jxsryecheng 的回复:]

你说的出现**.do,我也见过!好像是得到文件为空!

response.setContentType("application/jpg");
这句话有问题吧!
[/Quote]的确是一个空文件。不过response.setContentType("application/jpg");感觉没啥问题,不是要设置一下类型吗?
十橙心橙意 2010-10-28
  • 打赏
  • 举报
回复
恩,数组那里确实是个问题!是得固定。

另外就是下载的时候需要用response响应,这个时候需要设置流的contentType和Header。



ThinkCat 2010-10-28
  • 打赏
  • 举报
回复
上面有一点说错了,把数组大小固定,下载下来的图片的大小是数组的大小。开始测试的时候正好把数组大小设置成图片的字节长度,还以为一样呢
bgsbati 2010-10-28
  • 打赏
  • 举报
回复
-----------马甲---------------
ThinkCat 2010-10-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jxsryecheng 的回复:]

response.setContentType("Application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);

换掉试试!
[/Quote]
问题应该是int size = ins.available()这句。

文档里说“Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes. ”不应该用它决定数组大小(文档里也这样说了),因为它是在未阻塞的情况下才能返回字节数。我这个流可能是因为某些原因阻塞了,所以返回的是0(这一点文档中也提到了)。

然后我试图用

int ch;
int size;
StringBuffer sb = new StringBuffer();
while((ch = ins.read()) != -1) {
sb.append((char)ch);
}
size = sb.length();
byte[] total = new byte[size];

来获取byte数组大小,但是情况确实下载到的文件也是四百多k,但是却说是无效文件。

而把数组大小直接固定了,就可以正常显示了(这种情况和用上述代码时,下载到的图片大小是一样的)。我觉得应该是数组的事,在编译时,应该要确定数组的大小。而上述代码中的size只有在运行时才会确定。可能是这样吧。

最后的解决方法是,将int size = ins.available();去掉,把数组固定大小(虽然会浪费一些空间,也是无奈),然后把response.setContentType("application/jpg");换成你说的response.setContentType("Application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);,这样就可以了。
ThinkCat 2010-10-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jxsryecheng 的回复:]

response.setContentType("Application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);

换掉试试!
[/Quote]
问题应该是int size = ins.available()这句。

文档里说“Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes. ”不应该用它决定数组大小(文档里也这样说了),因为它是在未阻塞的情况下才能返回字节数。我这个流可能是因为某些原因阻塞了,所以返回的是0(这一点文档中也提到了)。

然后我试图用

int ch;
int size;
StringBuffer sb = new StringBuffer();
while((ch = ins.read()) != -1) {
sb.append((char)ch);
}
size = sb.length();
byte[] total = new byte[size];

来获取byte数组大小,但是情况确实下载到的文件也是四百多k,但是却说是无效文件。

而把数组大小直接固定了,就可以正常显示了(这种情况和用上述代码时,下载到的图片大小是一样的)。我觉得应该是数组的事,在编译时,应该要确定数组的大小。而上述代码中的size只有在运行时才会确定。可能是这样吧。

最后的解决方法是,将int size = ins.available();去掉,把数组固定大小(虽然会浪费一些空间,也是无奈),然后把response.setContentType("application/jpg");换成你说的response.setContentType("Application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);,这样就可以了。
十橙心橙意 2010-10-27
  • 打赏
  • 举报
回复
你说的出现**.do,我也见过!好像是得到文件为空!

response.setContentType("application/jpg");
这句话有问题吧!

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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