在之前的文章中我们讲了下文件上传,今天我们来说一下文件的下载。总的来说,文件下载有下面三种方式来实现。下面我们来一一介绍一下。
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="下载文件" οnclick="doDownLoad('fileName1');" /></td>
</tr>
<tr>
<td>文件2</td>
<td><input type="button" value="下载文件" οnclick="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="下载文件" οnclick="doDownLoad('fileName1');" /></td>
</tr>
<tr>
<td>文件2</td>
<td><input type="button" value="下载文件" οnclick="doDownLoad('fileName2');" /></td>
</tr>
</table>
</body>
</html>
后台下载逻辑同上面的。