前言
我们在开发web应用时,肯定要为用户提供上传的功能,比如用户上传一张图像作为头像等。为了能上传文件,我们必须将表单的method设置为post,将enctype设置为multipart/form-data
。只有在这种情况下,浏览器才会把用户选择文件的二进制数据发送给服务器。这篇文章就对struts2框架中的上传功能进行详细的总结,下面话不多说了,来一起看看详细的介绍吧。
struts2的文件上传
struts2并未提供自己的请求解析器,也就是说,struts2不会自己去处理multipart/form-data的请求,它需要调用其它上传框架来解析二进制请求数据,但struts2在原有的上传解析器基础上做了进一步封装,更进一步简化了文件上传。
在struts2的default.properties
配置文件中,可以看到这样的配置代码:
1
2
3
4
5
6
7
8
|
### parser to handle http post requests, encoded using the mime-type multipart/form-data
# struts.multipart.parser=cos
# struts.multipart.parser=pell
# struts.multipart.parser=jakarta-stream
struts.multipart.parser=jakarta
# uses javax.servlet.context.tempdir by default
struts.multipart.savedir=
struts.multipart.maxsize= 2097152
|
上述代码主要用于配置struts2上传文件时的上传解析器。struts2的封装隔离了底层文件上传组件的区别,开发者只要在此配置文件上传所使用的解析器,就可以轻松地在不同的文件上传框架之间切换。
struts2默认使用jakarta上传解析器,当然了,如果你不喜欢,你也可以换成别的。下面就通过代码来实现一个简单的基于struts2的文件上传功能。
实现文件上传的action
前台页面:
1
2
3
4
5
|
<form action= "upload" method= "post" enctype= "multipart/form-data" >
title:<input type= "text" name= "title" ><br>
file:<input type= "file" name= "upload" ><br>
<input type= "submit" value= "submit" >
</form>
|
action类:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
public class uploadaction extends actionsupport
{
private string title;
private file upload;
private string uploadcontenttype;
private string uploadfilename;
private string savepath;
public void setsavepath(string value)
{
this .savepath = value;
}
private string getsavepath()
{
string realpath = servletactioncontext.getservletcontext().getrealpath( "/web-inf/" + savepath);
return realpath;
}
public void settitle(string value)
{
this .title = value;
}
public string gettitle()
{
return title;
}
public void setupload(file value)
{
this .upload = value;
}
public file getupload()
{
return upload;
}
public void setuploadcontenttype(string value)
{
this .uploadcontenttype = value;
}
public string getfilecontenttype()
{
return uploadcontenttype;
}
public void setuploadfilename(string value)
{
this .uploadfilename = value;
}
public string getuploadfilename()
{
return uploadfilename;
}
@override
public string execute() throws exception
{
fileoutputstream fos = new fileoutputstream(getsavepath() + "\\" + getuploadfilename());
fileinputstream fis = new fileinputstream(getupload());
byte [] buffer = new byte [ 1024 ];
int len = 0 ;
while ((len = fis.read(buffer)) > 0 )
{
fos.write(buffer, 0 , len);
}
fis.close();
fos.close();
return success;
}
}
|
struts.xml配置文件:
1
2
3
4
5
6
7
|
< package name= "upload" extends = "struts-default" >
<action name= "upload" class = "com.jellythink.practise.uploadaction" >
<param name= "savepath" >/upload</param>
<result name= "success" >/success.jsp</result>
<result name= "input" >/index.jsp</result>
</action>
</ package >
|
对于action类中,包含了两个特别的属性:
- uploadcontenttype
- uploadfilename
这两个属性分别用于封装上传文件的文件名、上传文件的文件类型。对于struts2来说,如果form表单中包含一个name属性为xxx的文件域,则对应的action需要使用三个属性来封装该文件域的信息:
- 类型为file的xxx属性封装了该文件域对应的文件内容;
- 类型为string的xxxfilename属性封装了该文件域对应的文件的文件名;
- 类型为string的xxxcontenttype属性封装了该文件域对应的文件的文件类型。
通过上面的开发过程,可以看出通过struts2实现文件上传确实是一件简单的事情。我们需要做的事情就是将文件域与action中一个类型为file的属性关联,就可以轻松访问到上传文件的文件内容,至于struts2如何使用multipart解析器,对开发者完全透明。
手动实现文件过滤
很多时候,web应用不允许用户*上传,我们需要对用户上传的文件类型,文件大小进行限制,因此必须在文件上传过程中进行文件过滤。下面就先手动实现上传文件过滤。
在struts.xml中配置一个新的参数,表示支持的上传类型:
1
|
<param name= "allowtypes" >image/png,image/gif,image/jpeg</param>
|
在action中添加验证函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 进行验证
@override
public void validate()
{
string filterresult = filtertype(getallowtypes().split( "," ));
if (filterresult != null )
{
addfielderror( "upload" , "您要上传的文件类型不正确!" );
}
}
public string filtertype(string[] types)
{
string filetype = getfilecontenttype();
for (string type : types)
{
if (type.equals(filetype))
{
return null ;
}
}
return error;
}
|
这只是实现了类型的判断,然后在根据file类的length()
方法,来实现大小的验证。但是好麻烦,接下来就说一种更简单的说法。
拦截器实现文件过滤
struts2提供了一个文件上传的拦截器,通过配置拦截器可以更轻松地实现文件过滤。struts2中文件上传的拦截器fileupload,为了让该拦截器起作用,只需要在该action中配置该拦截器引用即可。
配置fileupload拦截器时,可以为其指定两个参数:
- allowedtypes:该参数指定允许上传的文件类型,多个文件类型之间以英文逗号隔开
- maximumsize:该参数指定允许上传的文件大小,单位是字节
1
2
3
4
5
6
7
8
9
10
|
<!-- 配置fileupload拦截器 -->
<interceptor-ref name= "fileupload" >
<param name= "allowedtypes" >image/png,image/gif,image/jpeg</param>
<param name= "maximumsize" > 20000000 </param>
</interceptor-ref>
<!-- 配置系统默认的拦截器 -->
<interceptor-ref name= "defaultstack" />
<result name= "success" >/success.jsp</result>
<result name= "input" >/index.jsp</result>
|
这样子,修改配置就可以搞定的事情,比写一坨代码真的轻松多了。
配置错误信息
对于上传出现错误的情况,系统默认都是提示英文的错误信息,但是为了输出国际化的提示信息,这就需要在国际化的资源配置文件中增加以下两个key的消息定义:
-
struts.messages.error.content.type.not.allowed
=上传文件类型不正确,请重新上传 -
struts.messages.error.file.too.large
=您上传的文件太大,请重新上传
接下来就可以使用<s:fielderror/>来输出错误信息了。
文件上传的常量配置
在文章的开始,我们说到default.properties
中的配置,其中有一个struts.multipart.savedir
配置,那么该配置项的具体作用是什么呢?
在struts2执行文件上传的过程中,需要指定一个临时文件夹,用来存放上传过程中产生的临时文件;如果没有指定临时文件夹,系统默认使用javax.servlet.context.tempdir
,在tomcat安装路径下的work/catalina/localhost/路径下。而这个struts.multipart.savedir就是配置临时文件的存放位置的。所以在开发的过程中,一定要注意该目录是否有读写权限哦。
还有一个struts.multipart.maxsize
配置,该配置表示上传文件的大小,如果同时指定了这个配置和fileupload拦截器的maximumsize属性,则先和struts.multipart.maxsize
配置的比较,再和fileupload拦截器的maximumsize属性比较,如果文件大小超过了struts.multipart.maxsize
配置的,则会出现异常,并不会将result转到input,这个一定要注意。
总结
这篇文章详细的总结了struts2中的文件上传,内容有点多,基本都是手册上的内容,也罢,就当手册了。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://www.jellythink.com/archives/299