这篇文件接上面的struts2文件上传的文件,对上传文件类型进行过滤, 这篇文件里的大量内容也是借鉴了李刚老师的《struts2权威指南》
手动实现文件过滤
大部分时候,Web应用不允许浏览者自由上传,尤其不能允许上传可执行性文件——因为可能是病毒程序。通常,我们可以允许浏览者上传图片,上传压缩文件等;除此之外,还必须对浏览者上传的文件大小进行限制。因此必须在文件上传中进行文件过滤。
从上面的Action中可以看出,Action内有两个方法分别用于获取文件类型和文件大小,为了实现文件过滤,完全可以通过判断这两个方法的返回值来实现文件过滤。
为了让上面的Action增加文件过滤的功能,在上面的Action中增加如下的方法:
/**
* 过滤文件类型
* @param types 系统所有允许上传的文件类型
* @return 如果上传文件的文件类型允许上传,返回null,否则返回input字符串
public String filterType(String[] types)
{
//取得上传文件的文件类型。
String fileType = getUploadContentType();
遍历
for (String type : types)
{
if (type.equals(fileType))
{
return null;
}
}
return INPUT;
}
上面方法判断了上传文件的文件类型是否在允许上传文件类型列表中。为了让应用程序可以动态配置允许上传的文件列表,为该Action增加了一个 allowTypes的属性,该属性的值列出了所有允许上传的文件类型。为了可以在struts.xml文件中配置allowTypes属性的值,必须在 Action类中提供如下代码:
//定义该Action允许上传的文件类型
private String allowTypes;
//allowTypes属性的setter和getter方法
public String getAllowTypes()
{
return allowTypes;
}
public void setAllowTypes(String allowTypes)
{
this.allowTypes = allowTypes;
}
下面就可以在是实现该Action的execute方法了,在通过该方法实现文件上传之前,应该先判断上传文件的文件类型是否允许上传,增加类型判断后的execute方法如下:
public String execute() throws Exception
{
//将允许上传文件类型的字符串以英文逗号(,)分解成字符串数组。
//从而判断当前文件类型是否允许上传
String filterResult = filterType(getAllowTypes().split(","));
//如果当前文件类型不允许上传
if (filterResult != null)
{
ActionContext.getContext().put("typeError" , "您要上传的文件类型不正确!");
return filterResult;
}
//以服务器的文件保存地址和原文件名建立上传文件输出流
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);(来源:www.iocblog.net )
}
return SUCCESS;
}
上面的Action类代码非常简单,它包含的execute方法先判断当前文件类型是否是允许上传的文件类型,如果该文件类型不允许上传,则返回input逻辑视图名;只有当该文件的类型是允许上传的文件类型时,才真正执行文件上传逻辑。
为了让文件类型检验失败时能返回input逻辑视图,因此必须为该Action增加input逻辑视图配置,下面是该Action的配置文件代码。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 指定Struts2配置文件的DTD信息 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 指定国际化资源文件的baseName为globalMessages -->
<constant name="struts.custom.i18n.resources" value="globalMessages"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="upload" class="lee.UploadAction">
<!-- 通过动态设置allowTypes的属性来动态指定允许上传的文件类型 -->
<param name="allowTypes">image/bmp,image/png,image/gif,image/jpeg</param>
<!-- 动态设置Action的属性值 -->
<param name="savePath">/upload</param>
<!-- 配置Struts2默认的视图资源 -->
<result>/succ.jsp</result>
<!-- 配置该应用的input逻辑视图 -->
<result name="input"> /upload.jsp</result>
</action>
</package>
</struts>
通过上面的配置看出,上面文件类型仅能上传各种类型的图片文件,如果试图上传其他类型的文件,系统将转入input逻辑视图,该逻辑视图就是upload.jsp页面,该页面中使用如下代码输出错误提示:
<!-- 使用表达式语言输出错误提示 -->
${requestScope.typeError}
如果试图上传非图片类型的文件,可以看到出错提示,提示用户不要上传非图片类型的文件
通过上面的介绍,我们可以更轻易地完成了文件类型的过滤。
如果需要实现文件大小过滤,与实现文件类型过滤的方法基本相似。虽然在上面的Action类中并没有方法直接获取上传文件的大小,但Action中包含了一个类型为File的属性,该属性封装了文件域对应的文件内容,而File类有一个length()方法,该方法可以返回文件的大小,通过比较该文件的大小和允许上传的文件大小,从而决定是否允许上传该文件。
拦截器实现文件过滤
上面手动实现文件过滤的方式虽然简单,但毕竟需要书写大量的过滤代码,不利于程序的高层次解构,而且开发复杂。
Struts2提供了一个文件上传的拦截器,通过配置该拦截器可以更轻松的实现文件过滤。Struts2中文件上传的过滤器是fileUpload,为了让该拦截器起作用,只需要在该Action配置该拦截器引用即可。
提示:关于拦截器更详细的介绍,请参阅本书的第七章。
配置fileUpload拦截器时,可以为其指定两个参数:
allowedTypes:该参数指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开。
maximumSize:该参数指定允许上传的文件大小,单位是字节。
通过配置fileUpload的拦截器,可以更轻易的实现文件过滤,当文件过滤失败后,系统自动转入input逻辑视图,因此必须为该Action配置名为input的逻辑视图。除此之外,还必须显式地为该Action配置defaultStack的拦截器引用。
通过拦截器来实现文件过滤的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 指定Struts2配置文件的DTD信息 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 指定国际化资源文件的baseName为globalMessages -->
<constant name="struts.custom.i18n.resources" value="globalMessages"/>
<!-- 设置该应用使用的解码集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<package name="lee" extends="struts-default">
<!-- 配置处理文件上传的Action -->
<action name="upload" class="lee.UploadAction">
<!-- 配置fileUpload的拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 配置允许上传的文件类型 -->
<param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>
<!-- 配置允许上传的文件大小 -->
<param name="maximumSize">2000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<!-- 动态设置Action的属性值 -->
<param name="savePath">/upload</param>
<!-- 配置Struts2默认的视图资源 -->
<result>/succ.jsp</result>
<!-- 配置该应用的input逻辑视图 -->
<result name="input">/upload.jsp</result>
</action>
</package>
</struts>
上面的拦截器过滤不仅过滤了文件的类型,也过滤了文件大小。上传文件的类型只能是图片文件,且文件大小不能大于2000字节(当然,我们随时可以更改到更大)。如果我们上传文件的文件太大,系统将转入input的逻辑视图,也就是/upload.jsp页面。