《研磨struts2》第十三章 文件上传下载 之 13.2 文件下载

13.2  文件下载

13.2.1概述

前面学习了文件上传的实现,接下来看看如何实现文件下载的功能。实现文件下载功能的方式也很多,这里只具体看看如何使用Struts2来实现文件下载。

使用Struts2来实现文件下载,会用到它的stream类型的Result,这种Result最终会返回一个InputStream,只需要让这个InputStream能读到用户想要下载的文件即可。

13.2.2 stream结果类型

先来回忆一下stream的结果类型出现在struts-default.xml中的配置,示例如下:

 

java代码:
  1.    <package name="struts-default" abstract="true">  
  2.        <result-types>  
  3.         ...  
  4.            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>  
  5.     ...  
  6.        </result-types>  
  7. ...  
  8.    </package>  

既然stream是struts-default包中声明的一种内置结果类型,因而只要我们的包继承自struts-default包就可以使用这种结果类型了。

13.2.3实现文件下载的Action

使用stream类型作为Result的Action和普通的Action有很大的不同,它不需要execute方法;而是需要一个公有的,返回InputStream的getInputStream方法,这个方法用来返回文件的内容。示例代码如下:


java代码:
  1. public class DownloadAction extends ActionSupport{  
  2.     public InputStream getInputStream() throws Exception{  
  3.         File file = new File("e:/temp/测试.doc");  
  4.         return new FileInputStream(file);  
  5.     }  
  6. }  

在上面示例中,仅是简单的返回一个读取绝对路径下的文件的输入流。

13.2.4struts.xml中配置Action

在struts.xml中,需要配置这个Action的后继页面为一个stream类型的Result。


java代码:
  1. <package name="helloworld" extends="struts-default">  
  2.     <action name="downloadAction" class="cn.javass.fileupload.DownloadAction">  
  3.         <result type="stream">  
  4.             <param name="contentDisposition">attachment;filename="test.doc"</param>  
  5.         </result>  
  6.     </action>  
  7. </package>  

上面配置中,<action>元素只有一个<result>子元素,其类型为stream;但是<result>元素有一个<param>子元素指定了contentDisposition的值为attachment;filename="test.doc",这指明了在访问这个Result的时候,会弹出一个下载框,其中的默认文件名为test.doc。

       stream类型的结果共可以指定7个参数:

  • contentType:下载文件的类型。
  • contentLength:下载文件的长度,用于浏览器的进度条显示。
  • contentDisposition:指定文件下载的默认名字,如果不指定则使用Action名.action。
  • inputName:Action中用于返回InputStream的get方法的名字,默认为inputStream,因此,我们的Action中定义了getInputStream的方法。
  • bufferSize:缓冲区大小,默认为1k。
  • allowCaching:是否允许浏览器进行缓存。
  • contentCharSet:HTTP响应头信息中的编码方式。

在以上7个参数中,最常用的是使用contentDisposition来指定默认的文件下载名,其他的使用默认即可。

13.2.5制作下载页面

现在还需要制作一个页面,在这个页面设置一个超链接,链接到下载的Action,示例代码如下:

 

java代码:
  1. <%@ page language="java" contentType="text/html; charset=gb2312"  
  2.     pageEncoding="gb2312"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  
  4.  "http://www.w3.org/TR/html4/loose.dtd">  
  5. <html>  
  6. <head>  
  7. <meta http-equiv="Content-Type" content="text/html; charset=gb2312">  
  8. <title>Insert title here</title>  
  9. </head>  
  10. <body>  
  11.     <a href="/helloworld/downloadAction.action">下载文件</a>  
  12. </body>  
  13. </html>  

测试运行一下,访问这个页面,点击上面的“下载文件”链接,就会弹出如下保存对话框,其默认文件名就是在struts.xml中配置的test.doc。

图13.4 跳转到downloadAction后弹出的文件下载对话框

13.2.6难道只能在配置文件中写死文件名吗?

看到这里,可能有朋友会想:难道下载的文件名只能在配置文件struts.xml中写死吗?肯定不是的,首先把对应的配置信息去掉,看看Struts2是否能自适应文件名

 

