一,概述
之前写了一篇博客,是关于
struts2之文件上传的.现在就写一篇关于struts2文件下载的博客.个人感觉,文件下载比文件上传复杂一点,哈哈,感觉而已...
二,Action开发
1)首先要做的就是拿到WebRoot/upload目录下的所有文件,显示到一个列表上,然后点击下载.
2)Action中显示列表和下载的逻辑都在DownAction.java中.
package com.bighuan.e_fileupload;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
* 文件下载Action 1,显示所有要下载的文件列表 2,文件下载
*
* @author bighuan
*
*/
public class DownAction extends ActionSupport {
// *********1,显示所有要下载的文件列表*********
public String list() throws Exception {
// 拿到upload目录路径
String path = ServletActionContext.getServletContext().getRealPath(
"/upload");
// 目录对象
File file = new File(path);
// 得到所有要下载的文件的文件名
String[] fileNames = file.list();
// 保存
ActionContext ac = ActionContext.getContext();
// 得到代表request的map
// Map<String, Object> request1 = ac.getContextMap();下面那行代码等价于这行
Map<String, Object> request = (Map<String, Object>) ac.get("request");
request.put("fileNames", fileNames);
return "list";
}
// *********2,文件下载*********
// 获取下载文件的文件名
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
// 处理传入的参数中中文乱码的问题(get提交)
try {
fileName = new String(fileName.getBytes("ISO8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// 把处理好的文件名赋值
this.fileName = fileName;
}
// 2,下载提交的业务方法(在struts.xml中配置返回stream)
public String down() throws Exception {
return "download";
}
// 3,返回文件流的方法
public InputStream getAttriInputStream() {
return ServletActionContext.getServletContext().getResourceAsStream(
"/upload/" + fileName);
}
// 4,下载显示的文件名(浏览器显示的文件名)
public String getDownFileName() {
// 需要进行中文编码
try {
// 浏览器显示时的名字
fileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return fileName;
}
}
3)list()方法是获得所有的WebRoot/upload目录下的文件的文件名,然后存入域对象中.在list.jsp页面显示出来.
<table border="1" width="60%" cellpadding="5" cellspacing="0" align="center">
<tr>
<td>序号</td>
<td>文件名</td>
<td>操作</td>
</tr>
<%--遍历 --%>
<c:forEach var="fileName" items="${requestScope.fileNames }" varStatus="varSta">
<tr>
<td>${varSta.count }</td>
<td>${fileName }</td>
<td>
<%--<a href="${pageContext.request.contextPath }/down_down">下载</a>--%>
<%--构建一个url --%>
<c:url var="url" value="down_down">
<c:param name="fileName" value="${fileName }"></c:param>
</c:url>
<a href="${url }">下载</a>
</td>
</tr>
</c:forEach>
</table>
4)点击list.jsp页面的下载,就访问Action中的down()方法,返回"download",这个方法内并没有具体的逻辑,只是返回一个字符串而已.处理下载的逻辑在struts.xml中配置即可.
<package name="file_upload" extends="struts-default">
<result name="success">/e/success.jsp</result>
<!-- 配置错误视图 -->
<result name="input">/e/error.jsp</result>
</action>
<action name="down_*" class="com.bighuan.e_fileupload.DownAction" method="{1}">
<!-- 显示下载列表 -->
<result name="list">/e/list.jsp</result>
<!-- 下载操作 -->
<result name="download" type="stream">
<!-- struts-default.xml <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> -->
<!-- 调用Action中返回流的方法 -->
<!-- 允许下载的文件的类型:指定为所有的二进制文件类型 -->
<param name="contentType">application/octet-stream</param>
<!-- 对应的是Action中的属性 : getAttriInputStream()-->
<param name="inputName">attriInputStream</param>
<!-- 下载头:包括浏览器显示的文件名 -->
<!-- ${downFileName}:$是struts中在配置文件中的取值符号,不是el,去对应的Action中找downFileName属性 -->
<param name="contentDisposition">attachment;filename=${downFileName}</param>
<!-- 缓冲区大小设置 -->
<param name="bufferSize">1024</param>
</result>
</action>
</package>
通过配置<result name="download" type="stream">...</result>来实现下载的逻辑.
a)为了方便,就将contentType配置为二进制文件
b)必须要得到相应要下载文件的流,这个流通过attriInputStream;来获得,而attriInputStream对应于DownAction.java中的getAttriInputStream()方法,通过这个方法的到输入流.
c)filename和上面那种方式差不多,也是通过属性获得,Action类中有一个getDownFileName()方法.
d)bufferSize就是设置缓存区大小了.
5)因为是get URL方式下载,所以要注意文件名的编码问题,在Action中做了处理.
三,总结
OK,到此结束!加油!!!