页面截图如下面形式:
序号 文件名称 文件类型 文件记录数 生成文件日期 下载次数 操作
1 e_20100909.xls EXCEL 222 4 下载
2 A_20100909.xls EXCEL 22 5 下载
3 数据源_20100909.txt TXT 1 33 下载
我的思路是点击下载后,通过异步请求,将文件名传到后台,调用struts2自带的下载文件功能,根据文件名打开文件流返回到浏览器。。。
但是始终不成功,还是经验不足啊,希望高人指点,提供一个好的解决办法:
26 个解决方案
#1
我的配置文件:
后台Action:
Extjs页面用的是异步请求向后台传要下载的文件名参数:
<!-- 文件下载,支持中文附件名 -->
<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,
}
#2
请教高人啦!
#3
下载不需要异步的,直接加个文件链接。然后通过文件路径在服务器下载即可。
//文件共享下载
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,
}
#4
我之前就是在网页上拼接URL,然后调用window.open(url),我要下载的文件只有三种格式TXT,EXCEL和XML;这种方式有弊端,不能满足需求:
如果文件名有中文,则服务器不识别;通过改变tomcat的默认编码为UTF-8虽然可以解决这个问题,但是如果是TXT文件就直接在浏览器中打开了,不能弹出文件保存对话框;
我的想法就是通过异步将下载文件名传到后台,然后调用struts2自带的下载文件功能下载服务器指定目录下的文件。高人指点啊!!!
如果文件名有中文,则服务器不识别;通过改变tomcat的默认编码为UTF-8虽然可以解决这个问题,但是如果是TXT文件就直接在浏览器中打开了,不能弹出文件保存对话框;
我的想法就是通过异步将下载文件名传到后台,然后调用struts2自带的下载文件功能下载服务器指定目录下的文件。高人指点啊!!!
#5
我的想法就是:前提不改变tomcat的默认编码;通过异步将下载文件名传到后台,然后调用struts2自带的下载文件功能下载服务器指定目录下的文件。高人指点啊!!!
#6
下载的时候乱码我也遇到过了,这个还是可以搞定的。
分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")
#7
谢谢您耐心的给予回复!这两天有事没上来,现在要继续解决这个问题,麻烦帮我看下!
现在情况是这样的:
struts.xml下载部分的配置如下:
后台Action:
Ext页面:
执行流程==>点击下载后执行Action的download()方法返回SUCCESS;
后台打印的测试语句如下:
===DOWNLOADFILEPATH+fileName===>/shareDownload/数据源_20100909.txt
getInputStream fileName=>数据源_20100909.txt realPath=>/shareDownload/数据源_20100909.txt
可是并没有弹出文件保存对话框,但是也没有报错;不知道是什么原因呢?是哪里配置错了,还是这种下载方式行不通呢?还请指教!!!!!
先去睡觉了......好困啊!
现在情况是这样的:
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
可是并没有弹出文件保存对话框,但是也没有报错;不知道是什么原因呢?是哪里配置错了,还是这种下载方式行不通呢?还请指教!!!!!
先去睡觉了......好困啊!
#8
hoojo大哥,帮忙看看!!!
#9
你的想法是好的,但是ajax好像不能实现异步下载的功能。如果要无刷新下载可以将
下载的资源的url赋给一个隐藏的iframe,用iframe请求下载地址完成下载功能。
#10
谢谢您啦!如果不用异步,但是又不脱离原来的Ext页面,还有其他的下载方式吗?我在网上找了很久,也没有找到好的解决方案!
#11
还有一种做法就是不需要后台Action处理,直接在页面上将资源的URL地址拼接,比如:url="/emc/shareDownload/e_2010819.txt",其中/emc为web应用的根目录,然后掉用window.open(url);可以打开一个窗口;但是当这个文件名为中文,比如:url="/emc/shareDownload/数据源_2010819.txt",这时就不行了;
还望高人指点啊!!!!!
还望高人指点啊!!!!!
#12
求达人指点......
#13
你这样是直接链接到你的资源,并没有用struts action;
你下载的Action干什么用的,你写了这么多还配置了xml。你又不用它?
用FileDownloadAction 下载传递参数即可
url="/emc/shareDownload/e_2010819.txt";
<a href="FileDownloadAction.action?fileName=e_2010819.txt">下载</a>
#14
#15
那是我采用的第一种思路,没走通;
我现在就是想问题简单化,不用Action处理了,直接window.open()打开资源;文件名是英文可以,一旦是中文就不行了,会报错,即资源找不到,报错:HTTP Status 404 - /emc/shareDownload/%E6%95%B0%E6%8D%AE%E6%BA%90_2010817.txt
#16
所以就用action啊,action里面转码就可以了。上面不是给你说了么?
look #6
#17
那种方式我用过了啊!乱码问题是可以解决,但那不是困难所在;关键是得不到文件流,没有出现预期的文件保存对话框啊!!!我在 #7楼已经提出过这个问题;就是上面Action里面贴出来的那句
我认为这句话执行完后,应该是会有个文件保存对话框的;但是什么都没有,后台也没报错。。。。。。
//返回指定文件对应的输入流
return ServletActionContext.getServletContext().getResourceAsStream(realPath);
#18
并不是这句话运行完了弹出,你先把struts2的基本下载搞好了,这里的下载和其他的下载是一样的
只要你在jsp页面能下载,在js中也可以下载的
就是多一步js将中文件名转码,然后在action再转码
可以用js进行编码传递过去
fileName = encodeURI(encodeURI("js客户端中文参数"))
window.open("url?fileName=" + fileName);
服务器端解码
URLDecoder.decode(fileName, "utf-8")
#19
给个URL即可。
#20
中文名的话,Tomcat找不到资源
#21
看18# 转换下就可以
#22
谢谢大侠的指点!呵呵...问题终于解决了!
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
可以去节贴了!!!!!!!!!
#23
代码贴出,希望能给遇到相似问题的朋友一点启发!
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
#24
代码贴出,希望能给遇到相似问题的朋友一点启发!
页面代码上面也有,关键点:
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
页面代码上面也有,关键点:
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
#25
ext下载 急用 我初学者 能否加个扣扣 给我讲下 450198392 谢谢
#26
还是没有解决问题,希望能给个详细的指导。
#1
我的配置文件:
后台Action:
Extjs页面用的是异步请求向后台传要下载的文件名参数:
<!-- 文件下载,支持中文附件名 -->
<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,
}
#2
请教高人啦!
#3
下载不需要异步的,直接加个文件链接。然后通过文件路径在服务器下载即可。
//文件共享下载
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,
}
#4
我之前就是在网页上拼接URL,然后调用window.open(url),我要下载的文件只有三种格式TXT,EXCEL和XML;这种方式有弊端,不能满足需求:
如果文件名有中文,则服务器不识别;通过改变tomcat的默认编码为UTF-8虽然可以解决这个问题,但是如果是TXT文件就直接在浏览器中打开了,不能弹出文件保存对话框;
我的想法就是通过异步将下载文件名传到后台,然后调用struts2自带的下载文件功能下载服务器指定目录下的文件。高人指点啊!!!
如果文件名有中文,则服务器不识别;通过改变tomcat的默认编码为UTF-8虽然可以解决这个问题,但是如果是TXT文件就直接在浏览器中打开了,不能弹出文件保存对话框;
我的想法就是通过异步将下载文件名传到后台,然后调用struts2自带的下载文件功能下载服务器指定目录下的文件。高人指点啊!!!
#5
我的想法就是:前提不改变tomcat的默认编码;通过异步将下载文件名传到后台,然后调用struts2自带的下载文件功能下载服务器指定目录下的文件。高人指点啊!!!
#6
下载的时候乱码我也遇到过了,这个还是可以搞定的。
分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")
#7
谢谢您耐心的给予回复!这两天有事没上来,现在要继续解决这个问题,麻烦帮我看下!
现在情况是这样的:
struts.xml下载部分的配置如下:
后台Action:
Ext页面:
执行流程==>点击下载后执行Action的download()方法返回SUCCESS;
后台打印的测试语句如下:
===DOWNLOADFILEPATH+fileName===>/shareDownload/数据源_20100909.txt
getInputStream fileName=>数据源_20100909.txt realPath=>/shareDownload/数据源_20100909.txt
可是并没有弹出文件保存对话框,但是也没有报错;不知道是什么原因呢?是哪里配置错了,还是这种下载方式行不通呢?还请指教!!!!!
先去睡觉了......好困啊!
现在情况是这样的:
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
可是并没有弹出文件保存对话框,但是也没有报错;不知道是什么原因呢?是哪里配置错了,还是这种下载方式行不通呢?还请指教!!!!!
先去睡觉了......好困啊!
#8
hoojo大哥,帮忙看看!!!
#9
你的想法是好的,但是ajax好像不能实现异步下载的功能。如果要无刷新下载可以将
下载的资源的url赋给一个隐藏的iframe,用iframe请求下载地址完成下载功能。
#10
谢谢您啦!如果不用异步,但是又不脱离原来的Ext页面,还有其他的下载方式吗?我在网上找了很久,也没有找到好的解决方案!
#11
还有一种做法就是不需要后台Action处理,直接在页面上将资源的URL地址拼接,比如:url="/emc/shareDownload/e_2010819.txt",其中/emc为web应用的根目录,然后掉用window.open(url);可以打开一个窗口;但是当这个文件名为中文,比如:url="/emc/shareDownload/数据源_2010819.txt",这时就不行了;
还望高人指点啊!!!!!
还望高人指点啊!!!!!
#12
求达人指点......
#13
你这样是直接链接到你的资源,并没有用struts action;
你下载的Action干什么用的,你写了这么多还配置了xml。你又不用它?
用FileDownloadAction 下载传递参数即可
url="/emc/shareDownload/e_2010819.txt";
<a href="FileDownloadAction.action?fileName=e_2010819.txt">下载</a>
#14
#15
那是我采用的第一种思路,没走通;
我现在就是想问题简单化,不用Action处理了,直接window.open()打开资源;文件名是英文可以,一旦是中文就不行了,会报错,即资源找不到,报错:HTTP Status 404 - /emc/shareDownload/%E6%95%B0%E6%8D%AE%E6%BA%90_2010817.txt
#16
所以就用action啊,action里面转码就可以了。上面不是给你说了么?
look #6
#17
那种方式我用过了啊!乱码问题是可以解决,但那不是困难所在;关键是得不到文件流,没有出现预期的文件保存对话框啊!!!我在 #7楼已经提出过这个问题;就是上面Action里面贴出来的那句
我认为这句话执行完后,应该是会有个文件保存对话框的;但是什么都没有,后台也没报错。。。。。。
//返回指定文件对应的输入流
return ServletActionContext.getServletContext().getResourceAsStream(realPath);
#18
并不是这句话运行完了弹出,你先把struts2的基本下载搞好了,这里的下载和其他的下载是一样的
只要你在jsp页面能下载,在js中也可以下载的
就是多一步js将中文件名转码,然后在action再转码
可以用js进行编码传递过去
fileName = encodeURI(encodeURI("js客户端中文参数"))
window.open("url?fileName=" + fileName);
服务器端解码
URLDecoder.decode(fileName, "utf-8")
#19
给个URL即可。
#20
中文名的话,Tomcat找不到资源
#21
看18# 转换下就可以
#22
谢谢大侠的指点!呵呵...问题终于解决了!
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
可以去节贴了!!!!!!!!!
#23
代码贴出,希望能给遇到相似问题的朋友一点启发!
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
#24
代码贴出,希望能给遇到相似问题的朋友一点启发!
页面代码上面也有,关键点:
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
页面代码上面也有,关键点:
window.location = encodeURI(encodeURI('download.html?path=' + '' + '&fileName=' + fileName));
后台代码在上面贴出来:
服务器端解码:URLDecoder.decode(fileName, "utf-8")
再次感谢hoojo
#25
ext下载 急用 我初学者 能否加个扣扣 给我讲下 450198392 谢谢
#26
还是没有解决问题,希望能给个详细的指导。