上传与下载,一个古老而现代的话题......让我们试目以待
13.Struts2中文件的上传与下载
(1). 数据编码方式
表单的enctype属性用于指定表单数据的编码方式,它可以为以下值:
l application/x-www-form-urlencoded:默认的编码方式,只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式。
l multipart/form-data:以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里;
l text/plain:主要适用于直接通过表单发送邮件的方式。
为了实现文件上传功能,必须将form的enctype属性值设置为multipart/form-data类型。
(2). 上传框架
Struts2默认使用Jakarta的Common-Fileupload组件来进行文件上传操作,除了使用common-fileupload组件外,也可以使用其它的上传组件,使用其它的组件时需要对struts.multipart.parser属性进行配置,如下:
struts.multipart.parser = jakarta // 使用common-fileupload组件上传
struts.multipart.parser = cost // 使用cos组件上传
struts.multipart.parser = pell // 使用pell组件上传
Common-Fileupload组件不管是文件域还是普通表单域,都把它当成FileItem对象来处理,如果该对象的isFormField()方法返回true,表明该表单域是一个普通表单域,否则将是一个文件域。以下给出几个FileItem常用的方法:
l getFiledName():取得该表单域的name属性值;
l getString(String encoding):取得该表单域的value属性值,其中encoding参数设置编码集;
l getName():仅当该表单域是文件域时才起作用,该方法返回上传文件的文件名;
l getContentType():仅当该表单域是文件域时才起作用,该方法返回上传文件的文件类型;
l get():仅当该表单域是文件域时才起作用,该方法返回上传文件的文件内容字节;
l getInputStream():仅当该表单域是文件域时才起作用,该方法返回上传文件对应的输入流。
COS框架是oreilly组织下的一个小项目,与Common-Fileupload相比而言,COS在处理上传下载时更加方便,COS用Part实例代表所有的表单域,不管是普通表单域还是文件域,都是Part实例;Part类有两个子类:ParamPart和FilePart,分别代表普通表单域和文件域,以下为Part类包含的常用方法:
l getName():取得该表单域的name属性值;
ParamPart类常用方法:
l getStringValue(String encoding):取得该表单域的value属性值,其中encoding参数设置编码集;
FilePar类常用方法:
l getFileName():该方法返回上传文件的文件名;
l getFilePath():该方法返回上传文件的文件路径;
l getContentType():该方法返回上传文件的文件类型;
Struts2中无论使用Common-fileupload还是COS,对于文件上传下载的操作都是一样的,在Struts2中,使用File类来封装文件域,如果表单中包含一个name属性为xxx的文件域,则对应的Action需要使用3个属性来封装该文件域的信息:
l 类型为File的xxx属性:封装文件域对应的文件内容;
l 类型为String的xxxFileName属性:封装该文件域对应的文件的文件名;
l 类型为String的xxxContentType属性:封装该文件域对应的文件的文件类型。
(3). 实现文件过滤
在Struts2中除了手动实现文件过滤操作外,还可以使用Struts2提供的上传文件过滤器fileUpload,配置fileUpload时需要指定两个参数:
l allowedTypes:指定允许上传的文件类型,多个文件类型之间用英文逗号隔开;
l maximumSize:指定允许上传的文件大小,单位是字节
需要说明的是,当文件过滤失效后,会自动转入input逻辑视图,除此之外还必须显示地为该Action配置defaultStack的拦截器起用,示例如下:
<package name=”demo” extends=”struts-default.xml”>
<action name=”upload” class=”com.demo.UploadAction”>
<interceptor-ref name=”fileUpload”>
<param name=”allowedTypes”>bmp, jpg, png</param>
<param name=”maximumSize”>2000</param>
</interceptor-ref>
<interceptor-ref name=”defaultStack” />
<param name=”savePath”>/uploadDir</param>
<result name=”error”>/error.jsp</result>
<result name=”input”>/input.jsp</result>
<result>/success.jsp</result>
</action>
</package>
上传文件太大的提示信息的key 为:struts.messages.error.file.too.large
上传文件时文件类型是不允许上传的文件类型时的消息key为:
struts.messages.error.content.type.not.allowed
未知的错误的提示信息key为:struts.messages.error.uploading
为了避免使用WEB容器的工作路径作为临时路径,需要设置struts.multipart.saveDir属性;此外整个表单请求内容的最大字节数由属性struts.multipart.maxSize设置。
(4). 文件下载
Struts2的文件下载Action需要提供一个返回InputStream流的方式,该输入流代表了被下载文件的入口。
在配置Action方面,与配置普通的Actoin没什么区别,唯一不同的是需要额外加上download拦截器引用,配置时需要指定以下参数:
l contentType:指定被下载文件的文件类型;
l inputName:指定被下载文件的入口输入流;
l contentDisposition:指定下载的文件名;
l bufferSize:指定下载文件时的缓冲大小。
示例:
public class DownloadDemo{
……
public InputStream getDownloadFile() throws Exception{
return ServletActionContext.getServletContext().getResourceAsStream(inputPath));
}
……
}
struts.xml
<package name=”demo” extends=”struts-default.xml”>
<default-action-ref name=”download”/>
<action name=”download” class=”com.demo.DownloadAction”>
<result type=”stream” name=”successs”>
<param name=”contenType”>/image/gif</param>
<param name=”inputName”>downloadFile</param>
<param name=”contentDisposition”>filename=”struts.gif”</param>
<param name=”bufferSize”>4096</param>
</result>
</action>
</package>