zoukankan      html  css  js  c++  java
  • struts2--上传总结(限制大小和类型 非法上传的跳转)


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

    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在上传的时候就判断给用户的感觉最好

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

    today lazy . tomorrow die .
  • 相关阅读:
    HDU 2444 The Accomodation of Students (判断是否是二分图,然后求最大匹配)
    HDU 1045 Fire Net (二分匹配)
    Leangoo如何颠覆传统项目管理软件?
    团队协作神器:Leangoo
    Leangoo-让工作更简单
    leangoo 轻量级项目协作和列表管理平台
    团队协作中的“贵族”leangoo
    使用leangoo实现多泳道任务看板
    项目管理工具到底应该为谁服务?
    《精益创业实战》读书笔记
  • 原文地址:https://www.cnblogs.com/france/p/4808615.html
Copyright © 2011-2022 走看看