下载

来源:互联网 发布:pc6下载站软件 编辑:程序博客网 时间:2024/04/27 18:38
 下载
==============================
处理下载的类:org.apache.struts2.dispatcher.StreamResult
== 属性 ==
String contentType = "text/plain";       
String contentLength;
String contentDisposition = "inline";    
String inputName = "inputStream";        
InputStream inputStream;                
int bufferSize = 1024;                  
== 说明 == 
contentType
内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片  
用来做动态文件下载的,事先并不知道未来的文件类型是什么,那么我们可以把它的值设置成为:application/octet-stream;charset=ISO8859-1 ,注意一定要加入charset,否则某些时候会导致下载的文件出错
inputName
下载文件的来源流,对应着action类中某个类型为Inputstream的属性名,例如取值为inputStream的属性需要编写getInputStream()方法
contentDisposition
文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。取值为:attachment;filename="struts2.txt",表示文件下载的时候保存的名字应为struts2.txt。如果直接写filename="struts2.txt",那么默认情况是代表inline,浏览器会尝试自动打开它,等价于这样的写法:inline; filename="struts2.txt"
bufferSize
下载缓冲区的大小
 # contentType属性和contentDisposition分别对应着HTTP响应中的头Content-Type和Content-disposition头。
   如:
     HTTP头内容:
     HTTP/1.1 200 OK 
     Server: Apache-Coyote/1.1 
     Content-disposition: attachment;filename="struts2.txt" 
     Content-Type: text/plain 
     Transfer-Encoding: chunked 
     Date: Sun, 02 Mar 2008 02:58:25 GMT
----------
  action
----------

Class DownloadAction extends ActionSupport {
 private String path;
 // setter... getter...
 //必须返回一个输入流,该流是让用户下载的
 public InputStream getDownloadFile() {
 
  //从某个文件获得流 --这里是获得项目root下upload下的文件
  //也可以 new FileInputStream("c:/test.text");
  return ServletActionContext.getServletContext().getResourceAsStream("/upload/struts2.ppt");
  
 }
 public String execute() throws Exception {
  return SUCCESS;
 }
}
-----------
struts.xml
-----------

 <action name="download" class="org.scorpio.jh.struts2.upload.action.DownloadAction">
  
   <!-- 依赖注入文件路径 -->
   <param name="path">/download/xhtml.txt</param>
   
   <!-- 设置结果类型为 流 -->
   <result name="success" type="stream">
    
    <!-- 设置内容类型 -->
    <param name="contentType">text/plain</param>
    
    <!-- 设置下载文件的名字  attachment:作为附件,filename=:指定下载文件名-->
    <param name="contentDisposition">attachment;filename="xhtml.txt"</param>
   
    <!-- 设置下载文件的输入流对应的方法 downloadFile对应DownloadAction中的getDownloadFile()-->
    <param name="inputName">downloadFile</param>
   
    <!-- 指定下载文件的缓冲大小 --> 
    <param name="bufferSize">4096</param>
   </result>
  </action>
 
==========================
  解决下载文件名中文问题
==========================
1.在下载action获取文件名的方法中先进行转码然后再返回
   path = new String( path.getBytes(), "ISO-8859-1" );

2.xml配置文件动态的获取path的值
   <param name="contentDisposition">attachment;filename="${path}"</param>
   ${path} 用于动态的获取所配置的action中path成员的值,相当于调用getPath()方法
-------
action
-------
private String path;
 
public String getPath() {
  
 try {               //转换成西欧字符集
  path = new String( path.getBytes(), "ISO-8859-1" );
 } catch (UnsupportedEncodingException e) {
  e.printStackTrace();
 } 
  
 return path;
}
public void setPath(String path) {
 this.path = path;
}
---------------
   struts.xml
---------------
<action name="download" class="org.scorpio.jh.struts2.upload.action.DownloadAction">
 
 <param name="path">/download/wmlscript实例.txt</param>
 <result name="success" type="stream">
  <param name="contentType">text/plain</param>
  <!-- 动态的获取 DownloadAction的path属性 -->
  <param name="contentDisposition">attachment;filename="${path}"</param>
  <param name="inputName">downloadFile</param>
  <param name="bufferSize">4096</param>
 </result>
</action>
 
=================
    安全隐患
=================
访问者如果精通Struts 2的话,它可能使用这样的带有表单参数的地址来访问:
[url]http://localhost:8080/struts2hello/download3.action?inputPath=/WEB-INF/web.xml[/url],这样的结果就是下载后的文件内容是您系统里面的web.xml的文件的源代码,甚至还可以用这种方式来下载任何其它JSP文件的源码。这对系统安全是个很大的威胁。作为一种变通的方法,读者最好是从数据库中进行路径配置,然后把Action类中的设置inputPath的方法统统去掉,简言之就是删除这个方法定义:
public void setPath(String path) { 
 this.path = path; 
}
而实际情况则应该成为 download.action?fileid=1 类似于这样的形式来进行。或者呢,读者可以在execute()方法中进行路径检查,如果发现有访问不属于download下面文件的代码,就一律拒绝,不给他们返回文件内容。例如,我们可以把刚才类中的execute()方法加以改进,成为这样:
public String execute() throws Exception {
// 文件下载目录路径
String downloadDir = ServletActionContext.getServletContext().getRealPath("/download");
// 文件下载路径
String downloadFile = ServletActionContext.getServletContext().getRealPath(inputPath);
java.io.File file = new java.io.File(downloadFile);
downloadFile = file.getCanonicalPath();// 真实文件路径,去掉里面的..等信息
// 发现企图下载不在 /download 下的文件, 就显示空内容 
if(!downloadFile.startsWith(downloadDir)) { 
 return null; 
}
return SUCCESS;
}
这时候如果访问者再企图下载web.xml的内容,它只能得到一个空白页,现在访问者只能下载位于/download目录下的文件
 
其他的一些资料:
 
Struts 2中实现文件上传
[url]http://www.blogjava.net/max/archive/2007/03/21/105124.html[/url]
 
Struts 2中实现文件下载(修正中文问题)
[url]http://www.blogjava.net/beansoft/archive/2008/03/03/183468.html[/url]
 
Struts 1文件下载:
[url]http://hi.baidu.com/gisland/blog/item/268caecc7b4eea1301e9288f.html[/url]
[url]http://hi.baidu.com/joe_tech/blog/item/164ced16bd0cbe52f2de3235.html[/url]