struts2学习笔记之文件上传
文件上传基础知识:
表单的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
http://struts.apache.org/2.0.14/docs/file-upload.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'
作者: 美码师(zale)
出处: http://www.cnblogs.com/littleatp/, 如果喜欢我的文章,请关注我的公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接 如有问题, 可留言咨询.