实现一张图片的上传下载。上传是没有问题的,用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”。先谢过大家了。

解决方案 »

  1.   

    你说的出现**.do,我也见过!好像是得到文件为空!response.setContentType("application/jpg");
    这句话有问题吧!
      

  2.   

    的确是一个空文件。不过response.setContentType("application/jpg");感觉没啥问题,不是要设置一下类型吗?
      

  3.   

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

  4.   

    fileName如何获取?是不是可以手动填写文件名呢?如果是这样的话,那么获得的文件还是0字节的。
      

  5.   

    问题应该是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);,这样就可以了。
      

  6.   

    问题应该是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);,这样就可以了。
      

  7.   

    恩,数组那里确实是个问题!是得固定。另外就是下载的时候需要用response响应,这个时候需要设置流的contentType和Header。