专注Java教育14年 全国咨询/投诉热线:444-1124-454
星辉LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 关于Struts2文件下载的介绍

关于Struts2文件下载的介绍

更新时间:2022-02-10 08:39:45 来源:星辉 浏览782次

文件下载路径问题,项目运行时MyEclipse会加载Tomcat的webapps目录下的项目。所以,关于路径问题(一定要设置相对路径强度)

下载到本地服务器需要相对路径。最好使用绝对路径上传到客户端

上传文件需要很多包。

1. Struts 2 支持文件下载

Struts 2 支持通过 org.apache.slruts2.dispatcher.Stream ResuIt 的结果类型下载文件。

它使下载易于编写的程序变得更加容易。

StreamResuIt 结果类型使用 HttpServletResponse 对象返回的 ServletOutputStrcam 对象,将下载文件的二进制数据输出到客户端,有以下参数:contentType发送到 Web 浏览器的数据流的 MIME 类型(默认为 text/plain)是下载文件的内容类型。

当客户端向Tomcat请求静态资源时,Tomcat会自动在Response Head中添加“Content-Type”属性,并配置具体属性列表。

contentLength

数据流的长度,以字节为单位(浏览器显示进度条),即下载文件的长度

contentDisposition:

该属性配置下载文件的文件名等属性,其中文件类型分为inline和attachment: 1.inline:浏览

器尝试直接打开文件(默认值)

2.attachment:浏览器下载直接作为附件

也不是绝对的。这适用于浏览器可以显示的下载。对于浏览器不支持的下载,即使使用了内联选择。

项目仍会弹出文件下载对话框。contentDispostion 的默认值是 inline。

inputName

Action 中用于下载文件的属性名称,类型为 InputStream。默认识别为 inputStream

inputName:用于指定下载文件的输入流入口,需要在Action中指定。也就是说需要action定义对应的属性类型InputStream。默认为输入流。

如果在Action中声明了getInputStream()方法,则在配置文件struts.xml中配置为<param name="inputName">inputStream</param>。

如果在 Action 中声明了 getTargetFile() 方法,则配置文件 struts.xml 配置为<param name="inputName">targetFile </param>。

bufferSize

文件数据从输入复制到输出的缓冲区大小,默认1024字节

allowCaching

是否允许缓存

StreamResult 结果类型已在 struts-default 文件中定义为逻辑名称流。

<结果名称=“成功”类型=“流”>
				<param name="contentType">文本/纯文本</param>
				<param name="inputName">输入流</param>
                //这里的filename就是要下载的文件名。
				<param name="contentDisposition">附件;filename="hello.txt"</param>
				<param name="bufferSize">1024</param>
			</结果>

案例

  <正文>
	<s:调试/>
	<s:a href="download?fileName=a.txt">下载一种方式</s:a>
	<a href="download?fileName=a.txt">向下模式二</a>
  </正文>
公共类 DownloadAction 扩展 ActionSupport {
	私有字符串文件名;
	公共输入流 getInputStream() 抛出 IOException {
		字符串路径 = ServletActionContext.getServletContext().getRealPath(fileName);
		/**
		 * 方法1 File file = new File(路径);返回新的文件输入流(文件);
		 * 方法二 FileUtils.openInputStream(file);
		 */
		文件文件 = 新文件(路径);
		返回 FileUtils.openInputStream(file);
	}
	公共字符串 getFileName() {
		返回文件名;
	}
	公共无效 setFileName(字符串文件名){
		this.fileName = 文件名;
	}
	@覆盖
	公共字符串执行()抛出异常{
		返回 super.execute();
	}
	公共无效setInputStream(输入流输入流){
	}
}
	    <动作
			名称="下载"
			类="action.DownloadAction">
			<结果名称=“成功”类型=“流”>
				<param name="contentType">文本/纯文本</param>
				<param name="inputName">输入流</param>
				<param name="contentDisposition">附件;filename="hello.txt"</param>
				<param name="bufferSize">1024</param>
			</结果>
		</行动>

此时,不要忘记导入包,以及导入哪个包的FileUtils,仔细看import org.apache.commons.io.FileUtils;

缺点或改进

缺点

如果要下载任意目录下的文件(不仅仅是Web应用目录),只需要修改action返回文件输入流的方式,比如return new FileInputStream(inputPath)。

在实际应用中,下载的文件不应该配置在struts.xml文件中。如果是这样,则相当于将 FileDownloadAction 的功能限制为仅下载一个文件。下载文件的选择应该通过编码来实现。根据浏览器的下载请求,查询配置文件或数据库,获取真正的下载文件数据,构造inputStream对象。

对于下载的文件名和下载的文件类型,它们是在struts.xml 文件中配置的。如果用户要下载的文件类型很多,这种方式显然不够灵活。

改进

为了动态设置文件类型和下载文件名,我们可以写一个拦截器,在Action执行前动态添加StreamResult的参数,执行结果。

为了在结果执行之前拦截调用,我们需要使用 PreResultListener 接口,可以通过 Action lnvocation 注册该接口,并在结果执行之前获取回调。PreResultListener 需要在拦截器中注册,所以我们需要编写一个拦截器,然后

在拦截器方法中注册一个 PreResultListener 实例。

下载文件时出错

java.lang.IllegalArgumentException:在调用堆栈中找不到名称为 [inputStream] 的 java.io.InputStream。
检查为此操作指定的 <param name="inputName"> 标记。
	在 org.apache.struts2.result.StreamResult.doExecute(StreamResult.java:234)
ERROR DefaultDispatcherErrorHandler 处理请求时发生异常:
java.lang.IllegalArgumentException:在调用堆栈中找不到名称为 [inputStream] 的 java.io.InputStream。
 检查为此操作指定的 <param name="inputName"> 标记。

这是因为 ServletActionContext.getServletContext().getResourceAsStream(path+fileName); 返回值为空。

也就是说,文件的路径不对。如果大家对此比较感兴趣,想了解更相关知识,可以关注一下星辉的Struts2视频教程,里面还有更丰富的知识等着大家去学习,希望对大家能够有所帮助。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>