Struts2 实现下载文件

问题

UBA的项目,录音播放满足不了用户,需要加一个下载。

解决方案

1、servlet原生
直接获取OutputStream,把要下载的文件一个按照byte流写入

OutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(fileLoad);

byte[] b = new byte[1024];
//b只是一个缓冲数组,一次最多读取1024个byte,多次读取整个文件
int size = in.read(b);
while (size > 0) {
    out.write(b,0,size);
    size = in.read(b);
}
in.close();
out.close();

response.setContentType("text/plain;charset=UTF-8");
response.addHeader("content-disposition", "attachment;filename="+localFileName);
response.setHeader("Content_Length", length);

in.close();
out.close();
out.flush();

2、struts2框架
struts2框架包装了方法1,简化版

FileInputStream in = new FileInputStream(fileLoad);
return in;

遇到的问题

虽然看上去很简单的实现,但是在实现过程中花了一个上午+半个下午,困难重重啊。
1、struts java.io.FileInputStream cannot be cast to java.lang.String
原因1,配置文件写错,仔细理解下这个配置:

<package name="polo" extends="struts-default" namespace="/polo">
     <action name="downloadF" class="com.ebupt.UBA.web.DownloadFileAction">
        <result name="success" type="stream">
        <param name="contentType">application/x-msdownload;</param>
<param name="contentDisposition">attachment;filename=${localFileName}</param>
         <param name="inputName">downToLocal</param>
         <param name="bufferSize">2048</param>
        </result>
     </action>
</package>

success是指,return “success”的结果对应着这个result。
contentType,http返回的头中类型
bufferSize,就是在输出流中每次读取多少个
inputName,最有意思的就是这个,我们需要定义的函数是

InputStream getDownToLocal(){}

但是需要注意的是,这个方法不是action方法,之前一直走的思维定式,哭啊。这个方法,只是返回一个FileInputStream。

2、点击下载,就是不返回信息
那action方法是哪个?需要定义的好吧。。。
还要写一个action方法,要不根本不会执行到getDownToLocal这个函数。
我们需要定义的action:

public String download(){
      return SUCCESS;
}

忍不住鄙视下struts,要不要这么2

3、点击了下载,就是不下载,但是在response中有响应,响应信息就是文件内容
这个问题是最恶心的了,一直以为是struts2哪里不对了
偶然间才解决了这个问题:
原来我在下载发请求的时候调用的是ajax方法,哭了,这么2的错误也能范,不细心啊。
是偶然间才发现的:
Struts2 实现下载文件_第1张图片
预期的响应格式和实际的响应格式不一致啊,能下载成功才怪啊。
下载的请求这么调才对啊:

 var url = ctx + "/polo/downloadF!download.action";
 var postData = {
     "localFileName": response.localFileName,
     "localPath": response.localPath
 };
 postM(url, postData);

直接发链接,或者用表单提交方式。

之前用原生的servlet一直返回文本,也是这个问题啊。。。

在整个过程中发现的问题

struts2的package中需要加上namespace=”polo”这样在action之前一层链接才会生效,否则填啥都行:

<package name="polo" extends="struts-default" namespace="/polo">

你可能感兴趣的:(struts,servlet,解决方案,struts2.0)