当前位置:首页 > 开发 > 编程语言 > Struts2 > 正文

Struts2实现文件的下载

发表于: 2013-04-06   作者:ducklsl   来源:转载   浏览次数:
摘要: 如果对于实现文件的下载有了基础的认识,那么就可以知道文件的下载其实就是HTTP请求头的控制,可以直接使用Servlet实现,也可以使用Struts2框架实现。相较于Servlet需要在代码中设置相应的参数,而Struts2框架提供的下载只需要做一些相应的配置,显得相对简单。具体步骤如下: 1.搭建简单的Struts2项目(参考Struts2的Example) 2.书写文件列表显示的Action
如果对于实现文件的下载有了基础的认识,那么就可以知道文件的下载其实就是HTTP请求头的控制,可以直接使用Servlet实现,也可以使用Struts2框架实现。相较于Servlet需要在代码中设置相应的参数,而Struts2框架提供的下载只需要做一些相应的配置,显得相对简单。具体步骤如下:
1.搭建简单的Struts2项目(参考Struts2的Example)
2.书写文件列表显示的Action类(ListFileAction)
public class ListFileAction implements ServletRequestAware, ServletContextAware {
	private HttpServletRequest request;
	private ServletContext application;
	private List<String> listNames = new ArrayList<String>();// 可以下载的文件名集合
	public String execute() {
		getFiles();
		return "success";
	}
	public void getFiles() {
		// 指定文件上传目录就是文件下载的目录
		String pathname = ServletActionContext.getServletContext().getRealPath(
				"/upload");
		File filedir = new File(pathname);// 新建文件
		if (filedir.exists() && filedir.isDirectory()) {// 判断是否为目录,是则遍历文件
			File[] files = filedir.listFiles();
			for (File file : files) {
				listNames.add(file.getName());// 将文件名放入集合中
			}
		}
		request.setAttribute("names", listNames);// 将文件名集合放入request作用域中
	}
	@Override
	public void setServletContext(ServletContext context) {
		this.application = context;
	}
	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
}
把文件列表放入request作用域中,所以在此Action中实现了ServletRequestAware, ServletContextAware这两个接口,使用依赖注入的方式获得request,也可以使用以下两种方式直接操作:
ActionContextActionContext.getContext().put("names", listNames);
ServletActionContext.getRequest().setAttribute("names", listNames);
以上两种方式都可以将names放到request的作用域中
3.显示文件名列表界面(list2.jsp)
<%
		List<String> fileNames = (List<String>) request.getAttribute("names");
			for (String name : fileNames) {
		%>
		<a href="download.action?filename=<%=name%>"><%=name%></a><br/>
		<%}%>
