在之前的文章中我们讲了下文件上传,今天我们来说一下文件的下载。总的来说,文件下载有下面三种方式来实现。下面我们来一一介绍一下。
Webx特有的方式
这种方式需要分两种情况来讲解。
情况一:
如果需要下载的页面没有处理类的。什么意思?比如说你发了一个请求,找到了你对应的页面,但是后台却没有响应的请求处理类来处理你的请求。对于这样的页面,你直接提交form表单就相当于是发了一次ajax请求,页面是不会进行刷新的。请看代码如下:
http://localhost:8080/MyWebxTest/down_load_file.htm
如果有这样的一个请求,但是后台没有这个请求的处理类,页面如下:
$page.setTitle("下载文件") <html> <head> <script type="text/javascript" src="static/js/jquery-2.1.4.min.js"></script> <script type="text/javascript"> function doDownLoad(fileName){ //$("input[name='fileName']").val(fileName); //$("#fileForm").submit(); //$("#fileForm").action="file_load.do"; $('#showValue').val('zhangsanlisi'); $("#fileForm").submit(); } </script> </head> <body> #*<form id="fileForm" method="post" action="file_load.do"> <input type="hidden" name="fileName" /> </form> *# <form id="fileForm" method="post" action=""> <input type="hidden" name="fileName" /> <input type="hidden" name="action" value="down_load_fileAction" /> </form> <input id="showValue" /> <table> <tr> <td>文件1</td> <td><input type="button" value="下载文件" onclick="doDownLoad('fileName1');" /></td> </tr> <tr> <td>文件2</td> <td><input type="button" value="下载文件" onclick="doDownLoad('fileName2');" /></td> </tr> </table> </body> </html>
如果点击了下载文件,会触发一个onclick事件,这个事件会提交一个表单,发送请求,发送的请求为:
http://localhost:8080/MyWebxTest/down_load_file.htm
这个时候你也许会有疑问,这个不就是访问这个页面的请求吗?没错,提交表单的时候发送的就是访问页面的请求,即是Referer。那么它是怎么找对应的处理类的呢?请注意这句话:<input type="hidden" name="action" value="down_load_fileAction"
/> Webx就是根据这个隐藏的action,来找他相应的处理类的。请注意的是处理类的路径,此类一定要放在
<services:module-loader> <ml-factories:class-modules> <search-packages type="$1" packages="com.alibaba.webx.MyWebxTest.myWebX.module.*"/> </ml-factories:class-modules> </services:module-loader>
<search-packages/>这个标签的包的下一级包action里。如图所示:
后台代码如下:
package com.alibaba.webx.MyWebxTest.myWebX.module.action; import static com.alibaba.citrus.util.StringEscapeUtil.escapeURL; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import com.alibaba.citrus.turbine.Context; /** * * @author zkn 2016-06-28 * */ public class DownLoadFileAction { @Autowired private HttpServletResponse response; public void execute(Context context){ String fileName = "G:/qqq.txt"; BufferedReader br = null; BufferedWriter bw = null; try { String loadFileName = "\"" + escapeURL("zhangsan.txt") + "\"";; //重置输出流 response.reset(); //设置下载框 response.setHeader("Content-disposition", "attachment; filename=" + loadFileName); //设置文件类型 response.setContentType("text/plain;charset=UTF-8"); br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName))); bw = new BufferedWriter(new OutputStreamWriter(response.getOutputStream())) ; String lineStr = null; while((lineStr = br.readLine()) != null){ bw.write(lineStr); } bw.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ if(br != null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if(bw != null){ try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
情况二:
这种情况是下载页面有对应的处理类:
这种方式和上面那种方式唯一不同的地方在于,后台在处理完下载的逻辑之后,它会再次走一遍下载页面的处理类。什么意思呢?是这样的:还是上面的那个请求,
http://localhost:8080/MyWebxTest/down_load_file.htm
对于这个请求,后台有一个处理类为DownLoadFile.java。页面还是上面的那个页面,如果这个时候你点了下载文件,它会在处理完DownLoadFileAction.java这个类之后,再次处理DownLoadFile.java这个类.同样的它也不会刷新页面,但是有可能会出现隐藏的问题。不建议使用这种方式。
window.open的方法
这种方法呢,只需要在js里写一个window.open就可以了。请求方式最好是.do。这种方式就不过多介绍了,唯一需要注意的是,下载逻辑的后台处理类要放在screen下面,如图:
部分代码如下:
function doDownLoad(fileName){ //$("input[name='fileName']").val(fileName); //$("#fileForm").submit(); //$("#fileForm").action="file_load.do"; $('#showValue').val('zhangsanlisi'); $("#fileForm").submit(); window.open('file_load.do'); }
传统的方式
什么是传统的方式呢?就是我们写一个form表单,在form的表单action里放入我们的请求。这种方式需要注意的是:form表单里不能有name=‘action’的input域。一定不能有。这种方式大家也都很熟悉了,也就没什么可说的了。代码如下:
$page.setTitle("下载文件") <html> <head> <script type="text/javascript" src="static/js/jquery-2.1.4.min.js"></script> <script type="text/javascript"> alert('zhangsanlisi'); function doDownLoad(fileName){ //$("input[name='fileName']").val(fileName); //$("#fileForm").submit(); //$("#fileForm").action="file_load.do"; $('#showValue').val('zhangsanlisi'); $("#fileForm").submit(); //window.open('file_load.do'); } </script> </head> <body> <form id="fileForm" method="post" action="file_load.do"> <input type="hidden" name="fileName" /> </form> #*<form id="fileForm" method="post" action=""> <input type="hidden" name="fileName" /> <input type="hidden" name="action" value="down_load_fileAction" /> </form> *# <input id="showValue" /> <table> <tr> <td>文件1</td> <td><input type="button" value="下载文件" onclick="doDownLoad('fileName1');" /></td> </tr> <tr> <td>文件2</td> <td><input type="button" value="下载文件" onclick="doDownLoad('fileName2');" /></td> </tr> </table> </body> </html>
后台下载逻辑同上面的。