日期:2014-05-16  浏览次数:20828 次

浅谈Struts2数据下载和AJAX服务端接口的实现

在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。

拿上面配置为例,即必须有:

?

	/**
	 * @return the inputStream
	 */
	public InputStream getInputStream() {
		return 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;
?