获取到ListFileAction放到request作用域的names的值,然后遍历出来,使用超链接的形式实现文件下载的请求
3.文件下载处理类(DownloadFileAction)
public class DownloadFileAction implements ServletRequestAware,
		ServletContextAware {
	private HttpServletRequest request;
	private ServletContext application;

	public InputStream getDownloadFile() {
		String fileName = "";
		try {
			fileName = new String(request.getParameter("filename").getBytes(
					"ISO-8859-1"), "GB2312");// 获取文件名,并且进行转码,防止乱码
			System.out.println(fileName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ServletActionContext.getServletContext().getResourceAsStream(
				"/upload/" + fileName);
	}
	public String execute() {
		return "success";
	}
	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
	@Override
	public void setServletContext(ServletContext context) {
		this.application = context;
	}
}
在下载处理类中获取到文件名后拼接到下载路径实现对某个文件的下载。
4.配置文件的实现(struts.xml)
<!-- 文件下载action -->
		<action name="download" class="changluo.file.DownloadFileAction">
			<!-- 必须设置type为stream类型 -->
			<result name="success" type="stream">
				<param name="contentType"></param>
				<!-- 设置http请求头并且设置attachment属性以附件的方式打开,
				 如果没有设置此属性,则以inputStream的方式直接在浏览器打开;
				 并且filename设置下载时,文件显示的名称 -->
				<param name="contentDisposition">
					attachment;filename="dddd.txt"
				</param>
				<!-- inputName的属性设置要依据action中的public InputStream getDownloadFile();
				方法类设定,就是此方法名get后面的部分-->
				<param name="inputName">downloadFile</param>
			</result>
		</action>
		<!-- 显示文件列表 -->
		<action name="listFile" class="changluo.file.ListFileAction">
			<result name="success">/list2.jsp</result>
			<result name="input">/index.jsp</result>
		</action>
以上就构成了Struts2文件下载的基本组成部分。
分析:
1.在struts2中实现文件下载Action的返回值使用的是stream,这点可以从Struts2的文档中就可以看出:
Stream Result      Used to stream an InputStream back to the browser (usually for file downloads)
2.通过查看struts2.x的核心jar包中的struts-default.xml文件中,发现其中有一个名为stream的文件下载拦截器
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
翻开这个类,就可以发现定义了四个变量:
...
protected String contentType="text/plain";//文件内容类型
protected String contentLength;//长度
protected String contentDisposition="inline";//默认方式为inline
protected String inputName="inputStream"; //inputStream的名称
protected String inputStream inputStream; //输入流,用于读取文件
protected int bufferSize=1024;//设置缓冲区大小
...

透过此类不难发现,其实Struts2实现文件下载的本质与普通Servlet是一致的,只是Struts2通过拦截器和配置文件进行工作。在下载Action的方法中有个固定的写法就是:
public InputStream getDownloadFile(){
    //....
    //编写返回InputStream的方法,可以直接用FileInputStream读取文件,也可以用其他方式
}
这个方法只要求返回要下载的文件的InputStream即可。所以,我也可以这样实现
public InputStream getDownloadFile() {
		String fileName = "";
		String pathName = ServletActionContext.getServletContext().getRealPath("/upload");
		String fullName = "";
		InputStream in =null;
		try {
			fileName = new String(request.getParameter("filename").getBytes(
					"ISO-8859-1"), "GB2312");// 获取文件名,并且进行转码,防止乱码
			System.out.println(fileName);
			System.out.println(pathName);
			fullName=pathName+"\\"+fileName;//完整的文件名
			System.out.println(fullName);
			in =new  FileInputStream(fullName);
		} catch (Exception e) {
			e.printStackTrace();
		}
//		return ServletActionContext.getServletContext().getResourceAsStream(
//				"/upload/" + fileName);
		return in;
	}
其实这个InputStream就如同使用Servlet实现下载时,获取到的InputStream,它是就是用来读取要下载的文件的,按照此逻辑应该有OutputStream才对,似乎没有发现。 翻看StreamResult类,发现它的doExecute(...)方法,就可以发现此方法都是对HTTP请求头content-Disposition以及response.getOutputStream的操作(翻翻源码对自己是有好处滴~)
至此可以看见Struts2框架实现文件下载其实原理和Servlet文件下载的方式是一致的,也就完全理解了Struts2实现文件下载为什么要配置相应的参数了
附上关于配置文件中参数的解释,免得以后自己忘记:

contentType - the stream mime-type as sent to the web browser (default = text/plain).

contentLength - the stream length in bytes (the browser displays a progress bar).

contentDisposition - the content disposition header value for specifing the file name (default = inline, values are typically attachment;filename="document.pdf".

inputName - the name of the InputStream property from the chained action (default = inputStream).

bufferSize - the size of the buffer to copy from input to output (default = 1024).

allowCaching - if set to 'false' it will set the headers 'Pragma' and 'Cache-Control' to 'no-cahce', and prevent client from caching the content. (default = true)

contentCharSet - if set to a string, ';charset=value' will be added to the content-type header, where value is the string set. If set to an expression, the result of evaluating the expression will be used. If not set, then no charset will be set on the header

Struts2实现文件的下载

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
文件的下载: 获取指定目录下的所有文件的名字 FileNameServlet.java文件的内容: package com.test.
phonegap 文件下载 效果图: package com.phonegap.plugins.downloader; import java.io.File; impo
phonegap 文件下载 效果图: package com.phonegap.plugins.downloader; import java.io.File; impo
Struts2文件下载 目录: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE
首先先来说下关于文件下载的原理: 服务端为客户端提供了一个下载服务,所以服务端需要一个输出流(
  当我们实现一个文件下载功能时,大多数人是通过Strust等框架实现的。Strust框架把底层的文件下
.Net2.0中新增了很多组件,WebClient就是其中一个,功能也很强大,今天拿WebClient做了一个小实验,
.Net2.0中新增了很多组件,WebClient就是其中一个,功能也很强大,今天拿WebClient做了一个小实验,
一、如何使用 如果此Servlet命名为download,请求的URL为:/download?path=xxx,请求后出现下载窗口
一、导入包 需要将commons-fileupload和commons-io包和struts包一起导入 实现步骤: 在Jsp页面实现
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号