france

https://github.com/francecil

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理


 网上有很多版本,鉴于实践出真知的态度 我自己探索了一番

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>


    文件上传类型大小错误action会直接返回input,所以不需要在action中的方法出现一个 return "input" ;


当然 如果是这样的话,如果是前面有填写文章的内容,却因为上传的类型不对而跳转 不就白写了T_T,,,

所以用转发的方式 存了 content 然后转发的页面在<input value="<s:property  value="content"/>"/>即可

当然 最好的话就是js在上传的时候就判断给用户的感觉最好

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2014-10-19 10:39  france  阅读(376)  评论(0编辑  收藏  举报