最近项目中用到,所以研究了下
现在贴出代码
注意看这个annotation写的action,不是在struts.xml中配的
这样写方便维护
/**
* 下载action
* @return
*/
@Action(value = "downloadlucky",
results = {
@Result(name = Constants.SUCCESS, type="stream" //, location="/website/lucky.jsp"因为有stream出来,所以定向到location会"断流",这里可以不写
,params = {"contentType", "application/msexcel"
, "contentDisposition", "attachment;filename=${filename}" // attachment表示以附件形式打开,inline表示在浏览器中打开,filename为保存时的名字
, "bufferSize", "10240" //缓存
, "inputName", "inputStream"//对应上面的public InputStream getInputStream() 方法
}
)
}
)
public String downloadlucky() {
try{
log.info("begin method:downloadlucky()");
fullPathName = "/WEB-INF/aa.xls";
filename = "我爱你.xls";
//使中文文件名不出现乱码
filename = new String(filename.getBytes(),"iso8859-1");
log.info("end method:downloadlucky()");
return SUCCESS;
}catch (DataAccessException ex) {
log.info("end method:downloadlucky()");
log.error("", ex);
throw ex;
} catch (BusinessAccessException ex) {
log.info("end method:downloadlucky()");
log.error("", ex);
throw ex;
} catch (Exception ex) {
log.info("end method:downloadlucky()");
log.error("", ex);
throw new ActionAccessException();
} catch (Throwable ex) {
log.info("end method:downloadlucky()");
log.error("", ex);
throw new ActionAccessException();
}
}
必须有一个方法,返回InputStream
//返回一个InputStream类型值
public InputStream getInputStream() throws Exception {
System.out.println(fullPathName);
InputStream is = ServletActionContext.getServletContext().getResourceAsStream (fullPathName);
return is;
}
fullPathName,filename 都需要get(),set()下
//文件路径
private String fullPathName;
//下载时的默认名字
private String filename;
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getFullPathName() {
return fullPathName;
}
public void setFullPathName(String fullPathName) {
this.fullPathName = fullPathName;
}
action的 params中的 "inputName", "inputStream" 指的是inputName对应getInputStream方法,当然,如果inputStream改成downloadStream ,那么对应的方法也改为public InputStream getDownloadStream()
目前这段代码没有放,不过也贴出来看下
/*
* 获取目标文件在服务器中保存的目录。若不在这个目录则拒绝下载,否则,
* 稍微精通struts2的人可能试图获取WEB-INF下的文件,那就不安全了。
*/
String downloadDir = ServletActionContext.getServletContext()
.getRealPath("/upload");
// 获取目标文件的绝对路径
String downloadFile = ServletActionContext.getServletContext()
.getRealPath(inputPath);
/*
* 防止企图下载不在目录downloadDir下的文件,以保障安全。若不在这个目
* 录则拒绝下载,否则,稍微精通struts2的人可能试图获取WEB-INF下 的文件,那就不安全了。
*/
if (!downloadFile.startsWith(downloadDir)) {
return null;
}
OK,记录到此结束。