java代码:
  1. <package name="helloworld" extends="struts-default">  
  2.     <action name="downloadAction" class="cn.javass.fileupload.DownloadAction">  
  3.         <result type="stream">                  
  4.         </result>  
  5.     </action>  
  6. </package>  

再次运行,弹出的文件对话框的下载文件名居然直接是“downloadAction.action”,就是action的名称,如下图所示:

图13.5 跳转到downloadAction后弹出的文件下载对话框

看起来不设置contentDisposition属性这条路走不通。那么该怎么做才能让下载显示的文件名称不是写死的呢?

       有两种解决的方式。一种就是在Action中提供一个返回文件名称的方法,然后在配置文件中引用这个变量;另外一种方法干脆就去掉配置文件中关于contentDisposition的配置,而直接在Action中提供一个getContentDisposition的方法。

       接下来分别看看示例。

1:第一种实现方式

       也就是在Action中提供一个返回文件名称的方法,然后在配置文件中引用这个变量,这一个实现方式。此时Action的实现,示例代码如下:

 

java代码:
  1. public class DownloadAction extends ActionSupport{  
  2.     public String getDownLoadFileName(){  
  3.         return "test.doc";  
  4.     }  
  5.     public InputStream getInputStream() throws Exception{  
  6.         File file = new File("e:/temp/测试.doc");  
  7.         return new FileInputStream(file);  
  8.     }  
  9. }  

在这个Action的实现里面,并没有属性,而直接提供的getDownLoadFileName方法,这是因为OGNL对应访问的就是getter方法。

       相应在struts.xml中的配置,示例如下:

 

java代码:
  1. <package name="helloworld" extends="struts-default">  
  2.     <action name="downloadAction" class="cn.javass.fileupload.DownloadAction">  
  3.         <result type="stream">  
  4.             <param name="contentDisposition">attachment;filename=${downLoadFileName}</param>  
  5.         </result>  
  6.     </action>  
  7. </package>  

去运行测试看看,这是否能正确设置下载显示的文件名。

2:第二种实现方式

       就是干脆就去掉配置文件中关于contentDisposition的配置,而直接在Action中提供一个getContentDisposition的方法,这样的一种方法。

       此时Action的实现,示例代码如下:

 

java代码:
  1. public class DownloadAction extends ActionSupport{  
  2.     public String getContentDisposition(){  
  3.         return "attachment;filename=\"test3.doc\"";  
  4.     }  
  5.     public InputStream getInputStream() throws Exception{  
  6.         File file = new File("e:/temp/测试.doc");  
  7.         return new FileInputStream(file);  
  8.     }  
  9. }  

       相应在struts.xml中的配置,示例如下:

 

java代码:
  1. <package name="helloworld" extends="struts-default">  
  2.     <action name="downloadAction" class="cn.javass.fileupload.DownloadAction">  
  3.         <result type="stream">  
  4.         </result>  
  5.     </action>  
  6. </package>  

去运行测试看看,这种方式能不能正确设置下载显示的文件名。

13.2.7处理中文文件名

前面的示例,下载显示的都是英文文件名,那么如何让下载显示的是中文的文件名呢?

       方法也很简单,就是在Action里面动态设置文件名称的时候,对其按照“ISO8859-1”进行编码,就可以了。

       此时的Action,示例代码如下:

 

java代码:
  1. public class DownloadAction extends ActionSupport{  
  2.     public String getContentDisposition() throws UnsupportedEncodingException{  
  3.         String s = new String("测试".getBytes(),"ISO8859-1");  
  4.         return "attachment;filename=\""+s+".doc\"";  
  5.     }  
  6.     public InputStream getInputStream() throws Exception{  
  7.         File file = new File("e:/temp/测试.doc");  
  8.         return new FileInputStream(file);  
  9.     }  
  10. }  

去运行测试看看,应该能正确显示中文的名称了,运行如下图所示:

图13.6  下载提示页面显示中文文件名

 

私塾在线网站原创《研磨struts2》系列

转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4122.html

欢迎访问http://sishuok.com获取更多内容

猜你喜欢

转载自rubbing-struts2.iteye.com/blog/1546102