Struts2实现文件的下载
编程技术  /  houtizong 发布于 3年前   76
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作用域中}@Overridepublic void setServletContext(ServletContext context) {this.application = context;}@Overridepublic void setServletRequest(HttpServletRequest request) {this.request = request;}}把文件列表放入request作用域中,所以在此Action中实现了ServletRequestAware, ServletContextAware这两个接口,使用依赖注入的方式获得request,也可以使用以下两种方式直接操作:
ActionContextActionContext.getContext().put("names", listNames);ServletActionContext.getRequest().setAttribute("names", listNames);以上两种方式都可以将names放到request的作用域中
<%List<String> fileNames = (List<String>) request.getAttribute("names");for (String name : fileNames) {%><a href="download.action?filename=<%=name%>"><%=name%></a><br/><%}%>获取到ListFileAction放到request作用域的names的值,然后遍历出来,使用超链接的形式实现文件下载的请求
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";}@Overridepublic void setServletRequest(HttpServletRequest request) {this.request = request;}@Overridepublic void setServletContext(ServletContext context) {this.application = context;}}在下载处理类中获取到文件名后拼接到下载路径实现对某个文件的下载。
<!-- 文件下载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文件下载的基本组成部分。
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>翻开这个类,就可以发现定义了四个变量:
...protected String contentType="text/plain";//文件内容类型protected String contentLength;//长度protected String contentDisposition="inline";//默认方式为inlineprotected String inputName="inputStream"; //inputStream的名称protected String inputStream inputStream; //输入流,用于读取文件protected int bufferSize=1024;//设置缓冲区大小...
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的操作(翻翻源码对自己是有好处滴~)
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接