文件上传基础知识:
表单的enctype类型:1 普通表单(默认):application/x-www-form-urlencoded
会将表单的元素值编码为url传输格式(用什么编码则根据页面编码而定)格式如param1=v1¶m2=v2的形式
可以通过request.getParameter获得值
2 文件上传表单:mutipart/form-data
将表单元素值以二进制方式发送(以页面编码的形式)
格式不同于上,无法通过request.getParameter获取
3 text/plain 不常用
因此文件上传的http请求数据与普通表单不同,无法直接通过HttpRequest的getParameter来获取,而是需要另行解析。目前有较为常用的几个框架:
Common-FileUpload 、Pell、COS.. 一般选择第一个即可。
struts2的文件上传:
struts并没有实现自己的文件上传模块,而是提供接口与第三方的文件上传模块结合使用,目前其支持的有jakarta(即common upload)、pell、cos
配置文件上传模块:
在struts.xml或struts.properties中指定常量:
struts.multipart.parser=jakarta(默认)//可选的有pell、cos
文件上传过程说明:
首先由upload模块(如common upload)解析文件上传请求,将所有的请求解析完毕之后,文件存储到临时目录,然后将
临时文件File对象注入到Action中以供进一步处理(同时也会注入contentType和fileName)。
允许对upload模块进行参数配置(发生在文件上传时)
struts.multipart.parser=jakarta
struts.multipart.saveDir=... //文件上传到服务器的临时目录,如果不配置将采用servle的t默认临时目录
struts.multipart.maxSize=2097152 //单个文件最大大小
也可在文件上传到临时目录后使用拦截器进行拦截(发生在文件上传后)
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/png,image/gif,image/pjpeg,*.*</param>
<param name="maximumSize">100000000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref> ---千万别忘记这个
拦截器参数设置说明:
maximumSize (optional) - 单个文件最大大小限制,以字节为单位,默认是2MB.
allowedTypes (optional) - 文件的MIME类型
allowedExtensions (optional) - 文件扩展名限制.
当拦截器发现上传文件“不合法”时,会直接返回input结果,同时也将fieldError添加到ActionContext中。
可以配置文件上传拦截器的出错信息:
struts.messages.error.uploading -- 文件上传过程出错的信息struts.messages.error.file.too.large - 文件过大
struts.messages.error.content.type.not.allowed - 文件的mime类型不合法
struts.messages.error.file.extension.not.allowed - 文件扩展名不合法
详情可参考:
https://cwiki.apache.org/WW/file-upload-interceptor.html
struts2文件上传示例:
表单:
<form id="form" name="form1" action="upload.action" method="post" enctype="multipart/form-data">
文件:<input name="file" type="file"/><br/>
<input type="submit" value="提交"/>
</form>
struts.xml配置片段:
<action name="upload" class="upload.UploadAction">
<param name="savePath">/uploadfiles</param>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/png,image/gif,image/pjpeg</param>
<param name="maximumSize">1000000000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="input">upload.jsp</result>
<result name="success">upload.jsp</result>
</action>
Action实现:
public class UploadAction extends ActionSupport{
private File file; //如果表单有多个文件域且都叫file,则这里可以使用数组或List
private String fileContentType;
private String fileFileName;
private String savePath; //要保存的相对路径
//...省略get set 方法
public String execute()throws Exception{
FileOutputStream os = null;
FileInputStream fis = null;
System.out.println(this.file.getAbsolutePath());
try{
String folderPath = ServletActionContext.getRequest().getRealPath(this.savePath);
File outFile = new File(folderPath+ "\\" + this.fileFileName);
os = new FileOutputStream(outFile);
fis = new FileInputStream(this.file);
byte[] buffer = new byte[1024];
int len = 0;
System.out.println("开始写文件");
while((len = fis.read(buffer))>0){
os.write(buffer,0, len);
}
System.out.println("传输完毕:"+outFile.getAbsolutePath());
return SUCCESS;
}finally{
close(fis);
close(os);
}
}
}
点评
struts虽然将文件上传封装到了比较高的层次,但较难获得更好的客户端交互体验,比如文件都是在上传到服务器之后才进行拦截和Action操作,屏蔽许多了上传过程中的相关信息。如果想实现文件上传进度的监听,仍需要研究相关源码,hack一下mutipart请求处理的相关模块
附录
struts2的allowTypes汇总(其实也就是mime类型,查一下mime类型即可得知): '.a' : 'application/octet-stream'
'.ai' : 'application/postscript'
'.aif' : 'audio/x-aiff'
'.aifc' : 'audio/x-aiff'
'.aiff' : 'audio/x-aiff'
'.au' : 'audio/basic'
'.avi' : 'video/x-msvideo'
'.bat' : 'text/plain'
'.bcpio' : 'application/x-bcpio'
'.bin' : 'application/octet-stream'
'.bmp' : 'image/x-ms-bmp'
'.c' : 'text/plain'
# Duplicates :( '.cdf' : 'application/x-cdf'
'.cdf' : 'application/x-netcdf'
'.cpio' : 'application/x-cpio'
'.csh' : 'application/x-csh'
'.css' : 'text/css'
'.dll' : 'application/octet-stream'
'.doc' : 'application/msword'
'.dot' : 'application/msword'
'.dvi' : 'application/x-dvi'
'.eml' : 'message/rfc822'
'.eps' : 'application/postscript'
'.etx' : 'text/x-setext'
'.exe' : 'application/octet-stream'
'.gif' : 'image/gif'
'.gtar' : 'application/x-gtar'
'.h' : 'text/plain'
'.hdf' : 'application/x-hdf'
'.htm' : 'text/html'
'.html' : 'text/html'
'.ief' : 'image/ief'
'.jpe' : 'image/jpeg'
'.jpeg' : 'image/jpeg'
'.jpg' : 'image/jpeg'
'.js' : 'application/x-javascript'
'.ksh' : 'text/plain'
'.latex' : 'application/x-latex'
'.m1v' : 'video/mpeg'
'.man' : 'application/x-troff-man'
'.me' : 'application/x-troff-me'
'.mht' : 'message/rfc822'
'.mhtml' : 'message/rfc822'
'.mif' : 'application/x-mif'
'.mov' : 'video/quicktime'
'.movie' : 'video/x-sgi-movie'
'.mp2' : 'audio/mpeg'
'.mp3' : 'audio/mpeg'
'.mpa' : 'video/mpeg'
'.mpe' : 'video/mpeg'
'.mpeg' : 'video/mpeg'
'.mpg' : 'video/mpeg'
'.ms' : 'application/x-troff-ms'
'.nc' : 'application/x-netcdf'
'.nws' : 'message/rfc822'
'.o' : 'application/octet-stream'
'.obj' : 'application/octet-stream'
'.oda' : 'application/oda'
'.p12' : 'application/x-pkcs12'
'.p7c' : 'application/pkcs7-mime'
'.pbm' : 'image/x-portable-bitmap'
'.pdf' : 'application/pdf'
'.pfx' : 'application/x-pkcs12'
'.pgm' : 'image/x-portable-graymap'
'.pl' : 'text/plain'
'.png' : 'image/png'
'.pnm' : 'image/x-portable-anymap'
'.pot' : 'application/vnd.ms-powerpoint'
'.ppa' : 'application/vnd.ms-powerpoint'
'.ppm' : 'image/x-portable-pixmap'
'.pps' : 'application/vnd.ms-powerpoint'
'.ppt' : 'application/vnd.ms-powerpoint'
'.ps' : 'application/postscript'
'.pwz' : 'application/vnd.ms-powerpoint'
'.py' : 'text/x-python'
'.pyc' : 'application/x-python-code'
'.pyo' : 'application/x-python-code'
'.qt' : 'video/quicktime'
'.ra' : 'audio/x-pn-realaudio'
'.ram' : 'application/x-pn-realaudio'
'.ras' : 'image/x-cmu-raster'
'.rdf' : 'application/xml'
'.rgb' : 'image/x-rgb'
'.roff' : 'application/x-troff'
'.rtx' : 'text/richtext'
'.sgm' : 'text/x-sgml'
'.sgml' : 'text/x-sgml'
'.sh' : 'application/x-sh'
'.shar' : 'application/x-shar'
'.snd' : 'audio/basic'
'.so' : 'application/octet-stream'
'.src' : 'application/x-wais-source'
'.sv4cpio': 'application/x-sv4cpio'
'.sv4crc' : 'application/x-sv4crc'
'.swf' : 'application/x-shockwave-flash'
'.t' : 'application/x-troff'
'.tar' : 'application/x-tar'
'.tcl' : 'application/x-tcl'
'.tex' : 'application/x-tex'
'.texi' : 'application/x-texinfo'
'.texinfo': 'application/x-texinfo'
'.tif' : 'image/tiff'
'.tiff' : 'image/tiff'
'.tr' : 'application/x-troff'
'.tsv' : 'text/tab-separated-values'
'.txt' : 'text/plain'
'.ustar' : 'application/x-ustar'
'.vcf' : 'text/x-vcard'
'.wav' : 'audio/x-wav'
'.wiz' : 'application/msword'
'.wsdl' : 'application/xml'
'.xbm' : 'image/x-xbitmap'
'.xlb' : 'application/vnd.ms-excel'
# Duplicates :( '.xls' : 'application/excel'
'.xls' : 'application/vnd.ms-excel'
'.xml' : 'text/xml'
'.xpdl' : 'application/xml'
'.xpm' : 'image/x-xpixmap'
'.xsl' : 'application/xml'
'.xwd' : 'image/x-xwindowdump'
'.zip' : 'application/zip'