网上有很多版本,鉴于实践出真知的态度 我自己探索了一番
struts版本:2.3.16
限制大小:
struts2默认是2M 所以如果要扩大大小限制,应该先配一个全局struts2最大上限
<constant name="struts.multipart.maxSize" value="55000000"/><!-- 可上传50M的文件 -->
注意 100w大概是1M=1024*1024b≈100W
这样配置完后对于每个action我们都可以上传不超过50M的文件了
如果还要在单个action里面限制
这样配置:
<action name="upload" class="strutsFileUpload"> <result name="input" type="redirect">/admin/ChangePhoto.jsp</result> <result name="userSuccess" type="redirect">/admin/index.jsp</result> <interceptor-ref name="defaultStack"> <!-- 配置允许上传的文件大小,单位字节 10485760=10M--> <param name="fileUpload.maximumSize">10485760</param> </interceptor-ref> </action>
默认拦截器里面做配置(待会说原因):
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">10485760</param>
值得注意的是:如果 <constant .../> 里面配置的是50M 而action里面配置的是100M 那最后也只有50M
还有另外一种配置:但是只能限制大小不能限制类型:
<转>
使用Struts2上传文件,其实使用的是apache的 commons-fileupload-1.1.jar
在实际使用的过程中,使用如下配置fileUpload拦截器并不能过滤上传的文件类型,只能处理大小过滤。
<interceptor-ref name="defaultStack"/> <!-- 限制文件上传大小和类型 --> <interceptor-ref name="fileUpload"> <param name="maximumSize">10485760</param> <param name="allowedTypes"> application/msword,application/pdf,application/zip </param> </interceptor-ref>
这样只能限制文件的大小,
如果不使用缺省的拦截器,则action中的属性不能正确赋值 就会出现jsp传到action里面的值不能得到 而为空。
而使用后,拦截类型不起作用。网上说缺省拦截器中已经包含了fileUpload拦截器。那么如上配置就是做了两次拦截。
那既然讲到限制类型,下面讲限制类型:
限制类型:
有两种配置:
1:
<action name="upload" class="strutsFileUpload"> <result name="input" type="redirect">/admin/ChangePhoto.jsp</result> <result name="userSuccess" type="redirect">/admin/index.jsp</result> <interceptor-ref name="defaultStack"> <!-- 配置允许上传的文件类型,多个用","分隔 --> <param name="fileUpload.allowedTypes"> image/png,image/gif,image/jpeg </param> </interceptor-ref> </action>
这样就能做到 限制了,只允许上面三种上传(PS:jpg也可以虽然上面有的只是jpeg但是我亲测是可以的,不放心可以再加一项)
2:
但是,用过这个参数的人都知道,allowedTypes是“文件类型”, 而不是“文件后缀名”,文件类型与文件后缀名有什么区别呢?
就如后缀名为bmp的图片的文件类型为image/bmp,后缀名为xls的Excel文件类型为application/vnd.ms-excel等等....
这各种各样的”文件类型“,让人烦不胜烦。。。。
猜想是否可以根据后缀名来过滤允许上次的文件,Struts如此红火的框架应该能想到这点。
于是便打开Struts文件上传的拦截器org.apache.struts2.interceptor.FileUploadInterceptor一看,发现如下代码:
protected Set<String> allowedTypesSet = Collections.emptySet(); protected Set<String> allowedExtensionsSet = Collections.emptySet();看到一个allowedTypesSet和一个allowedExtensionsSet,很容易想到,前者是用于存放参数allowedTypes的,
而后者呢,自然是用于存放参数allowedExtensions的,extension翻为:延长、扩展...
所以,我们可以大胆的猜想,allowedExtensions参数就是用于配置”允许上传的文件后缀名“。
再来看看FileUploadInterceptor里的一个方法acceptFile(),此方法用于根据当前配置,检查该文件是否允许被上传
protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation, Locale locale) { boolean fileIsAcceptable = false; // If it's null the upload failed if (file == null) { String errMsg = getTextMessage(action, "struts.messages.error.uploading", new Object[]{inputName}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else if (maximumSize != null && maximumSize < file.length()) { String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new Object[]{inputName, filename, file.getName(), "" + file.length()}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else if ((!allowedTypesSet.isEmpty()) && (!containsItem(allowedTypesSet, contentType))) { String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else if ((!allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(allowedExtensionsSet, filename))) { String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new Object[]{inputName, filename, file.getName(), contentType}, locale); if (validation != null) { validation.addFieldError(inputName, errMsg); } LOG.warn(errMsg); } else { fileIsAcceptable = true; } return fileIsAcceptable; }
别的先不管,先看看到第2,3个else if节点,分别是利用了allowedTypesSet和allowedExtensionsSet,如下
} else if (allowedTypesSet不为空 && allowedTypesSet不包含该文件的类型) { // 添加错误信息.... } else if (allowedExtensionsSet不为空 && allowedExtensionsSet不包含该文件的后缀名) { // 添加错误信息 }
从上面的代码中可以看出,如果我们要利用allowedExtensions参数来控制上传文件的后缀名,则不能配置allowedTypes参数。
否则,如果allowedTypes参数有配置,那么allowedExtensions参数将不会再起效。
总结
使用Struts文件上次功能,我们可以使用”文件类型“和”文件后缀名“两者中的一个来控制上传文件的类型/后缀名。但是,allowedTypes的优先级别高于allowedExtensions,如果配置了allowedTypes则allowedExtensions将不再起效。最后附上allowedExtensions的一个简单配置:
<action name="projectMake-Add" class="projectMake" method="add"> <result name="addsuccess" type="redirect">/admin/index2.jsp</result> <result name="fileUploadFail" >/WEB-INF/infoFail.jsp</result> <result name="input" >/WEB-INF/infoFail.jsp</result> <interceptor-ref name="defaultStack"> <!-- 配置允许上传的文件类型,多个用","分隔 --> <param name="fileUpload.allowedExtensions"> png,gif,jpeg </param> <!-- 配置允许上传的文件大小,单位字节 10485760=10M--> <param name="fileUpload.maximumSize">10485760</param> </interceptor-ref> </action>
当然 如果想用第一种的话,这边给出一些配置
'.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', '.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', '.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',
常用的都有了 如果还有没找到的 请下面评论 或者自己类比推 或者谷歌^_^
那么限制都做好了;
非法上传的跳转:
如果文件上传过大,或者类型不对 系统会报错;
一个办法是:
<action> <result name="input">/error/Error.jsp</result> <interceptor-ref name="defaultStack"> <!-- 配置允许上传的文件类型,多个用","分隔 --> <param name="fileUpload.allowedExtensions"> png,gif,jpeg </param> <!-- 配置允许上传的文件大小,单位字节 10485760=10M--> <param name="fileUpload.maximumSize">10485760</param> </interceptor-ref> </action>
所以用转发的方式 存了 content 然后转发的页面在<input value="<s:property value="content"/>"/>即可
当然 最好的话就是js在上传的时候就判断给用户的感觉最好
版权声明:本文为博主原创文章,未经博主允许不得转载。