Struts2文件的上传和下载
http://tmsoft.lsxy.com/trackback.php?tbID=514&extra=ecac1e
1. 文件上传的原理:
表单元素的
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
组件
(http://commons.apache.org/fileupload/)
,另一个是
Oreilly
组织的
COS
框架
(http://www.servlets.com/cos/)
。利用这两个框架都能很方便的实现文件的上传。
2. Struts2的文件上传:
Struts2
并未提供自己的请求解析器,也就是就
Struts2
不会自己去处理
multipart/form-data
的请求,它需要调用其他请求解析器,将
HTTP
请求中的表单域解析出来。但
Struts2
在原有的上传解析器基础上做了进一步封装,更进一步简化了文件上传。
Struts2
默认使用的是
Jakarta
的
Common-FileUpload
框架来上传文件,因此,要在
web
应用中增加两个
Jar
文件:
commons-fileupload-1.2.jar
和
commons-io-1.3.1.jar
。它在原上传框架上做了进一步封装,简化了文件上传的代码实现,取消了不同上传框架上的编程差异。
如果要改成其它的文件上传框架,可以修改
struts.multipart.parser
常量的值为
cos/pell
,默认值是
jakata
。并在
classpath
中增加相应上传组件的类库。
2.1. 步骤一:创建带上传表单域的页面
<%@
page
language
=
"java"
contentType
=
"text/html; charset=UTF-8"
%>
<
html
>
<
head
>
<
title
>
Struts2 File Upload
</
title
>
</
head
>
<
body
>
<
form
action
=
"fileUpload.action"
method
=
"POST"
enctype
=
"multipart/form-data"
>
文件标题:
<
input
type
=
"text"
name
=
"title"
size
=
"50"
/><
br
/>
选择文件:
<
input
type
=
"file"
name
=
"upload"
size
=
"50"
/><
br
/>
<
input
type
=
"submit"
value
=
"
上传
"
/>
</
form
>
</
body
>
</
html
>
|
此页面特殊之处只是把表单的
enctype
属性设置为
multipart/form-data
。
2.2. 步骤二:创建处理上传请求的Action类
package
org.qiujy.web.struts2;
import
java.io.BufferedInputStream;
import
java.io.BufferedOutputStream;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.InputStream;
import
java.io.OutputStream;
import
org.apache.struts2.ServletActionContext;
import
com.opensymphony.xwork2.ActionSupport;
/**
*
处理文件上传的
Action
类
*
@author
qiujy
*
@version
1.0
*/
public
class
FileUploadAction
extends
ActionSupport {
private
static
final
int
BUFFER_SIZE
= 16 * 1024;
//
文件标题
private
String
title
;
//
上传文件域对象
private
File
upload
;
//
上传文件名
private
String
uploadFileName
;
//
上传文件类型
private
String
uploadContentType
;
//
保存文件的目录路径
(
通过依赖注入
)
private
String
savePath
;
//
以下省略
getter
和
setter......
//
自己封装的一个把源文件对象复制成目标文件对象
private
static
void
copy(File src, File dst) {
InputStream in =
null
;
OutputStream out =
null
;
try
{
in =
new
BufferedInputStream(
new
FileInputStream(src),
BUFFER_SIZE
);
out =
new
BufferedOutputStream(
new
FileOutputStream(dst),
BUFFER_SIZE
);
byte
[] buffer =
new
byte
[
BUFFER_SIZE
];
int
len = 0;
while
((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
catch
(Exception e) {
e.printStackTrace();
}
finally
{
if
(
null
!= in) {
try
{
in.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}
if
(
null
!= out) {
try
{
out.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public
String execute()
throws
Exception {
//
根据服务器的文件保存地址和原文件名创建目录文件全路径
String dstPath = ServletActionContext.getServletContext()
.getRealPath(
this
.getSavePath())
+
"//"
+
this
.getUploadFileName();
System.
out
.println(
"
上传的文件的类型:
"
+
this
.getUploadContentType());
File dstFile =
new
File(dstPath);
copy(
this
.
upload
, dstFile);
return
SUCCESS
;
}
}
|
上面这个
Action
类中,提供了
title
和
upload
两个属性来分别对应页面的两个表单域属性,用来封装表单域的请求参数。
但是,值得注意的是,此
Action
中还有两个属性:
uploadFileName
和
uploadContentType
,这两个属性分别用于封装上传文件的文件名、文件类型。这是
Struts2
设计的独到之处:
Strut2
的
Action
类直接通过
File
类型属性直接封装了上传文件的文件内容,但这个
File
属性无法获取上传文件的文件名和文件类型,所以
Struts2
就直接将文件域中包含的上传文件名和文件类型的信息封装到
uploadFileName
和
uploadContentType
属性中,也就是说
Struts2
针对表单中名为
xxx
的文件域,在对应的
Action
类中使用
3
个属性来封装该文件域信息
:
l
类型为
File
的
xxx
属性:用来封装页面文件域对应的文件内容。
l
类型为
String
的
xxxFileName
属性:用来封装该文件域对应的文件的文件名。
l
类型为
String
的
xxxContentType
属性:用来封装该文件域应用的文件的文件类型。
另外,在这个
Action
类中还有一个
savePath
属性,它的值是通过配置文件来动态设置的,这也是
Strut2
设计中的一个依赖注入特性的使用。
2.3. 步骤三:配置
struts.xml
文件:
<!
DOCTYPE
struts
PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>
<
struts
>
<
package
name
=
"fileUploadDemo"
extends
=
"struts-default"
>
<
action
name
=
"fileUpload"
class
=
"org.qiujy.web.struts2.FileUploadAction"
>
<!--
动态设置
Action
中的
savePath
属性的值
-->
<
param
name
=
"savePath"
>
/upload
</
param
>
<
result
name
=
"success"
>
/showupload.jsp
</
result
>
</
action
>
</
package
>
</
struts
>
|
在这个文件中跟以前配置唯一不同的是给
action
配置了一个
<param …/>
元素,用来为该
Action
的
savePath
属性动态注入值�%