yxhxj2006
导航
BlogJava
首页
新随笔
联系
聚合
管理
<
2012年8月
>
日
一
二
三
四
五
六
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
留言簿
(7)
给我留言
查看公开留言
查看私人留言
随笔分类
J2EE(17)
(rss)
java(13)
(rss)
Javascipt
(rss)
Linux(3)
(rss)
PHP(4)
(rss)
SQL(12)
(rss)
励志(3)
(rss)
测试
(rss)
文章分类
paypal
(rss)
随笔档案
2016年6月 (1)
2015年12月 (1)
2015年11月 (1)
2015年10月 (1)
2015年8月 (1)
2015年6月 (1)
2015年5月 (3)
2015年4月 (6)
2015年3月 (1)
2015年2月 (4)
2015年1月 (4)
2014年12月 (6)
2014年11月 (1)
2014年9月 (3)
2014年6月 (2)
2014年5月 (5)
2014年4月 (3)
2014年3月 (3)
2014年2月 (15)
2014年1月 (11)
2013年12月 (1)
2013年11月 (8)
2013年10月 (6)
2013年9月 (2)
2013年8月 (19)
2013年7月 (1)
2013年6月 (1)
2013年5月 (3)
2013年4月 (3)
2013年3月 (5)
2012年12月 (3)
2012年11月 (4)
2012年10月 (1)
2012年9月 (25)
2012年8月 (54)
2012年7月 (10)
2012年6月 (7)
阅读排行榜
1. Hibernate实现有两种配置,xml配置与注释配置(49832)
2. 公钥与私钥 (42304)
3. 使用POI读取EXCEL中的所有Sheet表 (25882)
4. Maven实战(六)依赖(11931)
5. Oracle中把一个查询结果插入到一张表中(11018)
评论排行榜
1. 公钥与私钥 (31)
2. Hibernate实现有两种配置,xml配置与注释配置(4)
3. Java通过URL获取网站Html源代码 (3)
4. 让HTML中的文本框中的文字垂直居中 .(3)
5. struts2表单传值(2)
常用链接
我的随笔
我的评论
我的参与
最新评论
统计
随笔 - 228
文章 - 0
评论 - 53
引用 - 0
最新评论
1. re: 公钥与私钥
评论内容较长,点击标题查看
--chinaltang
2. re: 如何在magento中建立自定义页面
请问站长,你这个增加以下片段是在哪里增加的,还有你这是怎么显示出来页面呢,总要点击页面上的哪个东西跳转到这个页面吧,那点击跳转怎么操作
--王小丫
3. re: 公钥与私钥
343434
--zhangsa
4. re: 公钥与私钥
真的写的非常好,通俗易懂,但是不知道有demo没有,要是有求一份。
--Divella
5. re: Hibernate实现有两种配置,xml配置与注释配置[未登录]
sa
--sa
Struts2文件的上传和下载
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类
*@authorqiujy
*@version1.0
*/
publicclass FileUploadAction
extends
ActionSupport
{
privatestaticfinalintBUFFER_SIZE
=
16
*
1024
;
//
文件标题
private
String title;
//
上传文件域对象
private
File upload;
//
上传文件名
private
String uploadFileName;
//
上传文件类型
private
String uploadContentType;
//
保存文件的目录路径(通过依赖注入)
private
String savePath;
//
以下省略getter和setter
//
自己封装的一个把源文件对象复制成目标文件对象
privatestaticvoid 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
=
newbyte[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);
returnSUCCESS;
}
}
上面这个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属性动态注入值。
web.xml中的配置跟以前的应用一样。说明一点:好多网络文章说Struts2上传时要在web.xml中配置一个名为ActionContextUp的过滤器,说是有一些莫名的错误,可是是我用了Struts2新版本2.
0
.9GA版,测了n次,没出现什么问题,所以没配置。
2.4
. 运行调试:
运行前要在根目录下创建一个名为upload的文件夹,用来存放上传后的文件。
上传结果:
3
. 文件类型及错误输出:
Struts2提供了一个文件上传的拦截器(名为fileUpload),通过配置这个拦截器能轻松地实现文件类型的过滤。
在上例中,若要配置上传的文件只能是一些普通的图片文件格式:image
/
bmp、image
/
png、image
/
gif、image
/
jpeg、image
/
jpg等,则可在struts.xml文件中按如下方式配置:
<!
DOCTYPE struts PUBLIC
"
-//Apache Software Foundation//DTD Struts Configuration 2.0//EN
"
"
http://struts.apache.org/dtds/struts-2.0.dtd
"
>
<
struts
>
<
constant name
=
"
struts.custom.i18n.resources
"
value
=
"
messages
"
/>
<
package
name
=
"
fileUploadDemo
"
extends
=
"
struts-default
"
>
<
action name
=
"
fileUpload
"
class
=
"
org.qiujy.web.struts2.FileUploadAction
"
>
<
interceptor
-
ref name
=
"
fileUpload
"
>
<!--
配置允许上传的文件类型,多个用
"
,
"
分隔
-->
<
param name
=
"
allowedTypes
"
>
image
/
bmp,image
/
png,image
/
gif,image
/
jpeg,image
/
jpg
,image
/
x
-
png, image
/
pjpeg
</
param
>
<!--
配置允许上传的文件大小,单位字节
-->
<
param name
=
"
maximumSize
"
>
102400
</
param
>
</
interceptor
-
ref
>
<
interceptor
-
ref name
=
"
defaultStack
"
/>
<!--
动态设置Action中的savePath属性的值
-->
<
param name
=
"
savePath
"
>/
upload
</
param
>
<
result name
=
"
input
"
>/
index.jsp
</
result
>
<
result name
=
"
success
"
>/
showupload.jsp
</
result
>
</
action
>
</
package
>
</
struts
>
如果上传文件失败,系统返回到input对应的页面,要在input对应的页面输出文件过滤失败信息,可以在input对应的页面中增加
<
s:fielderror
/>
来显示错误信息。
运行调试:
结果:
显然,这样的提示不太友好,应用使用国际化信息。在国际化资源文件中添加如下三句:
#更改上传文件类型不允许的提示信息
struts.messages.error.content.type.not.allowed
=
文件上传失败:你要上传的文件类型不允许
#更改上传文件太大的提示信息
struts.messages.error.file.too.large
=
文件上传失败:你要上传的文件太大
#文件上传其它错误信息
struts.messages.error.uploading
=
文件上传失败:发生内部错误
别忘了要用native2ascii.exe进行编码转换哦。再运行调试:
另外,在控制台会看到一条消息:
Unable to find
'
struts.multipart.saveDir
'
property setting. Defaulting to javax.servlet.context.tempdir
Removing file upload D:\tomcat6.
0.13
\work\Catalina\localhost\fileload_struts2\upload__4b616fd1_115a3d5d9dc__7fff_00000005.tmp
第一个说是找不以struts.multipart.saveDir,即没有指定临时文件夹,这个很好解决,只需指定一个struts.multipart.saveDir常量值为某个目录来解决。第二个说正在删除一个临时文件,这个临时文件是上传过程中产生的,属正常。
4
. 多文件上传:
Struts2也可以很方便地实现多文件上传。
在输入表单域增加多个文件域:multifileupload.jsp
<%
@ page language
=
"
java
"
contentType
=
"
text/html; charset=UTF-8
"
%>
<%
@ taglib uri
=
"
/struts-tags
"
prefix
=
"
s
"
%>
<
html
>
<
head
>
<
title
>
多文件上传
</
title
>
</
head
>
<
body
>
<
font color
=
"
red
"
><
s:fielderror
/></
font
>
<
form action
=
"
multiFileUpload.action
"
method
=
"
POST
"
enctype
=
"
multipart/form-data
"
>
文件标题:
<
input type
=
"
text
"
name
=
"
title
"
size
=
"
50
"
value
=
"
${param.title }
"
/><
br
/>
<!--
设置二个文件域,名字相同
-->
选择第一个文件:
<
input type
=
"
file
"
name
=
"
upload
"
size
=
"
50
"
/><
br
/>
选择第二个文件:
<
input type
=
"
file
"
name
=
"
upload
"
size
=
"
50
"
/><
br
/>
<
input type
=
"
submit
"
value
=
"
上传
"
/>
</
form
>
</
body
>
</
html
>
在Action类中用数组来封装该多个文件域:MultiFileUploadAction.java
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.IOException;
import
java.io.InputStream;
import
java.io.OutputStream;
import
org.apache.struts2.ServletActionContext;
import
com.opensymphony.xwork2.ActionSupport;
/** */
/**
*处理多文件上传的Action类
*
*@authorqiujy
*@version1.0
*/
publicclass MultiFileUploadAction
extends
ActionSupport
{
privatestaticfinalintBUFFER_SIZE
=
16
*
1024
;
//
文件标题
private
String title;
//
用File数组来封装多个上传文件域对象
private
File[] upload;
//
用String数组来封装多个上传文件名
private
String[] uploadFileName;
//
用String数组来封装多个上传文件类型
private
String[] uploadContentType;
//
保存文件的目录路径(通过依赖注入)
private
String savePath;
//
以下为所有属性的getter和setter。省略。。。
//
自己封装的一个把源文件对象复制成目标文件对象
privatestaticvoid 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
=
newbyte[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
{
File[] srcFiles
=
this
.getUpload();
//
处理每个要上传的文件
for
(
int
i
=
0
; i
<
srcFiles.length; i
++
)
{
//
根据服务器的文件保存地址和原文件名创建目录文件全路径
String dstPath
=
ServletActionContext.getServletContext()
.getRealPath(
this
.getSavePath())
+
"
\\
"
+
this
.getUploadFileName()[i];
File dstFile
=
new
File(dstPath);
this
.copy(srcFiles[i], dstFile);
}
returnSUCCESS;
}
}
运行结果:
5
. Struts2的文件下载:
文件下载相对简单一些,一般只需在页面上提供一个超链接,该链接的href属性等于要下载文件的文件名就行了。但当文件名有中文时,就会导致失败;或者要在用户下载前进行权限判断,这时用Struts2提供的文件下载功能就能简单的解决这些问题。
posted on 2012-08-01 17:41
奋斗成就男人
阅读(580)
评论(0)
编辑
收藏
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
Powered by:
BlogJava
Copyright © 奋斗成就男人