后台是Struts2,页面是一个GridPanel的文件列表;要求点击“下载”后,弹出文件保存窗口;页面截图如下面形式: 序号 文件名称 文件类型 文件记录数 生成文件日期 下载次数 操作
1 e_20100909.xls EXCEL 222 4 下载
2 A_20100909.xls EXCEL 22 5 下载
3 数据源_20100909.txt TXT 1 33 下载
我的思路是点击下载后,通过异步请求,将文件名传到后台,调用struts2自带的下载文件功能,根据文件名打开文件流返回到浏览器
但是始终不成功,还是经验不足啊,希望高人指点,提供一个好的解决办法:
1 e_20100909.xls EXCEL 222 4 下载
2 A_20100909.xls EXCEL 22 5 下载
3 数据源_20100909.txt TXT 1 33 下载
我的思路是点击下载后,通过异步请求,将文件名传到后台,调用struts2自带的下载文件功能,根据文件名打开文件流返回到浏览器
但是始终不成功,还是经验不足啊,希望高人指点,提供一个好的解决办法:
解决方案 »
- JS的转意问题tree.replace("""," " ")
- 想讨论一下JS模拟加速的算法
- 有JavaScript高手吗????
- 如何修改alert(""),提示弹窗,打开的所在屏幕的位置,和禁止使用键盘回车和空格键来操作这个alert(""),提示弹窗
- extjs4 tabpanel引用其他页面panel时border布局高度不能自动适应
- 当在一文本框中输入数据时,如何取得该文本框的name和value?因为我的文本框是动态生成的,急需得到这两个值。急!急!急!在线等!谢谢
- 为什么调用不到javascript函数?
- 超级郁闷的问题!
- 如何解决层间透明的问题
- 高德地图的点聚合方法
- jquery 如何选中鼠标选中的文字,然后在前后加上标签 就是BBCODE
- 新手,问一个jquery导航栏的问题
<!-- 文件下载,支持中文附件名 -->
<action name="fileDownloadAction" class="com.tydic.emc.webapp.action.sharefile.FileDownloadAction" method="download">
<!-- 初始文件名 -->
<param name="fileName">fileName</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream;charset=ISO8859-1</param>
<param name="inputName">inputStream</param>
<!-- 使用经过转码的文件名作为下载文件名,downloadFileName属性
对应action类中的方法 getDownloadFileName() -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>后台Action:package com.tydic.emc.webapp.action.sharefile;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.Action;public class FileDownloadAction implements Action {
// 初始的通过param指定的文件名属性
private String fileName;
//下载文件原始存放路径
private final static String DOWNLOADFILEPATH="/shareDownload/"; public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
try {
fileName = new String(fileName.getBytes("ISO8859-1"),"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.fileName = fileName;
} //从下载文件原始存放路径读取得到文件输出流
public InputStream getInputStream() throws IOException {
//拿到web app的绝对根路径
String rootpath = ServletActionContext.getServletContext().getRealPath("/");
//要下载的文件路径及文件名
String fileUrl = rootpath+"shareDownload\\"+fileName;
System.out.println("===fileUrl===>"+fileUrl);
//return ServletActionContext.getServletContext().getResourceAsStream(fileUrl);
return new ByteArrayInputStream("Struts 2 下载示例".getBytes());
}
/** 提供转换编码后的供下载用的文件名 */
public String getDownloadFileName() {
String downloadFileName = fileName;
try {
downloadFileName = new String(downloadFileName.getBytes("ISO8859-1"), "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downloadFileName;
}
/**
* 下载文件
*
* @return
*/
public String download() {
System.out.println("=====fileName====>"+fileName);
System.out.println("===DOWNLOADFILEPATH+fileName===>"+DOWNLOADFILEPATH+fileName);
return SUCCESS;
}
public String execute() {
return SUCCESS;
}}
Extjs页面用的是异步请求向后台传要下载的文件名参数: //文件共享下载
function downLoadFile(){
//拿到文件名和文件类型;
var selectedRecords = tableGrid.getSelectionModel().getSelections();
var fileName = selectedRecords[0].get('fileName');
var fileType = selectedRecords[0].get('fileType');
var selectedId = "";
var selectedId = "&selectedId="+selectedRecords[0].get('id');
//var params = "&fileName="+encodeURI(encodeURI(fileName));
var params = "&fileName="+fileName;
alert("params="+params);
var url = "/emc/shareDownload/"+fileName;
//window.open(url);
//异步请求,调用struts2的文件下载功能?
Ext.Ajax.request({
method: 'POST',
//向后台Action传表单参数
url: '<c:url value="/sharefile/fileDownloadAction!download.html?ajax=true"/>' + params,
//成功返回后调用函数
success: function(){
alert("返回成功!");
//调用update函数,更新下载次数
update();
}
});
// url: '<c:url value="/sharefile/shareFileAction!downLoadFile.html?ajax=true"/>' + params,
}
下载不需要异步的,直接加个文件链接。然后通过文件路径在服务器下载即可。
//文件共享下载
function downLoadFile(){
//拿到文件名和文件类型;
var selectedRecords = tableGrid.getSelectionModel().getSelections();
var fileName = selectedRecords[0].get('fileName');
var fileType = selectedRecords[0].get('fileType');
var selectedId = "";
var selectedId = "&selectedId="+selectedRecords[0].get('id');
//var params = "&fileName="+encodeURI(encodeURI(fileName));
var params = "&fileName="+fileName;
alert("params="+params);
var url = "/emc/shareDownload/"+fileName;
//window.open(url);//这种方式不行么
//异步请求,调用struts2的文件下载功能?
Ext.Ajax.request({
method: 'POST',
//向后台Action传表单参数
url: '<c:url value="/sharefile/fileDownloadAction!download.html?ajax=true"/>' + params,//再说你这里的url好像不对啊,/sharefile/fileDownloadAction.action?download.html&ajax=true
fileDownloadAction这个action下载已经配置了method是download,不带download
//成功返回后调用函数
success: function(){
alert("返回成功!");
//调用update函数,更新下载次数
update();
}
});
// url: '<c:url value="/sharefile/shareFileAction!downLoadFile.html?ajax=true"/>' + params,
}
如果文件名有中文,则服务器不识别;通过改变tomcat的默认编码为UTF-8虽然可以解决这个问题,但是如果是TXT文件就直接在浏览器中打开了,不能弹出文件保存对话框;
我的想法就是通过异步将下载文件名传到后台,然后调用struts2自带的下载文件功能下载服务器指定目录下的文件。高人指点啊!!!
分get和默认方式,如果是get传递参数有中文就会乱码
public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
try {
fileName = new String(fileName.getBytes(),"GBK");
HttpSerlvetRequest request = ServletActionContext.getRequest();
if (request.getMethod().equalsIgnoreCase("get")) {//get传参
fileName = new String(fileName.getBytes("ISO8859-1"),"GBK");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.fileName = fileName;
}
就是在下载的时候,如果文件名乱码了会有异常的对不对。你就用这种方式判断
首次好像不会乱码,你要分情况处理。
这个思路肯定是可以解决乱码的。还有如果是服务器不能识别的文件名称
可以用js进行编码传递过去
fileName = encodeURI(encodeURI("js客户端中文参数"))
window.open("url?fileName=" + fileName);
服务器端解码
URLDecoder.decode(fileName, "utf-8")
现在情况是这样的:struts.xml下载部分的配置如下: <package name="sharefile" extends="default" namespace="/sharefile">
<action name="shareFileAction!*" class="shareFileAction">
<result name="listShareFiles">/WEB-INF/pages/sharefile/shareFileList.jsp</result>
</action>
<!-- 文件下载,支持中文附件名 -->
<action name="fileDownloadAction!*" class="com.tydic.emc.webapp.action.sharefile.FileDownloadAction">
<!-- 初始文件名 -->
<param name="fileName">\shareDownload\数据源_20100909.txt</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream;charset=ISO8859-1</param>
<param name="inputName">inputStream</param>
<!-- 使用经过转码的文件名作为下载文件名,downloadFileName属性
对应action类中的方法 getDownloadFileName() -->
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
</package>
后台Action:package com.tydic.emc.webapp.action.sharefile;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.Action;
import com.sun.java_cup.internal.internal_error;public class FileDownloadAction implements Action {
// 初始的通过param指定的文件名属性
private String fileName ;
//下载文件原始存放路径
private final static String DOWNLOADFILEPATH="/shareDownload/"; public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
try {
fileName = new String(fileName.getBytes("ISO8859-1"),"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.fileName = fileName;
} //从下载文件原始存放路径读取得到文件输出流
public InputStream getInputStream() throws IOException {
//拿到web app的绝对根路径
//String rootpath = ServletActionContext.getServletContext().getRealPath("/");
//要下载的文件路径及文件名 String realPath=rootpath+"shareDownload\\"+fileName;
String realPath="/shareDownload/"+fileName;
System.out.println("getInputStream fileName=>"+fileName+" realPath=>"+realPath);
InputStream in=ServletActionContext.getServletContext().getResourceAsStream(realPath);
/*
int b = 0;
while((b=in.read())!=-1) {
System.out.println((char)b);
}
*/
if(null==in){
System.out.println("Can not find a java.io.InputStream with the name [inputStream] in the invocation stack. Check the <param name=\"inputName\"> tag specified for this action.检查action中文件下载路径是否正确.");
}
//返回指定文件对应的输入流
return ServletActionContext.getServletContext().getResourceAsStream(realPath);
}
/** 提供转换编码后的供下载用的文件名 */
public String getDownloadFileName() {
String downloadFileName = fileName;
try {
downloadFileName = new String(downloadFileName.getBytes("ISO8859-1"), "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downloadFileName;
}
/**
* 下载文件
*
* @return
*/
public String download() {
System.out.println("===DOWNLOADFILEPATH+fileName===>"+DOWNLOADFILEPATH+fileName);
return SUCCESS;
}
public String execute() {
return SUCCESS;
}
}
Ext页面:<script type="text/javascript">
function downLoad(){
var str = '<a href="#" onclick="javascript:downLoadFile();return false"> <font color="green">下载</font> </a>';
return str;
}
//文件共享下载
function downLoadFile(){
//拿到文件名和文件类型;
var selectedRecords = tableGrid.getSelectionModel().getSelections();
var fileName = selectedRecords[0].get('fileName');
var fileType = selectedRecords[0].get('fileType');
var selectedId = "";
var selectedId = "&selectedId="+selectedRecords[0].get('id');
//var params = "&fileName="+encodeURI(encodeURI(fileName));
var params = "&fileName="+fileName;
alert("params="+params);
var url = "/emc/shareDownload";
//window.open(url+"?fileName="+encodeURI(encodeURI(fileName))); //异步请求,调用struts2的文件下载功能?
Ext.Ajax.request({
method: 'POST',
//向后台Action传表单参数
url: '<c:url value="/sharefile/fileDownloadAction!download.html?ajax=true"/>' + params,
//成功返回后调用函数
success: function(){
alert("返回成功!");
//调用update函数,更新下载次数
update();
}
});
// url: '<c:url value="/sharefile/shareFileAction!downLoadFile.html?ajax=true"/>' + params,
}
//更新下载次数
function update() {
var selectedRecords = tableGrid.getSelectionModel().getSelections();
var selectedId = "";
var selectedId = "&selectedId="+selectedRecords[0].get('id');
Ext.Ajax.request({
method: 'POST',
//向后台Action传表单参数
url: '<c:url value="/sharefile/shareFileAction!update.html?ajax=true"/>' + selectedId,
//成功返回后调用函数
success: function(){
parent.closePopupWin();
//重新加载数据,刷新列表
parent.rightContentFrm.contentWindow.location.reload();
}
});
}</script>执行流程==>点击下载后执行Action的download()方法返回SUCCESS;
后台打印的测试语句如下:
===DOWNLOADFILEPATH+fileName===>/shareDownload/数据源_20100909.txt
getInputStream fileName=>数据源_20100909.txt realPath=>/shareDownload/数据源_20100909.txt 可是并没有弹出文件保存对话框,但是也没有报错;不知道是什么原因呢?是哪里配置错了,还是这种下载方式行不通呢?还请指教!!!!!
先去睡觉了......好困啊!
你的想法是好的,但是ajax好像不能实现异步下载的功能。如果要无刷新下载可以将
下载的资源的url赋给一个隐藏的iframe,用iframe请求下载地址完成下载功能。
还望高人指点啊!!!!!
你这样是直接链接到你的资源,并没有用struts action;
你下载的Action干什么用的,你写了这么多还配置了xml。你又不用它?
用FileDownloadAction 下载传递参数即可
url="/emc/shareDownload/e_2010819.txt";
<a href="FileDownloadAction.action?fileName=e_2010819.txt">下载</a>
我现在就是想问题简单化,不用Action处理了,直接window.open()打开资源;文件名是英文可以,一旦是中文就不行了,会报错,即资源找不到,报错:HTTP Status 404 - /emc/shareDownload/%E6%95%B0%E6%8D%AE%E6%BA%90_2010817.txt
所以就用action啊,action里面转码就可以了。上面不是给你说了么?
look #6
//返回指定文件对应的输入流
return ServletActionContext.getServletContext().getResourceAsStream(realPath);
我认为这句话执行完后,应该是会有个文件保存对话框的;但是什么都没有,后台也没报错
只要你在jsp页面能下载,在js中也可以下载的
就是多一步js将中文件名转码,然后在action再转码
可以用js进行编码传递过去
fileName = encodeURI(encodeURI("js客户端中文参数"))
window.open("url?fileName=" + fileName);
服务器端解码
URLDecoder.decode(fileName, "utf-8")
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")再次感谢hoojo
页面代码上面也有,关键点:
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")再次感谢hoojo