Struts2 文件下载及找不到文件的处理办法

Struts2 对文件的上传和下载提供了很好的支持,上传时直接用 java.io.File 来接收,下载时也无需自己去设置相应的 Stream 响应头,它提供了 org.apache.struts2.dispatcher.StreamResult 给 Action 使用。它反映到 struts.xml 配置里就是type="stream" 的 result,由 result 去负责把文件内容写入响应中去。Action 的执行方法在 result 之前执行,所以你可以借此控制下载权限,本文也演示了如何判断文件是否存在,不存在则导向到 FileNotFound 页面。StreamResult 中有哪些相关的配置参数可以参考它的源代码:

 1public class StreamResult extends StrutsResultSupport {
 2
 3    private static final long serialVersionUID = -1468409635999059850L;
 4
 5    protected static final Logger LOG = LoggerFactory.getLogger(StreamResult.class);
 6
 7    public static final String DEFAULT_PARAM = "inputName";
 8
 9    protected String contentType = "text/plain";
10    protected String contentLength;
11    protected String contentDisposition = "inline";
12    protected String contentCharSet ;
13    protected String inputName = "inputStream";
14    protected InputStream inputStream;
15    protected int bufferSize = 1024;
16    protected boolean allowCaching = true;
17 
18    .......................

下面是一个文件下载的例子:

struts.xml
 1<action name="down/pro" method="down">
 2    <param name="fileDir">c:/downloads/</param>
 3    <result name="fileNotFound">errors/page_404.html</result>
 4    <result type="stream">
 5        <param name="contentType">application/pdf</param>
 6        <param name="inputName">targetFile</param>
 7        <param name="contentDisposition">filename="${fileName}"</param>
 8        <param name="buttferSize">4096</param>
 9    </result>
10</action>

说明:
1. fileDir 属性设置到 Action 的 fileDire 字段上,标识文件所处的目录。
2. fileNotFound result 是在文件找不到时转向的页面
3. inputName 用于指定待下载文件输入流的名称,即对应于 Action 的属性名;默认为 inputStream,这里定义为 targetFile,所

以 StreamResult 会调用 Action 的 getTargetFile() 方法。
4. ${fileName} 会被这里的 Action 的 fileName 属性替代,它是个 OGNL。
5. 其他的配置看 StreamResult 的源码了

DownloadAction.java
 1package cc.unmi.download;
 2
 3import java.io.File;
 4import java.io.FileInputStream;
 5import java.io.FileNotFoundException;
 6import java.io.InputStream;
 7
 8import com.opensymphony.xwork2.ActionSupport;
 9
10
11public class DownloadAction extends ActionSupport{
12
13    private String fileDir;
14    private String fileName;
15
16    public InputStream getTargetFile() {
17        try {
18            String filePath = fileDir + fileName;
19            return new FileInputStream(filePath);
20        } catch (FileNotFoundException e) {
21            e.printStackTrace();
22        }
23        return null;
24    }
25
26    public String down(){
27
28        //这里判断文件存不存在,不存在则转向到 fileNotFound 页面
29        String filePath = fileDir + fileName;
30        if(!new File(filePath).exists()){
31            return "fileNotFound";
32        }
33
34        //由 StreamResult 来处理后续的部分了
35        return SUCCESS;
36    }
37
38
39    public String getFileDir() {
40        return fileDir;
41    }
42
43    public void setFileDir(String fileDir) {
44        this.fileDir = fileDir;
45    }
46
47    public void setFileName(String fileName) {
48        this.fileName = fileName;
49    }
50
51    public String getFileName() {
52        return fileName;
53    }
54}

如果文件不存,getTargetFile() 里出现异常,在页面中将会打出:

Struts Problem Report
Struts has detected an unhandled exception:

Messages: Can not find a java.io.InputStream with the name [targetFile] in the invocation stack. Check the tag

specified for this action.
 
File: org/apache/struts2/dispatcher/StreamResult.java
Line number: 237
--------------------------------------------------------------------------------

Stacktraces
java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [targetFile] in the invocation

stack. Check the tag specified for this action.
    org.apache.struts2.dispatcher.StreamResult.doExecute(StreamResult.java:237)
    org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:277)

getTargetFile() 会在 down() 后由 StreamResult 调用,所以可在 down() 中判断文件不存在就 return "fileNotFound"; 永久链接 https://yanbin.blog/struts2-download-file-not-found/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。