在struts2中实现文件或特定数据格式文件下载其实并不难的。
一,struts2配置文件示例,见下面代码:
<package name="export" namespace="/export" extends="struts-default"> <action name="test" class="exportAction"> <result name="success" type="stream"> <param name="contentType">text/plain</param> <param name="inputName">inputStream</param> <param name="contentDisposition">filename="${fileName}"</param> <param name="bufferSize">4096</param> </result> </action> </package>
说明:
1 .class="exportAction"
exportAction是spring配置好的实例。因为这里我是集成spring,给spring管理。
2.<result name="success" type="stream">
type="stream" 不用多说了吧,我们这里返回的是stream。若有问题请查看struts2的result中的type说明。
3.stream的几个相关参数
contentType | 声明stream的内容类别,常用的如:text/plain、application/zip、text/html等 |
inputName | inputStream类型的参数,action中必须有get此输入流的名字的方法,最主要的参数。这里特别注意一下,你想action实现下载的文件也好,实现输出数据也好,都必须配置好此inputStream。 拿上面配置为例,即必须有:
|
contentDisposition | 内容报头。一般用来指定下载文件的名字。注意参数中我用了一个${fileName}来指定文件的名字。是因为一般下载的文件都是动态的,并且这个文件若有中文,也不能直接写在配置文件上,不然会出现乱码。同样的,action中必须有定义fileName的getFileName的方法。 |
bufferSize | 比较好理解,指定缓存区的大小。 |
二,中文乱码问题
就以刚刚的fileName为例,一般都需要指定文件名的编码格式乱码才会正常。具体参考如下:
fileName = new String("测试下载.dbf".getBytes("GBK"), "ISO8859-1");
然后记得保证action中有下面方法:
/**
* @return the fileName
*/
public String getFileName() {
return fileName;
}
注意,编码是为GBK,就算项目中是UTF8也好。因为这里的乱码问题大多是由于操作系统的浏览器引起的,所以只有GBK才会正常。
三,AJAX接口的实现。
很多时候,我们会用到struts2来制作AJAX的服务端接口。
这里,我们用两个参数便可以了。
<result name="success" type="stream"> <param name="contentType">text/html</param> <param name="inputName">inputStream</param> </result>
然后在action中,我们需要把返回的AJAX数据(即string)转成inputStream,但记得也要指定编码,因为这里也会出现乱码的情况。
在这,我分享一个units方法:
public static InputStream stringToInputStream(String str) {
if (str == null) {
str = StringUtils.EMPTY;
}
InputStream in = null;
try {
in = new ByteArrayInputStream(str.getBytes(DEFAULT_ENCODING));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return in;
}
DEFAULT_ENCODING:我使用的是UTF-8,与项目默认编码一致。
PS:也可以用struts2提供的JSON plugin来实现,不过个人更喜欢用inputStream来自己构造JSON体,因为这样更加自由,遇到复杂的多层列表的JSON时也可以游刃有余。
四,题外,有时候也许会遇到下载文件的时候会只支持outputStream的情况。但struts2这个配置只支持inputStream,所以,我们也需要把outputStream转成inputStream。
ByteArrayOutputStream out = new ByteArrayOutputStream();
writer.setCharactersetName("GBK");
writer.write(out);
inputStream = new ByteArrayInputStream(out.toByteArray());
fileName = new String("测试下载.dbf".getBytes("GBK"), "ISO8859-1");
return SUCCESS;