使用Struts2下载文件遇到问题总结

前言: 最近在研究如何使用struts2实现文件下载,其中遇到如下两个问题觉得应该总结一番。

1. struts2实现文件下载的配置问题

利用struts2实现文件下载代码如下:

public class fileDownloadAction extends ActionSupport implements ServletContextAware {

    private static final Logger logger = Logger.getLogger(fileDownloadAction.class);    

    String fileName;

    public String excute() {        

        return SUCCESS;
    }

    public InputStream getDownloadFile() throws Exception {
        this.fileName = "configurations.zip";       
        return ServletActionContext.getServletContext().getResourceAsStream("C:/Profile/java/workspace/FileDownload/configurations.zip"); 
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }   

}

编写完实现下载的action类后,需要在struts.xml中添加如下代码:

<action name="fileDownloadAction" class="fileDownloadAction">
    <result name="success" type="stream">
        <param name="contentType">text/plain</param>
        <param name="contentDisposition">attachment;fileName="${fileName}"</param>  
        <param name="inputName">downloadFile</param>  
        <param name="bufferSize">1024</param> 
    </result>
</action>

关于上面的配置说明如下:
1) .action类中的excute()方法只能返回SUCCESS,如果返回其他的字符串会报如下错误:

05/08/2017 09:45:27.833 UTC [http-apr-8080-exec-4] ERROR org.apache.struts2.dispatcher.Dispatcher null:: Exception occurred during processing request: No result defined for action com.test.filedownload.FileDownloadAction and result success
No result defined for action com.test.filedownload.FileDownloadAction and result success
    at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
    at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
    at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)

2). 结果类型必须要写成 type=”stream”,与之对应的处理类是 org.apache.struts2.dispatcher.StreamResult;

3). 关于<param name="contentDisposition">attachment;fileName="${fileName}"</param>
a) 其中contentDisposition默认是 inline(内联的),比如说下载的文件是文本类型的,就直接在网页上打开,不能直接打开的才会打开下载框自己选择;
b) attachment :下载时会打开下载框;
c) fileName=”${fileName}” :这个变量定义在fileDownloadAction类中,最后这个名字是显示在下载框上的文件名字。

4). <param name="inputName">downloadFile</param>,其中downloadFile对应action类中返回InputStream的get方法,去除掉get后的名字。例如,在action类中我们由getFileNeedToBeDownloaded方法获得下载文件,并以InputStream返回,那么这个时候配置为<param name="inputName">fileNeedToBeDownloaded</param>

2. 在点击下载按钮以后报错

报错内容是:Can not find a java.io.InputStream with the name [downloadFile] in the invocation stack. Check the tag specified for this action.
出现这个错误最开始想的是不是struts.xml配置错误,排除配置错误以后查看网上博客发现有可能是action类中的下载路径不正确。因为当InputStream为null时,也会报这样的错误,源码片段如下:

if (inputStream == null) {   
         // Find the inputstream from the invocation variable stack  
         inputStream = (InputStream) invocation.getStack().findValue(conditionalParse(inputName, invocation));   
}   

if (inputStream == null) {   
     String msg = ("Can not find a java.io.InputStream with the name [" + inputName + "] in the invocation stack. " +   
         "Check the <param name=\"inputName\"> tag specified for this action.");   
     LOG.error(msg);   
     throw new IllegalArgumentException(msg);   
 }  

于是我在实现下载的action类中,在返回下载文件前先打印了其内容,结果果然是为null。

InputStream is = ServletActionContext.getServletContext().getResourceAsStream("C:/Profile/java/workspace/FileDownload/configurations.zip"); 
if(is == null) {
    System.out.println("File path is not correct!");
}

导致这个的原因是因为,我返回文件的代码如下:

ServletActionContext.getServletContext().getResourceAsStream("C:/Profile/java/workspace/FileDownload/configurations.zip"); 

而getResourceAsStream读取的文件路径只局限于工程的源文件夹中,包括在工程src根目录下,以及类包里面任何位置,但是如果配置文件路径是在除了源文件夹之外的其他文件夹中时,该方法是用不了的。 将需要下载的文件放到项目的download文件夹下面,并将代码改为如下便可以解决这个报错:

ServletActionContext.getServletContext().getResourceAsStream("download/configurations.zip");
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值