`
yongjiucui
  • 浏览: 18629 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Struts2文件上传下载

    博客分类:
  • SSH
阅读更多

文件上传的原理:

  表单元素的enctype属性指定的是表单数据的编码方式,该属性有3个值:
  1) application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的
值处理成URL编码方式。
  2) multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到
请求参数里。
  3) text/plain:这种方式主要适用于直接通过表单发送邮件的方式。
  文件上传是web应用经常用到的一个知识。原理是,通过为表单元素设置enctype=”multipart/form-data”属性,让表单提交的数据以二
进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。
  在Java领域中,有两个常用的文件上传项目:一个是Apache组织Jakarta的Common-FileUpload组件
([url]http://commons.apache.org/fileupload/[/url]),另一个是Oreilly组织的COS框架([url]http://www.servlets.com/cos/[/url])。利用这两个框架都能很方便
的实现文件的上传。

==================================
Struts2上传文件

增加commons-fileupload-1.2.jar和commons-io-1.3.1.jar到lib
=====
 jsp
=====
form 的 enctype 设置为 multipart/form-data
 
==============
 UploadAction
==============
private String username;
private String password;
private File file;           // 对应文件域
private String fileFileName; // 前面的File属性的名字 + FileName(固定的)
private String fileContent;  // 前面的File属性的名字 + Content
//  setter...  getter...
String execute() throws Exception {
 InputStream is = new FileInputStream( file );
 String root = ServletActionContext.getRequest().getRealPath("/upload");
 File destFile = new File(root,this.getFileFileName());
 OutputStream os = new FileOutputStream( destFile );
 byte[] buffer = new byte[400];
 int length = 0;
 while( (length = is.read(buffer)) > 0 ) {
  os.write(buffer,0,length);
 }
 is.close();
 os.close();
 return SUCCESS;
}
=================
    中文问题
=================
不过我全部用UTF-8并未遇到中文问题
struts2-core包
struts-default.xml                      ----拦截器的设置
org.apache.struts2.default.properties   ----全局属性的设置
33行  strusts.i18n.encoding=UTF-8   默认UTF-8
可以在struts.xml下进行设置
<struts>
 设置字符集
 <constant name="struts.i18n.encoding" value="gbk"/>
 设置上传文件缓存
 <constant name="struts.multipart.saveDir" value="c:\"/> 
</struts>
其他属性
struts.multipart.parser=jakarta   struts2采用那种方式上传
                        pell
                        cos
struts.multipart.maxSize=2097152   默认上传文件最大的请求大小2M
struts.action.extension=action     整个url的后缀名
 

================
  上传多个文件
================
有两种方式:
1.数组
File[] file                文件
String[] fileFileName      文件名
String[] fileContentType   文件类型
2.集合
List<File>   file  
List<String> fileFileName
List<String> fileContentType
--------
action中:
--------

String execute() {
 for(int i = 0; i < file.size(); i++) {
  InputStream is = new FileInputStream(file.get(i));
  String root = ServletActionContext.getRequest().getRealPath("/upload");
  File destFile = new File(root,this.getFileFileName().get(i)); 
  ... 
 } 
 return SUCCESS;
}
------
jsp中:
------

多个file时,file的名字要一致,都要叫file,它会自动set到跟file名对应的List中去
<s:file name="file" />
<s:file name="file" />
<s:file name="file" />

========================
  上传任意个文件
========================
<td id="more">
 <input type="button" value="添加" />
</td>
------
  JS:
------

funcation addMore() {
 var td = document.getElementById("more");
 //生成一个换行符
 var br = document.createElement("br");
 //创建一个input组件
 var input = document.createElement("input");
 var button = document.createElement("input");
 //指定类型 为 file 为文件上传
 input.type = "file";
 //指定组件的名字
 input.name = "file";
 button.type = "button";
 button.value = "删除";
 //为删除按钮注册一个事件 
 button.onclick = function() {
  //alert("删除按钮");
  //删除一行
  td.removeChild(br);
  td.removeChild(input);
  td.removeChild(button);
 }
 //将创建的组件加到<td>中
 td.appendChild(br);
 td.appendChild(input);
 td.appendChild(button);
}
 
=======================
     限制上传类型
=======================
org.apache.struts2.interceptor.FileUploadInterceptor类
Long maximumSize:最大上传大小---每一个文件的大小,不是总和
String allowedTypes:允许的类型
-------------
 struts.xml
-------------

<struts>
 <action ...>
  <result name="input">/upload.jsp</result>
  <result .../>
  
  加入一个上传文件的拦截器并设置其属性
  <interceptor-ref name="fileUpload">

   <param name="maximumSize">409600</param>   单个上传文件最大不能超过400K
   <param name="allowedTypes">...</param>     mime类型,多个用逗号分开

  </interceptor-ref>
  ** 加入默认的拦截器
  <interceptor-ref name="defaultStack" />
 </action>  
</struts>
注:后缀可以到tomcat\conf\web.xml中找<mime-type>中的字符串
 
--------------
  upload.jsp
--------------
  添加<s:fielderror />
----------------------
  更改显示的错误信息
----------------------
org.apache.struts2中  找到struts-messages.properties
-----------------------
上传文件类型不匹配
struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" {2}
-----------------------
上传文件大小超出规定
struts.messages.error.file.too.large=File too large: {0} "{1}" {2}
-----------------------
上传文件出错
struts.messages.error.uploading=Error uploading: {0}
创建一个全局的属性文件 /src/messages.properties
struts.messages.error.content.type.not.allowed=不支持上传该类型的文件
struts.messages.error.file.too.large=上传文件过大,请重试
struts.messages.error.uploading=上传文件时发生错误
---------
  国际化
---------

<constant name="struts.custom.i18n.resources" value="messages"/>
messages_en_US.properties
messages_zh_CN.properties
 

==============================
            下载
==============================
处理下载的类: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中实现文件上传
 
Struts 2中实现文件下载(修正中文问题)
 
Struts 1文件下载:
分享到:
评论

相关推荐

    struts2文件上传下载源代码

    在Struts2中,文件上传和下载是常见的功能需求,特别是在处理用户交互和数据交换时。这篇博客文章提供的"struts2文件上传下载源代码"旨在帮助开发者理解和实现这些功能。 文件上传功能允许用户从他们的设备上传文件...

    struts2文件上传下载

    在这个特定的项目中,我们关注的是"struts2文件上传下载"的功能,这涉及到用户通过Web界面上传文件到服务器,以及从服务器下载文件到用户的设备。 文件上传是Web应用中的常见需求,例如用户可能需要提交图片、文档...

    struts2文件上传下载实例

    在“struts2文件上传下载实例”中,我们将探讨如何在Struts2框架下实现文件的上传和下载功能,这对于许多Web应用程序来说是必不可少的特性。 首先,`pom.xml`文件是Maven项目对象模型的配置文件,它定义了项目的...

    Struts2文件上传下载和表单重复提交问题

    综上所述,Struts2文件上传下载和表单重复提交涉及多个技术点,包括Struts2的配置、文件操作、HTTP响应头设置、安全性和异常处理。理解并熟练掌握这些知识点,对于构建健壮的Web应用程序至关重要。

    struts2文件上传下载(注解版)

    在本项目中,我们关注的是Struts2中的文件上传和下载功能,这些功能是Web开发中常见的需求,尤其在处理用户数据提交或提供资源下载时。下面将详细介绍这个“struts2文件上传下载(注解版)”项目的关键知识点。 1. ...

    struts2实现文件上传下载

    Struts2是一个强大的MVC(模型-视图-控制器)框架,广泛应用于Java ...以上就是使用Struts2框架实现文件上传下载的基本步骤和关键知识点。在实际开发中,可以根据项目需求进行调整和优化,确保功能的稳定性和安全性。

    struts2 文件上传下载

    在Struts2中,文件上传和下载是常见的功能,它们允许用户从服务器上下载文件或向服务器上传文件。理解并掌握这一部分的知识对于开发交互性强的Web应用至关重要。 ### 一、文件上传 1. **使用Struts2的FileUpload...

    第八章:struts2文件上传下载.ppt

    第八章:struts2文件上传下载.ppt

    Struts2文件上传下载 中文乱码

    在Struts2框架中,文件上传和下载是常见的功能需求,但处理中文文件名或内容时,可能会遇到中文乱码的问题。这个问题主要涉及到字符编码的处理,包括HTTP请求的编码、文件名的编码以及文件内容的编码。接下来,我们...

    struts2文件上传与下载

    在Struts2中,文件上传和下载是常见的功能需求,主要用于处理用户在Web表单中提交的文件,如图片、文档等。下面将详细介绍Struts2中文件上传和下载的实现方法。 ### 1. 文件上传 #### 1.1 配置Struts2 首先,我们...

    Struts2文件上传与下载

    Struts2是一个强大的Java web框架,它为开发者提供了丰富的功能,包括处理用户表单提交、进行文件上传和下载。在Web应用中,文件上传和下载是常见的需求,例如用户上传头像、下载文档等。Struts2通过其Action类和...

    struts2 文件上传

    Struts2 文件上传是Web开发中的一个重要功能,它允许用户通过网页上传文件到服务器。Struts2 是一个基于MVC(Model-View-Controller)设计模式的Java Web框架,提供了丰富的特性和强大的控制层功能,使得文件上传...

Global site tag (gtag.js) - Google Analytics